You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2011/11/07 12:09:52 UTC

svn commit: r1198703 [1/2] - in /subversion/branches/showing-merge-info: ./ build/ build/ac-macros/ notes/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_subr/ subversion/libsvn_wc/ ...

Author: julianfoad
Date: Mon Nov  7 11:09:51 2011
New Revision: 1198703

URL: http://svn.apache.org/viewvc?rev=1198703&view=rev
Log:
On the 'showing-merge-info' branch: Catch up to trunk@1198699.

Modified:
    subversion/branches/showing-merge-info/   (props changed)
    subversion/branches/showing-merge-info/build/ac-macros/sqlite.m4
    subversion/branches/showing-merge-info/build/getversion.py
    subversion/branches/showing-merge-info/notes/editor-v2.txt
    subversion/branches/showing-merge-info/subversion/include/private/svn_wc_private.h
    subversion/branches/showing-merge-info/subversion/include/svn_client.h
    subversion/branches/showing-merge-info/subversion/include/svn_dirent_uri.h
    subversion/branches/showing-merge-info/subversion/include/svn_editor.h
    subversion/branches/showing-merge-info/subversion/libsvn_client/client.h
    subversion/branches/showing-merge-info/subversion/libsvn_client/copy.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/delete.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/diff.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/externals.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/info.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/patch.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c
    subversion/branches/showing-merge-info/subversion/libsvn_delta/compat.c
    subversion/branches/showing-merge-info/subversion/libsvn_subr/dirent_uri.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/adm_ops.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.h
    subversion/branches/showing-merge-info/subversion/svn/cl.h
    subversion/branches/showing-merge-info/subversion/svn/copy-cmd.c
    subversion/branches/showing-merge-info/subversion/svn/main.c
    subversion/branches/showing-merge-info/subversion/svn/util.c
    subversion/branches/showing-merge-info/subversion/tests/cmdline/copy_tests.py
    subversion/branches/showing-merge-info/subversion/tests/cmdline/dav-mirror-autocheck.sh
    subversion/branches/showing-merge-info/subversion/tests/cmdline/davautocheck.sh
    subversion/branches/showing-merge-info/subversion/tests/cmdline/patch_tests.py
    subversion/branches/showing-merge-info/subversion/tests/libsvn_delta/editor-test.c
    subversion/branches/showing-merge-info/subversion/tests/libsvn_repos/repos-test.c
    subversion/branches/showing-merge-info/subversion/tests/libsvn_wc/   (props changed)
    subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/cronjob
    subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/run
    subversion/branches/showing-merge-info/tools/server-side/svnauthz-validate.c

Propchange: subversion/branches/showing-merge-info/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov  7 11:09:51 2011
@@ -57,4 +57,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1177607-1195555
+/subversion/trunk:1177607-1198699

Modified: subversion/branches/showing-merge-info/build/ac-macros/sqlite.m4
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/build/ac-macros/sqlite.m4?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/build/ac-macros/sqlite.m4 (original)
+++ subversion/branches/showing-merge-info/build/ac-macros/sqlite.m4 Mon Nov  7 11:09:51 2011
@@ -106,7 +106,7 @@ AC_DEFUN(SVN_SQLITE_PKG_CONFIG,
       sqlite_version=`$PKG_CONFIG $SQLITE_PKGNAME --modversion --silence-errors`
 
       if test -n "$sqlite_version"; then
-        SVN_SQLITE_VERNUM_PARSE
+        SVN_SQLITE_VERNUM_PARSE([$sqlite_version], [sqlite_ver_num])
 
         if test "$sqlite_ver_num" -ge "$sqlite_min_ver_num"; then
           AC_MSG_RESULT([$sqlite_version])
@@ -198,20 +198,22 @@ SQLITE_VERSION_OKAY
   fi
 ])
 
-dnl SVN_SQLITE_VERNUM_PARSE()
+dnl SVN_SQLITE_VERNUM_PARSE(version_string, result_var)
 dnl
-dnl Parse a x.y[.z] version string sqlite_version into a number sqlite_ver_num.
+dnl Parse a x.y[.z] version string version_string into a number result_var.
 AC_DEFUN(SVN_SQLITE_VERNUM_PARSE,
 [
-  sqlite_major=`expr $sqlite_version : '\([[0-9]]*\)'`
-  sqlite_minor=`expr $sqlite_version : '[[0-9]]*\.\([[0-9]]*\)'`
-  sqlite_micro=`expr $sqlite_version : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
-  if test -z "$sqlite_micro"; then
-    sqlite_micro=0
+  version_string="$1"
+  
+  major=`expr $version_string : '\([[0-9]]*\)'`
+  minor=`expr $version_string : '[[0-9]]*\.\([[0-9]]*\)'`
+  micro=`expr $version_string : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+  if test -z "$micro"; then
+    micro=0
   fi
-  sqlite_ver_num=`expr $sqlite_major \* 1000000 \
-                    \+ $sqlite_minor \* 1000 \
-                    \+ $sqlite_micro`
+  $2=`expr $major \* 1000000 \
+        \+ $minor \* 1000 \
+        \+ $micro`
 ])
 
 dnl SVN_SQLITE_MIN_VERNUM_PARSE()
@@ -220,12 +222,7 @@ dnl Parse a x.y.z version string SQLITE_
 dnl sqlite_min_ver_num.
 AC_DEFUN(SVN_SQLITE_MIN_VERNUM_PARSE,
 [
-  sqlite_min_major=`expr $SQLITE_MINIMUM_VER : '\([[0-9]]*\)'`
-  sqlite_min_minor=`expr $SQLITE_MINIMUM_VER : '[[0-9]]*\.\([[0-9]]*\)'`
-  sqlite_min_micro=`expr $SQLITE_MINIMUM_VER : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
-  sqlite_min_ver_num=`expr $sqlite_min_major \* 1000000 \
-                        \+ $sqlite_min_minor \* 1000 \
-                        \+ $sqlite_min_micro`
+  SVN_SQLITE_VERNUM_PARSE([$SQLITE_MINIMUM_VER], [sqlite_min_ver_num])
 ])
 
 dnl SVN_DOWNLOAD_SQLITE()

Modified: subversion/branches/showing-merge-info/build/getversion.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/build/getversion.py?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/build/getversion.py (original)
+++ subversion/branches/showing-merge-info/build/getversion.py Mon Nov  7 11:09:51 2011
@@ -85,7 +85,7 @@ def sqlite_extractor(parser, include_fil
 
 extractors = {
   'SVN' : svn_extractor,
-  'SQLITE' : sqlite_extractor,
+  # 'SQLITE' : sqlite_extractor, # not used
   }
 
 def usage_and_exit(msg):

Modified: subversion/branches/showing-merge-info/notes/editor-v2.txt
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/notes/editor-v2.txt?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/notes/editor-v2.txt (original)
+++ subversion/branches/showing-merge-info/notes/editor-v2.txt Mon Nov  7 11:09:51 2011
@@ -1,3 +1,11 @@
+###
+###
+### THIS FILE IS HISTORICAL ONLY. FOR CURRENT INFORMATION, PLEASE SEE:
+###     include/svn_editor.h
+###
+###
+
+
 NOTES on a revamped editor interface
 
 -- all paths are relpaths

Modified: subversion/branches/showing-merge-info/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/private/svn_wc_private.h?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/private/svn_wc_private.h Mon Nov  7 11:09:51 2011
@@ -354,13 +354,14 @@ svn_wc__node_get_children(const apr_arra
 
 
 /**
- * Fetch the repository root information for a given @a local_abspath into
- * @a *repos_root_url and @a repos_uuid. Use @a wc_ctx to access the working copy
+ * Fetch the repository root information for the working version
+ * of the node at @a local_abspath into @a *repos_root_url
+ * and @a *repos_uuid. Use @a wc_ctx to access the working copy
  * for @a local_abspath, @a scratch_pool for all temporary allocations,
  * @a result_pool for result allocations. Note: the result may be NULL if the
  * given node has no repository root associated with it (e.g. locally added).
  *
- * Either input value may be NULL, indicating no interest.
+ * Either output argument may be NULL, indicating no interest.
  */
 svn_error_t *
 svn_wc__node_get_repos_info(const char **repos_root_url,
@@ -1132,6 +1133,22 @@ svn_wc__delete_internal(svn_wc_context_t
                         void *notify_baton,
                         apr_pool_t *scratch_pool);
 
+
+/* Alternative version of svn_wc_delete4().
+ * It can delete multiple TARGETS more efficiently (within a single sqlite
+ * transaction per working copy), but lacks support for moves. */
+svn_error_t *
+svn_wc__delete_many(svn_wc_context_t *wc_ctx,
+                    const apr_array_header_t *targets,
+                    svn_boolean_t keep_local,
+                    svn_boolean_t delete_unversioned_target,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    svn_wc_notify_func2_t notify_func,
+                    void *notify_baton,
+                    apr_pool_t *scratch_pool);
+
+
 /* If the node at LOCAL_ABSPATH was moved away set *MOVED_TO_ABSPATH to
  * the absolute path of the copied move-target node, and *COPY_OP_ROOT_ABSPATH
  * to the absolute path of the root node of the copy operation.

Modified: subversion/branches/showing-merge-info/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/svn_client.h?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/svn_client.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/svn_client.h Mon Nov  7 11:09:51 2011
@@ -2865,9 +2865,10 @@ svn_client_blame(const char *path_or_url
 
 /**
  * Produce diff output which describes the delta between
- * @a path1/@a revision1 and @a path2/@a revision2.  Print the output
- * of the diff to @a outfile, and any errors to @a errfile.  @a path1
- * and @a path2 can be either working-copy paths or URLs.
+ * @a path_or_url1/@a revision1 and @a path_or_url2/@a revision2.  Print
+ * the output of the diff to @a outstream, and any errors to @a
+ * errstream.  @a path_or_url1 and @a path_or_url2 can be either
+ * working-copy paths or URLs.
  *
  * If @a relative_to_dir is not @c NULL, the @a original_path and
  * @a modified_path will have the @a relative_to_dir stripped from the
@@ -2880,9 +2881,10 @@ svn_client_blame(const char *path_or_url
  * If either @a revision1 or @a revision2 has an `unspecified' or
  * unrecognized `kind', return #SVN_ERR_CLIENT_BAD_REVISION.
  *
- * @a path1 and @a path2 must both represent the same node kind -- that
- * is, if @a path1 is a directory, @a path2 must also be, and if @a path1
- * is a file, @a path2 must also be.
+ * @a path_or_url1 and @a path_or_url2 must both represent the same node
+ * kind -- that is, if @a path_or_url1 is a directory, @a path_or_url2
+ * must also be, and if @a path_or_url1 is a file, @a path_or_url2 must
+ * also be.
  *
  * If @a depth is #svn_depth_infinity, diff fully recursively.
  * Else if it is #svn_depth_immediates, diff the named paths and
@@ -2948,9 +2950,9 @@ svn_client_blame(const char *path_or_url
  */
 svn_error_t *
 svn_client_diff6(const apr_array_header_t *diff_options,
-                 const char *path1,
+                 const char *path_or_url1,
                  const svn_opt_revision_t *revision1,
-                 const char *path2,
+                 const char *path_or_url2,
                  const svn_opt_revision_t *revision2,
                  const char *relative_to_dir,
                  svn_depth_t depth,
@@ -3091,22 +3093,22 @@ svn_client_diff(const apr_array_header_t
                 apr_pool_t *pool);
 
 /**
- * Produce diff output which describes the delta between the
- * filesystem object @a path in peg revision @a peg_revision, as it
- * changed between @a start_revision and @a end_revision.  @a path can
+ * Produce diff output which describes the delta between the filesystem
+ * object @a path_or_url in peg revision @a peg_revision, as it changed
+ * between @a start_revision and @a end_revision.  @a path_or_url can
  * be either a working-copy path or URL.
  *
  * If @a peg_revision is #svn_opt_revision_unspecified, behave
- * identically to svn_client_diff5(), using @a path for both of that
- * function's @a path1 and @a path2 arguments.
+ * identically to svn_client_diff6(), using @a path_or_url for both of that
+ * function's @a path_or_url1 and @a path_or_url2 arguments.
  *
- * All other options are handled identically to svn_client_diff5().
+ * All other options are handled identically to svn_client_diff6().
  *
- * @since New in 1.7.
+ * @since New in 1.8.
  */
 svn_error_t *
 svn_client_diff_peg6(const apr_array_header_t *diff_options,
-                     const char *path,
+                     const char *path_or_url,
                      const svn_opt_revision_t *peg_revision,
                      const svn_opt_revision_t *start_revision,
                      const svn_opt_revision_t *end_revision,
@@ -3250,8 +3252,9 @@ svn_client_diff_peg(const apr_array_head
 
 /**
  * Produce a diff summary which lists the changed items between
- * @a path1/@a revision1 and @a path2/@a revision2 without creating text
- * deltas. @a path1 and @a path2 can be either working-copy paths or URLs.
+ * @a path_or_url1/@a revision1 and @a path_or_url2/@a revision2 without
+ * creating text deltas. @a path_or_url1 and @a path_or_url2 can be
+ * either working-copy paths or URLs.
  *
  * The function may report false positives if @a ignore_ancestry is false,
  * since a file might have been modified between two revisions, but still
@@ -3260,14 +3263,14 @@ svn_client_diff_peg(const apr_array_head
  * Calls @a summarize_func with @a summarize_baton for each difference
  * with a #svn_client_diff_summarize_t structure describing the difference.
  *
- * See svn_client_diff5() for a description of the other parameters.
+ * See svn_client_diff6() for a description of the other parameters.
  *
  * @since New in 1.5.
  */
 svn_error_t *
-svn_client_diff_summarize2(const char *path1,
+svn_client_diff_summarize2(const char *path_or_url1,
                            const svn_opt_revision_t *revision1,
-                           const char *path2,
+                           const char *path_or_url2,
                            const svn_opt_revision_t *revision2,
                            svn_depth_t depth,
                            svn_boolean_t ignore_ancestry,
@@ -3302,13 +3305,13 @@ svn_client_diff_summarize(const char *pa
 
 /**
  * Produce a diff summary which lists the changed items between the
- * filesystem object @a path in peg revision @a peg_revision, as it
- * changed between @a start_revision and @a end_revision. @a path can
+ * filesystem object @a path_or_url in peg revision @a peg_revision, as it
+ * changed between @a start_revision and @a end_revision. @a path_or_url can
  * be either a working-copy path or URL.
  *
  * If @a peg_revision is #svn_opt_revision_unspecified, behave
- * identically to svn_client_diff_summarize2(), using @a path for both
- * of that function's @a path1 and @a path2 arguments.
+ * identically to svn_client_diff_summarize2(), using @a path_or_url for
+ * both of that function's @a path_or_url1 and @a path_or_url2 arguments.
  *
  * The function may report false positives if @a ignore_ancestry is false,
  * as described in the documentation for svn_client_diff_summarize2().
@@ -3321,7 +3324,7 @@ svn_client_diff_summarize(const char *pa
  * @since New in 1.5.
  */
 svn_error_t *
-svn_client_diff_summarize_peg2(const char *path,
+svn_client_diff_summarize_peg2(const char *path_or_url,
                                const svn_opt_revision_t *peg_revision,
                                const svn_opt_revision_t *start_revision,
                                const svn_opt_revision_t *end_revision,

Modified: subversion/branches/showing-merge-info/subversion/include/svn_dirent_uri.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/svn_dirent_uri.h?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/svn_dirent_uri.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/svn_dirent_uri.h Mon Nov  7 11:09:51 2011
@@ -122,6 +122,10 @@
  * source -- such as from the network -- is converted to a dirent it
  * should be tested with svn_dirent_is_under_root() before you can
  * assume the path to be a safe local path.
+ *
+ * MEMORY ALLOCATION: A function documented as allocating the result
+ * in a pool may instead return a static string such as "." or "". If
+ * the result is equal to an input, it will duplicate the input.
  */
 
 #ifndef SVN_DIRENT_URI_H
@@ -141,34 +145,39 @@ extern "C" {
 /** Convert @a dirent from the local style to the canonical internal style.
  * "Local style" means native path separators and "." for the empty path.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 const char *
 svn_dirent_internal_style(const char *dirent,
-                          apr_pool_t *pool);
+                          apr_pool_t *result_pool);
 
 /** Convert @a dirent from the internal style to the local style.
  * "Local style" means native path separators and "." for the empty path.
  * If the input is not canonical, the output may not be canonical.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 const char *
 svn_dirent_local_style(const char *dirent,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool);
 
 /** Convert @a relpath from the local style to the canonical internal style.
  * "Local style" means native path separators and "." for the empty path.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 const char *
 svn_relpath__internal_style(const char *relpath,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool);
 
 
-/** Join a base dirent (@a base) with a component (@a component), allocated in
- * @a pool.
+/** Join a base dirent (@a base) with a component (@a component).
  *
  * If either @a base or @a component is the empty string, then the other
  * argument will be copied and returned.  If both are the empty string then
@@ -181,15 +190,17 @@ svn_relpath__internal_style(const char *
  * dirents. Only for "internal" canonicalized dirents, since it uses '/'
  * for the separator.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 char *
 svn_dirent_join(const char *base,
                 const char *component,
-                apr_pool_t *pool);
+                apr_pool_t *result_pool);
 
-/** Join multiple components onto a @a base dirent, allocated in @a pool. The
- * components are terminated by a @c NULL.
+/** Join multiple components onto a @a base dirent. The components are
+ * terminated by a @c NULL.
  *
  * If any component is the empty string, it will be ignored.
  *
@@ -198,26 +209,30 @@ svn_dirent_join(const char *base,
  *
  * See svn_dirent_join() for further notes about joining dirents.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 char *
-svn_dirent_join_many(apr_pool_t *pool,
+svn_dirent_join_many(apr_pool_t *result_pool,
                      const char *base,
                      ...);
 
-/** Join a base relpath (@a base) with a component (@a component), allocating
- * the result in @a pool. @a component need not be a single component.
+/** Join a base relpath (@a base) with a component (@a component).
+ * @a component need not be a single component.
  *
  * If either @a base or @a component is the empty path, then the other
  * argument will be copied and returned.  If both are the empty path the
  * empty path is returned.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 char *
 svn_relpath_join(const char *base,
                  const char *component,
-                 apr_pool_t *pool);
+                 apr_pool_t *result_pool);
 
 /** Gets the name of the specified canonicalized @a dirent as it is known
  * within its parent directory. If the @a dirent is root, return "". The
@@ -225,8 +240,8 @@ svn_relpath_join(const char *base,
  *
  * Example: svn_dirent_basename("/foo/bar") -> "bar"
  *
- * The returned basename will be allocated in @a pool. If @a pool is NULL
- * a pointer to the basename in @a dirent is returned.
+ * If @a result_pool is NULL, return a pointer to the basename in @a dirent,
+ * otherwise allocate the result in @a result_pool.
  *
  * @note If an empty string is passed, then an empty string will be returned.
  *
@@ -234,7 +249,7 @@ svn_relpath_join(const char *base,
  */
 const char *
 svn_dirent_basename(const char *dirent,
-                    apr_pool_t *pool);
+                    apr_pool_t *result_pool);
 
 /** Get the dirname of the specified canonicalized @a dirent, defined as
  * the dirent with its basename removed.
@@ -242,16 +257,15 @@ svn_dirent_basename(const char *dirent,
  * If @a dirent is root  ("/", "X:/", "//server/share/") or "", it is returned
  * unchanged.
  *
- * The returned dirname will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.6.
  */
 char *
 svn_dirent_dirname(const char *dirent,
-                   apr_pool_t *pool);
+                   apr_pool_t *result_pool);
 
-/** Divide the canonicalized @a dirent into @a *dirpath and @a
- * *base_name, allocated in @a pool.
+/** Divide the canonicalized @a dirent into @a *dirpath and @a *base_name.
  *
  * If @a dirpath or @a base_name is NULL, then don't set that one.
  *
@@ -272,16 +286,17 @@ svn_dirent_dirname(const char *dirent,
  *             - <pre>"X:foo"         ==>  "X:" and "foo"</pre>
  *  Posix:     - <pre>"X:foo"         ==>  ""   and "X:foo"</pre>
  *
+ * Allocate the results in @a result_pool.
+ *
  * @since New in 1.7.
  */
 void
 svn_dirent_split(const char **dirpath,
                  const char **base_name,
                  const char *dirent,
-                 apr_pool_t *pool);
+                 apr_pool_t *result_pool);
 
-/** Divide the canonicalized @a relpath into @a *dirpath and @a
- * *base_name, allocated in @a pool.
+/** Divide the canonicalized @a relpath into @a *dirpath and @a *base_name.
  *
  * If @a dirpath or @a base_name is NULL, then don't set that one.
  *
@@ -296,13 +311,15 @@ svn_dirent_split(const char **dirpath,
  *             - <pre>"bar"          ==>  ""  and "bar"</pre>
  *             - <pre>""              ==>  ""   and ""</pre>
  *
+ * Allocate the results in @a result_pool.
+ *
  * @since New in 1.7.
  */
 void
 svn_relpath_split(const char **dirpath,
                   const char **base_name,
                   const char *relpath,
-                  apr_pool_t *pool);
+                  apr_pool_t *result_pool);
 
 /** Get the basename of the specified canonicalized @a relpath.  The
  * basename is defined as the last component of the relpath.  If the @a
@@ -311,8 +328,8 @@ svn_relpath_split(const char **dirpath,
  *
  * Example: svn_relpath_basename("/trunk/foo/bar") -> "bar"
  *
- * The returned basename will be allocated in @a pool. If @a
- * pool is NULL a pointer to the basename in @a relpath is returned.
+ * If @a result_pool is NULL, return a pointer to the basename in @a relpath,
+ * otherwise allocate the result in @a result_pool.
  *
  * @note If an empty string is passed, then an empty string will be returned.
  *
@@ -320,24 +337,24 @@ svn_relpath_split(const char **dirpath,
  */
 const char *
 svn_relpath_basename(const char *relpath,
-                     apr_pool_t *pool);
+                     apr_pool_t *result_pool);
 
 /** Get the dirname of the specified canonicalized @a relpath, defined as
  * the relpath with its basename removed.
  *
  * If @a relpath is empty, "" is returned.
  *
- * The returned relpath will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
  */
 char *
 svn_relpath_dirname(const char *relpath,
-                    apr_pool_t *pool);
+                    apr_pool_t *result_pool);
 
 
 /** Divide the canonicalized @a uri into a uri @a *dirpath and a
- * (URI-decoded) relpath @a *base_name, allocated in @a pool.
+ * (URI-decoded) relpath @a *base_name.
  *
  * If @a dirpath or @a base_name is NULL, then don't set that one.
  *
@@ -350,13 +367,15 @@ svn_relpath_dirname(const char *relpath,
  * Examples:
  *   - <pre>"http://server/foo/bar"  ==>  "http://server/foo" and "bar"</pre>
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 void
 svn_uri_split(const char **dirpath,
               const char **base_name,
               const char *uri,
-              apr_pool_t *pool);
+              apr_pool_t *result_pool);
 
 /** Get the (URI-decoded) basename of the specified canonicalized @a
  * uri.  The basename is defined as the last component of the uri.  If
@@ -365,13 +384,13 @@ svn_uri_split(const char **dirpath,
  *
  * Example: svn_uri_basename("http://server/foo/bar") -> "bar"
  *
- * The returned basename will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
  */
 const char *
 svn_uri_basename(const char *uri,
-                 apr_pool_t *pool);
+                 apr_pool_t *result_pool);
 
 /** Get the dirname of the specified canonicalized @a uri, defined as
  * the uri with its basename removed.
@@ -379,13 +398,13 @@ svn_uri_basename(const char *uri,
  * If @a uri is root (e.g. "http://server"), it is returned
  * unchanged.
  *
- * The returned dirname will be allocated in @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
  */
 char *
 svn_uri_dirname(const char *uri,
-                apr_pool_t *pool);
+                apr_pool_t *result_pool);
 
 /** Return TRUE if @a dirent is considered absolute on the platform at
  * hand. E.g. '/foo' on Posix platforms or 'X:/foo', '//server/share/foo'
@@ -431,13 +450,13 @@ svn_uri_is_root(const char *uri,
  *
  * and possibly other semantically inoperative transformations.
  *
- * The returned dirent may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.6.
  */
 const char *
 svn_dirent_canonicalize(const char *dirent,
-                        apr_pool_t *pool);
+                        apr_pool_t *result_pool);
 
 
 /** Return a new relpath like @a relpath, but transformed such that some types
@@ -450,13 +469,13 @@ svn_dirent_canonicalize(const char *dire
  *
  * and possibly other semantically inoperative transformations.
  *
- * The returned relpath may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
  */
 const char *
 svn_relpath_canonicalize(const char *relpath,
-                         apr_pool_t *pool);
+                         apr_pool_t *result_pool);
 
 
 /** Return a new uri like @a uri, but transformed such that some types
@@ -474,16 +493,17 @@ svn_relpath_canonicalize(const char *rel
  *
  * and possibly other semantically inoperative transformations.
  *
- * The returned uri may be allocated statically or from @a pool.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
  */
 const char *
 svn_uri_canonicalize(const char *uri,
-                     apr_pool_t *pool);
+                     apr_pool_t *result_pool);
 
-/** Return @c TRUE iff @a dirent is canonical.  Use @a pool for temporary
- * allocations.
+/** Return @c TRUE iff @a dirent is canonical.
+ *
+ * Use @a scratch_pool for temporary allocations.
  *
  * @note The test for canonicalization is currently defined as
  * "looks exactly the same as @c svn_dirent_canonicalize() would make
@@ -494,7 +514,7 @@ svn_uri_canonicalize(const char *uri,
  */
 svn_boolean_t
 svn_dirent_is_canonical(const char *dirent,
-                        apr_pool_t *pool);
+                        apr_pool_t *scratch_pool);
 
 /** Return @c TRUE iff @a relpath is canonical.
  *
@@ -504,37 +524,42 @@ svn_dirent_is_canonical(const char *dire
 svn_boolean_t
 svn_relpath_is_canonical(const char *relpath);
 
-/** Return @c TRUE iff @a uri is canonical.  Use @a pool for temporary
- * allocations.
+/** Return @c TRUE iff @a uri is canonical.
+ *
+ * Use @a scratch_pool for temporary allocations.
  *
  * @see svn_uri_canonicalize()
  * @since New in 1.7.
  */
 svn_boolean_t
 svn_uri_is_canonical(const char *uri,
-                     apr_pool_t *pool);
+                     apr_pool_t *scratch_pool);
 
 /** Return the longest common dirent shared by two canonicalized dirents,
  * @a dirent1 and @a dirent2.  If there's no common ancestor, return the
  * empty path.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 char *
 svn_dirent_get_longest_ancestor(const char *dirent1,
                                 const char *dirent2,
-                                apr_pool_t *pool);
+                                apr_pool_t *result_pool);
 
 /** Return the longest common path shared by two relative paths,
  * @a relpath1 and @a relpath2.  If there's no common ancestor, return the
  * empty path.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 char *
 svn_relpath_get_longest_ancestor(const char *relpath1,
                                  const char *relpath2,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 /** Return the longest common path shared by two canonicalized uris,
  * @a uri1 and @a uri2.  If there's no common ancestor, return the
@@ -544,37 +569,46 @@ svn_relpath_get_longest_ancestor(const c
  * resources), and (b) share a common ancestor in their path
  * component, i.e. 'protocol://' is not a sufficient ancestor.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 char *
 svn_uri_get_longest_ancestor(const char *uri1,
                              const char *uri2,
-                             apr_pool_t *pool);
+                             apr_pool_t *result_pool);
 
 /** Convert @a relative canonicalized dirent to an absolute dirent and
- * return the results in @a *pabsolute, allocated in @a pool.
+ * return the results in @a *pabsolute.
  * Raise SVN_ERR_BAD_FILENAME if the absolute dirent cannot be determined.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.6.
  */
 svn_error_t *
 svn_dirent_get_absolute(const char **pabsolute,
                         const char *relative,
-                        apr_pool_t *pool);
+                        apr_pool_t *result_pool);
 
 /** Similar to svn_uri_skip_ancestor(), except that if @a child_uri is
  * the same as @a parent_uri, it is not considered a child, so the result
  * is @c NULL; an empty string is never returned.
+ *
+ * Allocate the result in @a result_pool.
  */
 const char *
 svn_uri__is_child(const char *parent_uri,
                   const char *child_uri,
-                  apr_pool_t *pool);
+                  apr_pool_t *result_pool);
 
 /** Similar to svn_dirent_skip_ancestor(), except that if @a child_dirent is
  * the same as @a parent_dirent, it is not considered a child, so the result
  * is @c NULL; an empty string is never returned.
  *
+ * If @a result_pool is NULL, return a pointer into @a child_dirent, otherwise
+ * allocate the result in @a result_pool.
+ *
  * ### TODO: Deprecate, as the semantics are trivially
  * obtainable from *_skip_ancestor().
  *
@@ -583,7 +617,7 @@ svn_uri__is_child(const char *parent_uri
 const char *
 svn_dirent_is_child(const char *parent_dirent,
                     const char *child_dirent,
-                    apr_pool_t *pool);
+                    apr_pool_t *result_pool);
 
 /** Return TRUE if @a parent_dirent is an ancestor of @a child_dirent or
  * the dirents are equal, and FALSE otherwise.
@@ -633,6 +667,7 @@ svn_relpath_skip_ancestor(const char *pa
 /** Return the URI-decoded relative path of @a child_uri that is below
  * @a parent_uri, or just "" if @a parent_uri is equal to @a child_uri. If
  * @a child_uri is not below or equal to @a parent_uri, return NULL.
+ *
  * Allocate the result in @a result_pool.
  *
  * @since New in 1.7.
@@ -670,8 +705,8 @@ svn_uri_skip_ancestor(const char *parent
  * If there are no items in @a targets, set @a *pcommon and (if
  * applicable) @a *pcondensed_targets to @c NULL.
  *
- * Allocates @a *pcommon and @a *targets in @a result_pool. All
- * intermediate allocations will be performed in @a scratch_pool.
+ * Allocate the results in @a result_pool. Use @a scratch_pool for
+ * temporary allocations.
  *
  * @since New in 1.7.
  */
@@ -711,8 +746,8 @@ svn_dirent_condense_targets(const char *
  * If there are no items in @a targets, set @a *pcommon and (if
  * applicable) @a *pcondensed_targets to @c NULL.
  *
- * Allocate @a *pcommon and @a *targets in @a result_pool. Temporary
- * allocations will be performed in @a scratch_pool.
+ * Allocate the results in @a result_pool. Use @a scratch_pool for
+ * temporary allocations.
  *
  * @since New in 1.7.
  */
@@ -729,11 +764,13 @@ svn_uri_condense_targets(const char **pc
  * it resolves to a path above @a base_path, or if @a path is an absolute
  * path, then set @a *under_root to @c FALSE. Otherwise, set @a *under_root
  * to @c TRUE and, if @a result_path is not @c NULL, set @a *result_path to
- * the resulting path, allocated in @a result_pool.
+ * the resulting path.
  *
  * @a path need not be canonical. @a base_path must be canonical and
  * @a *result_path will be canonical.
  *
+ * Allocate the result in @a result_pool.
+ *
  * Note: Use of this function is strongly encouraged. Do not roll your own.
  * (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-3846)
  *
@@ -749,22 +786,26 @@ svn_dirent_is_under_root(svn_boolean_t *
 /** Set @a *dirent to the path corresponding to the file:// URL @a url, using
  * the platform-specific file:// rules.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 svn_error_t *
 svn_uri_get_dirent_from_file_url(const char **dirent,
                                  const char *url,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 /** Set @a *url to a file:// URL, corresponding to @a dirent using the
  * platform specific dirent and file:// rules.
  *
+ * Allocate the result in @a result_pool.
+ *
  * @since New in 1.7.
  */
 svn_error_t *
 svn_uri_get_file_url_from_dirent(const char **url,
                                  const char *dirent,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/showing-merge-info/subversion/include/svn_editor.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/svn_editor.h?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/svn_editor.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/svn_editor.h Mon Nov  7 11:09:51 2011
@@ -123,6 +123,11 @@ extern "C" {
 
 /** An abstract object that edits a target tree.
  *
+ * @note The term "follow" means at any later time in the editor drive.
+ * Terms such as "must", "must not", "required", "shall", "shall not",
+ * "should", "should not", "recommended", "may", and "optional" in this
+ * document are to be interpreted as described in RFC 2119.
+ *
  * \n
  * <h3>Life-Cycle</h3>
  *
@@ -236,8 +241,9 @@ extern "C" {
  *   destination of a copy (where these new, copied nodes are subject to
  *   the Once Rule).
  *
- * - The ancestor of an added or modified node may not be deleted. The
- *   ancestor may not be moved (instead: perform the move, *then* the edits).
+ * - The ancestor of an added, copied-here, moved-here or modified node may
+ *   not be deleted. The ancestor may not be moved (instead: perform the
+ *   move, *then* the edits).
  *
  * - svn_editor_delete() must not be used to replace a path -- i.e.
  *   svn_editor_delete() must not be followed by an svn_editor_add_*() on
@@ -336,11 +342,7 @@ extern "C" {
  * context.
  *
  *
- * @todo ### TODO anything missing? -- allow text and prop change to follow
- * a move or copy. -- set_text() vs. apply_text_delta()? -- If a
- * set_props/set_text/set_target/copy/move/delete in a merge source is
- * applied to a different branch, which side will REVISION arguments reflect
- * and is there still a problem?
+ * @todo ### TODO anything missing?
  *
  * @since New in 1.8.
  */
@@ -699,17 +701,8 @@ svn_editor_setcb_many(svn_editor_t *edit
  * Create a new directory at @a relpath. The immediate parent of @a relpath
  * is expected to exist.
  *
- * Set the properties of the new directory to @a props, which is an
- * apr_hash_t holding key-value pairs. Each key is a const char* of a
- * property name, each value is a const svn_string_t*. If no properties are
- * being set on the new directory, @a props must be NULL.
- *
- * If this add is expected to replace a previously existing file or
- * directory at @a relpath, the revision number of the node to be replaced
- * must be given in @a replaces_rev. Otherwise, @a replaces_rev must be
- * SVN_INVALID_REVNUM.  Note: it is not allowed to call a "delete" followed
- * by an "add" on the same path. Instead, an "add" with @a replaces_rev set
- * accordingly MUST be used.
+ * For descriptions of @a props and @a replaces_rev, see
+ * svn_editor_add_file().
  *
  * A complete listing of the immediate children of @a relpath that will be
  * added subsequently is given in @a children. @a children is an array of
@@ -737,7 +730,7 @@ svn_editor_add_directory(svn_editor_t *e
  * property name, each value is a const svn_string_t*. If no properties are
  * being set on the new file, @a props must be NULL.
  *
- * If this add is expected to replace a previously existing file or
+ * If this add is expected to replace a previously existing file, symlink or
  * directory at @a relpath, the revision number of the node to be replaced
  * must be given in @a replaces_rev. Otherwise, @a replaces_rev must be
  * SVN_INVALID_REVNUM.  Note: it is not allowed to call a "delete" followed
@@ -778,6 +771,7 @@ svn_editor_add_symlink(svn_editor_t *edi
  * Create an "absent" node of kind @a kind at @a relpath. The immediate
  * parent of @a relpath is expected to exist.
  * ### TODO @todo explain "absent".
+ * ### JAF: What are the allowed values of 'kind'?
  *
  * For a description of @a replaces_rev, see svn_editor_add_file().
  *
@@ -800,6 +794,8 @@ svn_editor_add_absent(svn_editor_t *edit
  * ### what about "entry props"? will these still be handled via
  * ### the general prop function?
  *
+ * For a description of @a props, see svn_editor_add_file().
+ *
  * @a complete must be FALSE if and only if
  * - @a relpath is a file and an svn_editor_set_text() call will follow on
  *   the same path, or

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/client.h?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/client.h (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/client.h Mon Nov  7 11:09:51 2011
@@ -105,6 +105,7 @@ svn_error_t *svn_client__get_copy_source
    specify the point(s) of interest (typically the revisions referred
    to as the "operative range" for a given operation) along that history.
 
+   START_REVISION and/or END_REVISION may be NULL if not wanted.
    END may be NULL or of kind svn_opt_revision_unspecified (in either case
    END_URL and END_REVISION are not touched by the function);
    START and REVISION may not.
@@ -131,9 +132,9 @@ svn_error_t *svn_client__get_copy_source
    Use POOL for all allocations.  */
 svn_error_t *
 svn_client__repos_locations(const char **start_url,
-                            svn_opt_revision_t **start_revision,
+                            svn_revnum_t *start_revision,
                             const char **end_url,
-                            svn_opt_revision_t **end_revision,
+                            svn_revnum_t *end_revision,
                             svn_ra_session_t *ra_session,
                             const char *path,
                             const svn_opt_revision_t *revision,
@@ -397,6 +398,19 @@ svn_error_t * svn_client__wc_delete(cons
                                     svn_client_ctx_t *ctx,
                                     apr_pool_t *pool);
 
+
+/* Like svn_client__wc_delete(), but deletes mulitple TARGETS efficiently. */
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+                           svn_boolean_t force,
+                           svn_boolean_t dry_run,
+                           svn_boolean_t keep_local,
+                           svn_wc_notify_func2_t notify_func,
+                           void *notify_baton,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *pool);
+
+
 /* Make PATH and add it to the working copy, optionally making all the
    intermediate parent directories if MAKE_PARENTS is TRUE. */
 svn_error_t *

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/copy.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/copy.c Mon Nov  7 11:09:51 2011
@@ -795,7 +795,6 @@ repos_to_repos_copy(const apr_array_head
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
       apr_hash_t *mergeinfo;
-      svn_opt_revision_t *src_rev;
 
       /* Are the source and destination URLs at or under REPOS_ROOT? */
       if (! (svn_uri__is_ancestor(repos_root, pair->src_abspath_or_url)
@@ -805,18 +804,11 @@ repos_to_repos_copy(const apr_array_head
            _("Source and destination URLs appear not to point to the "
              "same repository."));
 
-      /* Resolve revision keywords and such into real revision number,
-         passing NULL for the path (to ensure error if trying to get a
-         revision based on the working copy). */
-      SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, &youngest,
-                                              ctx->wc_ctx, NULL,
-                                              ra_session,
-                                              &pair->src_op_revision, pool));
-
-      /* Run the history function to get the source's URL in the
+      /* Run the history function to get the source's URL and revnum in the
          operational revision. */
       SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
-      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url, &src_rev,
+      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
+                                          &pair->src_revnum,
                                           NULL, NULL,
                                           ra_session,
                                           pair->src_abspath_or_url,
@@ -1826,11 +1818,10 @@ repos_to_wc_copy(const apr_array_header_
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
       const char *src;
-      svn_opt_revision_t *new_rev;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_client__repos_locations(&src, &new_rev, NULL, NULL,
+      SVN_ERR(svn_client__repos_locations(&src, &pair->src_revnum, NULL, NULL,
                                           NULL,
                                           pair->src_abspath_or_url,
                                           &pair->src_peg_revision,
@@ -1857,18 +1848,6 @@ repos_to_wc_copy(const apr_array_header_
                                                NULL, NULL, FALSE, TRUE,
                                                ctx, pool));
 
-  /* Pass null for the path, to ensure error if trying to get a
-     revision based on the working copy.  */
-  for (i = 0; i < copy_pairs->nelts; i++)
-    {
-      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
-                                                    svn_client__copy_pair_t *);
-
-      SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, NULL,
-                                              ctx->wc_ctx, NULL, ra_session,
-                                              &pair->src_op_revision, pool));
-    }
-
   /* Get the correct src path for the peg revision used, and verify that we
      aren't overwriting an existing path. */
   for (i = 0; i < copy_pairs->nelts; i++)

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/delete.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/delete.c Mon Nov  7 11:09:51 2011
@@ -329,10 +329,49 @@ svn_client__wc_delete(const char *path,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+                           svn_boolean_t force,
+                           svn_boolean_t dry_run,
+                           svn_boolean_t keep_local,
+                           svn_wc_notify_func2_t notify_func,
+                           void *notify_baton,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *pool)
+{
+  int i;
+  apr_array_header_t *abs_targets;
+
+  abs_targets = apr_array_make(pool, targets->nelts, sizeof(const char *));
+  for (i = 0; i < targets->nelts; i++)
+    {
+      const char *path = APR_ARRAY_IDX(targets, i, const char *);
+      const char *local_abspath;
+
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+      APR_ARRAY_PUSH(abs_targets, const char *) = local_abspath;
+
+      if (!force && !keep_local)
+        /* Verify that there are no "awkward" files */
+        SVN_ERR(svn_client__can_delete(local_abspath, ctx, pool));
+    }
+
+  if (!dry_run)
+    /* Mark the entry for commit deletion and perform wc deletion */
+    return svn_error_trace(svn_wc__delete_many(ctx->wc_ctx, abs_targets,
+                                               keep_local, TRUE,
+                                               ctx->cancel_func,
+                                               ctx->cancel_baton,
+                                               notify_func, notify_baton,
+                                               pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Callback baton for delete_with_write_lock_baton. */
 struct delete_with_write_lock_baton
 {
-  const char *path;
+  const apr_array_header_t *targets;
   svn_boolean_t force;
   svn_boolean_t keep_local;
   svn_client_ctx_t *ctx;
@@ -346,12 +385,11 @@ delete_with_write_lock_func(void *baton,
 {
   struct delete_with_write_lock_baton *args = baton;
 
-  /* Let the working copy library handle the PATH. */
-  return svn_client__wc_delete(args->path, args->force,
-                               FALSE, args->keep_local,
-                               args->ctx->notify_func2,
-                               args->ctx->notify_baton2,
-                               args->ctx, scratch_pool);
+  return svn_client__wc_delete_many(args->targets, args->force,
+                                    FALSE, args->keep_local,
+                                    args->ctx->notify_func2,
+                                    args->ctx->notify_baton2,
+                                    args->ctx, scratch_pool);
 }
 
 svn_error_t *
@@ -379,32 +417,76 @@ svn_client_delete4(const apr_array_heade
     }
   else
     {
-      apr_pool_t *subpool = svn_pool_create(pool);
+      struct delete_with_write_lock_baton dwwlb;
+      const char *wcroot_abspath;
+      const char *local_abspath;
+      apr_hash_t *wcroots;
+      apr_hash_index_t *hi;
       int i;
-
+      int j;
+      apr_pool_t *iterpool;
+      svn_boolean_t is_new_target;
+
+      /* Build a map of wcroots and targets within them. */
+      wcroots = apr_hash_make(pool);
+      iterpool = svn_pool_create(pool);
       for (i = 0; i < paths->nelts; i++)
         {
-          struct delete_with_write_lock_baton dwwlb;
-          const char *path = APR_ARRAY_IDX(paths, i, const char *);
-          const char *local_abspath;
+          apr_array_header_t *targets;
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
 
           /* See if the user wants us to stop. */
           if (ctx->cancel_func)
             SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-          SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
-          dwwlb.path = path;
+          SVN_ERR(svn_dirent_get_absolute(&local_abspath,
+                                          APR_ARRAY_IDX(paths, i,
+                                                        const char *),
+                                          pool));
+          SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
+                                      local_abspath, pool, iterpool));
+          targets = apr_hash_get(wcroots, wcroot_abspath,
+                                 APR_HASH_KEY_STRING);
+          if (targets == NULL)
+            {
+              targets = apr_array_make(pool, 1, sizeof(const char *));
+              apr_hash_set(wcroots, wcroot_abspath, APR_HASH_KEY_STRING,
+                           targets);
+             }
+
+          /* Make sure targets are unique. */
+          is_new_target = TRUE;
+          for (j = 0; j < targets->nelts; j++)
+            {
+              if (strcmp(APR_ARRAY_IDX(targets, j, const char *),
+                         local_abspath) == 0)
+                {
+                  is_new_target = FALSE;
+                  break;
+                }
+            }
+
+          if (is_new_target)
+            APR_ARRAY_PUSH(targets, const char *) = local_abspath;
+        }
+
+      /* Delete the targets from each working copy in turn. */
+      for (hi = apr_hash_first(pool, wcroots); hi; hi = apr_hash_next(hi))
+        {
+          svn_pool_clear(iterpool);
+
+          wcroot_abspath = svn__apr_hash_index_key(hi);
+          dwwlb.targets = svn__apr_hash_index_val(hi);
           dwwlb.force = force;
           dwwlb.keep_local = keep_local;
           dwwlb.ctx = ctx;
           SVN_ERR(svn_wc__call_with_write_lock(delete_with_write_lock_func,
                                                &dwwlb, ctx->wc_ctx,
-                                               local_abspath, TRUE,
-                                               pool, subpool));
+                                               wcroot_abspath, TRUE,
+                                               iterpool, iterpool));
         }
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(iterpool);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/diff.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/diff.c Mon Nov  7 11:09:51 2011
@@ -72,7 +72,7 @@ static const char under_string[] =
 
 /* A helper function for display_prop_diffs.  Output the differences between
    the mergeinfo stored in ORIG_MERGEINFO_VAL and NEW_MERGEINFO_VAL in a
-   human-readable form to FILE, using ENCODING.  Use POOL for temporary
+   human-readable form to OUTSTREAM, using ENCODING.  Use POOL for temporary
    allocations. */
 static svn_error_t *
 display_mergeinfo_diff(const char *old_mergeinfo_val,
@@ -509,8 +509,8 @@ print_git_diff_header(svn_stream_t *os,
 }
 
 /* A helper func that writes out verbal descriptions of property diffs
-   to FILE.   Of course, OUTSTREAM will probably be whatever was
-   passed to svn_client_diff5, which is probably stdout.
+   to OUTSTREAM.   Of course, OUTSTREAM will probably be whatever was
+   passed to svn_client_diff6(), which is probably stdout.
 
    ### FIXME needs proper docstring
 
@@ -741,7 +741,7 @@ struct diff_cmd_baton {
   const char *orig_path_2;
 
   /* These are the numeric representations of the revisions passed to
-     svn_client_diff5, either may be SVN_INVALID_REVNUM.  We need these
+     svn_client_diff6(), either may be SVN_INVALID_REVNUM.  We need these
      because some of the svn_wc_diff_callbacks4_t don't get revision
      arguments.
 
@@ -1377,16 +1377,17 @@ convert_to_url(const char **url,
   return SVN_NO_ERROR;
 }
 
-/** Check if paths PATH1 and PATH2 are urls and if the revisions REVISION1
- *  and REVISION2 are local. If PEG_REVISION is not unspecified, ensure that
- *  at least one of the two revisions is non-local.
- *  If PATH1 can only be found in the repository, set *IS_REPOS1 to TRUE.
- *  If PATH2 can only be found in the repository, set *IS_REPOS2 to TRUE. */
+/** Check if paths PATH_OR_URL1 and PATH_OR_URL2 are urls and if the
+ * revisions REVISION1 and REVISION2 are local. If PEG_REVISION is not
+ * unspecified, ensure that at least one of the two revisions is non-local.
+ * If PATH_OR_URL1 can only be found in the repository, set *IS_REPOS1
+ * to TRUE. If PATH_OR_URL2 can only be found in the repository, set
+ * *IS_REPOS2 to TRUE. */
 static svn_error_t *
 check_paths(svn_boolean_t *is_repos1,
             svn_boolean_t *is_repos2,
-            const char *path1,
-            const char *path2,
+            const char *path_or_url1,
+            const char *path_or_url2,
             const svn_opt_revision_t *revision1,
             const svn_opt_revision_t *revision2,
             const svn_opt_revision_t *peg_revision)
@@ -1424,15 +1425,15 @@ check_paths(svn_boolean_t *is_repos1,
          URLs.  We don't do that here, though.  We simply record that it
          needs to be done, which is information that helps us choose our
          diff helper function.  */
-      *is_repos1 = ! is_local_rev1 || svn_path_is_url(path1);
-      *is_repos2 = ! is_local_rev2 || svn_path_is_url(path2);
+      *is_repos1 = ! is_local_rev1 || svn_path_is_url(path_or_url1);
+      *is_repos2 = ! is_local_rev2 || svn_path_is_url(path_or_url2);
     }
 
   return SVN_NO_ERROR;
 }
 
-/** Prepare a repos repos diff between PATH1 and PATH2@PEG_REVISION,
- * in the revision range REVISION1:REVISION2.
+/** Prepare a repos repos diff between PATH_OR_URL1 and
+ * PATH_OR_URL2@PEG_REVISION, in the revision range REVISION1:REVISION2.
  * Return URLs and peg revisions in *URL1, *REV1 and in *URL2, *REV2.
  * Return suitable anchors in *ANCHOR1 and *ANCHOR2, and targets in
  * *TARGET1 and *TARGET2, based on *URL1 and *URL2.
@@ -1451,43 +1452,43 @@ diff_prepare_repos_repos(const char **ur
                          const char **target2,
                          svn_ra_session_t **ra_session,
                          svn_client_ctx_t *ctx,
-                         const char *path1,
-                         const char *path2,
+                         const char *path_or_url1,
+                         const char *path_or_url2,
                          const svn_opt_revision_t *revision1,
                          const svn_opt_revision_t *revision2,
                          const svn_opt_revision_t *peg_revision,
                          apr_pool_t *pool)
 {
   svn_node_kind_t kind1, kind2;
-  const char *path2_abspath;
-  const char *path1_abspath;
+  const char *abspath_or_url2;
+  const char *abspath_or_url1;
 
-  if (!svn_path_is_url(path2))
-    SVN_ERR(svn_dirent_get_absolute(&path2_abspath, path2,
+  if (!svn_path_is_url(path_or_url2))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url2, path_or_url2,
                                     pool));
   else
-    path2_abspath = path2;
+    abspath_or_url2 = path_or_url2;
 
-  if (!svn_path_is_url(path1))
-    SVN_ERR(svn_dirent_get_absolute(&path1_abspath, path1,
+  if (!svn_path_is_url(path_or_url1))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url1, path_or_url1,
                                     pool));
   else
-    path1_abspath = path1;
+    abspath_or_url1 = path_or_url1;
 
   /* Figure out URL1 and URL2. */
-  SVN_ERR(convert_to_url(url1, ctx->wc_ctx, path1_abspath,
+  SVN_ERR(convert_to_url(url1, ctx->wc_ctx, abspath_or_url1,
                          pool, pool));
-  SVN_ERR(convert_to_url(url2, ctx->wc_ctx, path2_abspath,
+  SVN_ERR(convert_to_url(url2, ctx->wc_ctx, abspath_or_url2,
                          pool, pool));
 
   /* We need exactly one BASE_PATH, so we'll let the BASE_PATH
-     calculated for PATH2 override the one for PATH1 (since the diff
-     will be "applied" to URL2 anyway). */
+     calculated for PATH_OR_URL2 override the one for PATH_OR_URL1
+     (since the diff will be "applied" to URL2 anyway). */
   *base_path = NULL;
-  if (strcmp(*url1, path1) != 0)
-    *base_path = path1;
-  if (strcmp(*url2, path2) != 0)
-    *base_path = path2;
+  if (strcmp(*url1, path_or_url1) != 0)
+    *base_path = path_or_url1;
+  if (strcmp(*url2, path_or_url2) != 0)
+    *base_path = path_or_url2;
 
   SVN_ERR(svn_client__open_ra_session_internal(ra_session, NULL, *url2,
                                                NULL, NULL, FALSE,
@@ -1497,12 +1498,10 @@ diff_prepare_repos_repos(const char **ur
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
     {
-      svn_opt_revision_t *start_ignore, *end_ignore;
-
-      SVN_ERR(svn_client__repos_locations(url1, &start_ignore,
-                                          url2, &end_ignore,
+      SVN_ERR(svn_client__repos_locations(url1, NULL,
+                                          url2, NULL,
                                           *ra_session,
-                                          path2,
+                                          path_or_url2,
                                           peg_revision,
                                           revision1,
                                           revision2,
@@ -1514,7 +1513,7 @@ diff_prepare_repos_repos(const char **ur
 
   /* Resolve revision and get path kind for the second target. */
   SVN_ERR(svn_client__get_revision_number(rev2, NULL, ctx->wc_ctx,
-           (path2 == *url2) ? NULL : path2_abspath,
+           (path_or_url2 == *url2) ? NULL : abspath_or_url2,
            *ra_session, revision2, pool));
   SVN_ERR(svn_ra_check_path(*ra_session, "", *rev2, &kind2, pool));
   if (kind2 == svn_node_none)
@@ -1526,7 +1525,7 @@ diff_prepare_repos_repos(const char **ur
   /* Do the same for the first target. */
   SVN_ERR(svn_ra_reparent(*ra_session, *url1, pool));
   SVN_ERR(svn_client__get_revision_number(rev1, NULL, ctx->wc_ctx,
-           (strcmp(path1, *url1) == 0) ? NULL : path1_abspath,
+           (strcmp(path_or_url1, *url1) == 0) ? NULL : abspath_or_url1,
            *ra_session, revision1, pool));
   SVN_ERR(svn_ra_check_path(*ra_session, "", *rev1, &kind1, pool));
   if (kind1 == svn_node_none)
@@ -1554,8 +1553,8 @@ diff_prepare_repos_repos(const char **ur
 
 /* A Theoretical Note From Ben, regarding do_diff().
 
-   This function is really svn_client_diff5().  If you read the public
-   API description for svn_client_diff5(), it sounds quite Grand.  It
+   This function is really svn_client_diff6().  If you read the public
+   API description for svn_client_diff6(), it sounds quite Grand.  It
    sounds really generalized and abstract and beautiful: that it will
    diff any two paths, be they working-copy paths or URLs, at any two
    revisions.
@@ -1575,7 +1574,7 @@ diff_prepare_repos_repos(const char **ur
    pigeonholed into one of these three use-cases, we currently bail
    with a friendly apology.
 
-   Perhaps someday a brave soul will truly make svn_client_diff5
+   Perhaps someday a brave soul will truly make svn_client_diff6()
    perfectly general.  For now, we live with the 90% case.  Certainly,
    the commandline client only calls this function in legal ways.
    When there are other users of svn_client.h, maybe this will become
@@ -1588,7 +1587,7 @@ static svn_error_t *
 unsupported_diff_error(svn_error_t *child_err)
 {
   return svn_error_create(SVN_ERR_INCORRECT_PARAMS, child_err,
-                          _("Sorry, svn_client_diff5 was called in a way "
+                          _("Sorry, svn_client_diff6 was called in a way "
                             "that is not yet supported"));
 }
 
@@ -1598,7 +1597,7 @@ unsupported_diff_error(svn_error_t *chil
    PATH1 and PATH2 are both working copy paths.  REVISION1 and
    REVISION2 are their respective revisions.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_wc_wc(const char *path1,
            const svn_opt_revision_t *revision1,
@@ -1674,19 +1673,19 @@ diff_wc_wc(const char *path1,
 
 /* Perform a diff between two repository paths.
 
-   PATH1 and PATH2 may be either URLs or the working copy paths.
+   PATH_OR_URL1 and PATH_OR_URL2 may be either URLs or the working copy paths.
    REVISION1 and REVISION2 are their respective revisions.
-   If PEG_REVISION is specified, PATH2 is the path at the peg revision,
+   If PEG_REVISION is specified, PATH_OR_URL2 is the path at the peg revision,
    and the actual two paths compared are determined by following copy
-   history from PATH2.
+   history from PATH_OR_URL2.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_repos_repos(const svn_wc_diff_callbacks4_t *callbacks,
                  struct diff_cmd_baton *callback_baton,
                  svn_client_ctx_t *ctx,
-                 const char *path1,
-                 const char *path2,
+                 const char *path_or_url1,
+                 const char *path_or_url2,
                  const svn_opt_revision_t *revision1,
                  const svn_opt_revision_t *revision2,
                  const svn_opt_revision_t *peg_revision,
@@ -1716,7 +1715,7 @@ diff_repos_repos(const svn_wc_diff_callb
   /* Prepare info for the repos repos diff. */
   SVN_ERR(diff_prepare_repos_repos(&url1, &url2, &base_path, &rev1, &rev2,
                                    &anchor1, &anchor2, &target1, &target2,
-                                   &ra_session, ctx, path1, path2,
+                                   &ra_session, ctx, path_or_url1, path_or_url2,
                                    revision1, revision2, peg_revision,
                                    pool));
 
@@ -1767,16 +1766,16 @@ diff_repos_repos(const svn_wc_diff_callb
 
 /* Perform a diff between a repository path and a working-copy path.
 
-   PATH1 may be either a URL or a working copy path.  PATH2 is a
+   PATH_OR_URL1 may be either a URL or a working copy path.  PATH2 is a
    working copy path.  REVISION1 and REVISION2 are their respective
    revisions.  If REVERSE is TRUE, the diff will be done in reverse.
-   If PEG_REVISION is specified, then PATH1 is the path in the peg
+   If PEG_REVISION is specified, then PATH_OR_URL1 is the path in the peg
    revision, and the actual repository path to be compared is
    determined by following copy history.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
-diff_repos_wc(const char *path1,
+diff_repos_wc(const char *path_or_url1,
               const svn_opt_revision_t *revision1,
               const svn_opt_revision_t *peg_revision,
               const char *path2,
@@ -1802,21 +1801,21 @@ diff_repos_wc(const char *path1,
   void *diff_edit_baton;
   svn_boolean_t rev2_is_base = (revision2->kind == svn_opt_revision_base);
   svn_boolean_t server_supports_depth;
-  const char *abspath1;
+  const char *abspath_or_url1;
   const char *abspath2;
   const char *anchor_abspath;
 
   SVN_ERR_ASSERT(! svn_path_is_url(path2));
 
-  if (!svn_path_is_url(path1))
-    SVN_ERR(svn_dirent_get_absolute(&abspath1, path1, pool));
+  if (!svn_path_is_url(path_or_url1))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url1, path_or_url1, pool));
   else
-    abspath1 = path1;
+    abspath_or_url1 = path_or_url1;
 
   SVN_ERR(svn_dirent_get_absolute(&abspath2, path2, pool));
 
-  /* Convert path1 to a URL to feed to do_diff. */
-  SVN_ERR(convert_to_url(&url1, ctx->wc_ctx, abspath1, pool, pool));
+  /* Convert path_or_url1 to a URL to feed to do_diff. */
+  SVN_ERR(convert_to_url(&url1, ctx->wc_ctx, abspath_or_url1, pool, pool));
 
   SVN_ERR(svn_wc_get_actual_target2(&anchor, &target,
                                     ctx->wc_ctx, path2,
@@ -1835,11 +1834,9 @@ diff_repos_wc(const char *path1,
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
     {
-      svn_opt_revision_t *start_ignore;
-
-      SVN_ERR(svn_client__repos_locations(&url1, &start_ignore, NULL, NULL,
+      SVN_ERR(svn_client__repos_locations(&url1, NULL, NULL, NULL,
                                           NULL,
-                                          path1,
+                                          path_or_url1,
                                           peg_revision,
                                           revision1, NULL,
                                           ctx, pool));
@@ -1891,8 +1888,8 @@ diff_repos_wc(const char *path1,
 
   /* Tell the RA layer we want a delta to change our txn to URL1 */
   SVN_ERR(svn_client__get_revision_number(&rev, NULL, ctx->wc_ctx,
-                                          (strcmp(path1, url1) == 0)
-                                                    ? NULL : abspath1,
+                                          (strcmp(path_or_url1, url1) == 0)
+                                                    ? NULL : abspath_or_url1,
                                           ra_session, revision1, pool));
 
   if (!reverse)
@@ -1929,13 +1926,13 @@ diff_repos_wc(const char *path1,
 }
 
 
-/* This is basically just the guts of svn_client_diff[_peg]5(). */
+/* This is basically just the guts of svn_client_diff[_peg]6(). */
 static svn_error_t *
 do_diff(const svn_wc_diff_callbacks4_t *callbacks,
         struct diff_cmd_baton *callback_baton,
         svn_client_ctx_t *ctx,
-        const char *path1,
-        const char *path2,
+        const char *path_or_url1,
+        const char *path_or_url2,
         const svn_opt_revision_t *revision1,
         const svn_opt_revision_t *revision2,
         const svn_opt_revision_t *peg_revision,
@@ -1950,7 +1947,7 @@ do_diff(const svn_wc_diff_callbacks4_t *
   svn_boolean_t is_repos2;
 
   /* Check if paths/revisions are urls/local. */
-  SVN_ERR(check_paths(&is_repos1, &is_repos2, path1, path2,
+  SVN_ERR(check_paths(&is_repos1, &is_repos2, path_or_url1, path_or_url2,
                       revision1, revision2, peg_revision));
 
   if (is_repos1)
@@ -1959,32 +1956,33 @@ do_diff(const svn_wc_diff_callbacks4_t *
         {
           /* ### Ignores 'show_copies_as_adds'. */
           SVN_ERR(diff_repos_repos(callbacks, callback_baton, ctx,
-                                   path1, path2, revision1, revision2,
+                                   path_or_url1, path_or_url2,
+                                   revision1, revision2,
                                    peg_revision, depth, ignore_ancestry,
                                    pool));
         }
-      else /* path2 is a working copy path */
+      else /* path_or_url2 is a working copy path */
         {
-          SVN_ERR(diff_repos_wc(path1, revision1, peg_revision,
-                                path2, revision2, FALSE, depth,
+          SVN_ERR(diff_repos_wc(path_or_url1, revision1, peg_revision,
+                                path_or_url2, revision2, FALSE, depth,
                                 ignore_ancestry, show_copies_as_adds,
                                 use_git_diff_format, changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
     }
-  else /* path1 is a working copy path */
+  else /* path_or_url1 is a working copy path */
     {
       if (is_repos2)
         {
-          SVN_ERR(diff_repos_wc(path2, revision2, peg_revision,
-                                path1, revision1, TRUE, depth,
+          SVN_ERR(diff_repos_wc(path_or_url2, revision2, peg_revision,
+                                path_or_url1, revision1, TRUE, depth,
                                 ignore_ancestry, show_copies_as_adds,
                                 use_git_diff_format, changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
-      else /* path2 is a working copy path */
+      else /* path_or_url2 is a working copy path */
         {
-          SVN_ERR(diff_wc_wc(path1, revision1, path2, revision2,
+          SVN_ERR(diff_wc_wc(path_or_url1, revision1, path_or_url2, revision2,
                              depth, ignore_ancestry, show_copies_as_adds,
                              use_git_diff_format, changelists,
                              callbacks, callback_baton, ctx, pool));
@@ -1999,7 +1997,7 @@ do_diff(const svn_wc_diff_callbacks4_t *
    PATH1 and PATH2 are both working copy paths.  REVISION1 and
    REVISION2 are their respective revisions.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_summarize_wc_wc(svn_client_diff_summarize_func_t summarize_func,
                      void *summarize_baton,
@@ -2057,8 +2055,8 @@ static svn_error_t *
 diff_summarize_repos_repos(svn_client_diff_summarize_func_t summarize_func,
                            void *summarize_baton,
                            svn_client_ctx_t *ctx,
-                           const char *path1,
-                           const char *path2,
+                           const char *path_or_url1,
+                           const char *path_or_url2,
                            const svn_opt_revision_t *revision1,
                            const svn_opt_revision_t *revision2,
                            const svn_opt_revision_t *peg_revision,
@@ -2091,7 +2089,7 @@ diff_summarize_repos_repos(svn_client_di
   SVN_ERR(diff_prepare_repos_repos(&url1, &url2, &base_path, &rev1, &rev2,
                                    &anchor1, &anchor2, &target1, &target2,
                                    &ra_session, ctx,
-                                   path1, path2, revision1, revision2,
+                                   path_or_url1, path_or_url2, revision1, revision2,
                                    peg_revision, pool));
 
   SVN_ERR(svn_client__get_diff_summarize_callbacks(
@@ -2132,8 +2130,8 @@ static svn_error_t *
 do_diff_summarize(svn_client_diff_summarize_func_t summarize_func,
                   void *summarize_baton,
                   svn_client_ctx_t *ctx,
-                  const char *path1,
-                  const char *path2,
+                  const char *path_or_url1,
+                  const char *path_or_url2,
                   const svn_opt_revision_t *revision1,
                   const svn_opt_revision_t *revision2,
                   const svn_opt_revision_t *peg_revision,
@@ -2146,17 +2144,19 @@ do_diff_summarize(svn_client_diff_summar
   svn_boolean_t is_repos2;
 
   /* Check if paths/revisions are urls/local. */
-  SVN_ERR(check_paths(&is_repos1, &is_repos2, path1, path2,
+  SVN_ERR(check_paths(&is_repos1, &is_repos2, path_or_url1, path_or_url2,
                       revision1, revision2, peg_revision));
 
   if (is_repos1 && is_repos2)
     return diff_summarize_repos_repos(summarize_func, summarize_baton, ctx,
-                                      path1, path2, revision1, revision2,
+                                      path_or_url1, path_or_url2,
+                                      revision1, revision2,
                                       peg_revision, depth, ignore_ancestry,
                                       pool);
   else if (! is_repos1 && ! is_repos2)
     return diff_summarize_wc_wc(summarize_func, summarize_baton,
-                                path1, revision1, path2, revision2,
+                                path_or_url1, revision1,
+                                path_or_url2, revision2,
                                 depth, ignore_ancestry,
                                 changelists, ctx, pool);
   else
@@ -2270,9 +2270,9 @@ set_up_diff_cmd_and_options(struct diff_
 */
 svn_error_t *
 svn_client_diff6(const apr_array_header_t *options,
-                 const char *path1,
+                 const char *path_or_url1,
                  const svn_opt_revision_t *revision1,
-                 const char *path2,
+                 const char *path_or_url2,
                  const svn_opt_revision_t *revision2,
                  const char *relative_to_dir,
                  svn_depth_t depth,
@@ -2295,8 +2295,8 @@ svn_client_diff6(const apr_array_header_
   peg_revision.kind = svn_opt_revision_unspecified;
 
   /* setup callback and baton */
-  diff_cmd_baton.orig_path_1 = path1;
-  diff_cmd_baton.orig_path_2 = path2;
+  diff_cmd_baton.orig_path_1 = path_or_url1;
+  diff_cmd_baton.orig_path_2 = path_or_url2;
 
   SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
                                       ctx->config, pool));
@@ -2319,14 +2319,15 @@ svn_client_diff6(const apr_array_header_
   diff_cmd_baton.anchor = NULL;
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
-                 path1, path2, revision1, revision2, &peg_revision,
+                 path_or_url1, path_or_url2, revision1, revision2,
+                 &peg_revision,
                  depth, ignore_ancestry, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
 svn_error_t *
 svn_client_diff_peg6(const apr_array_header_t *options,
-                     const char *path,
+                     const char *path_or_url,
                      const svn_opt_revision_t *peg_revision,
                      const svn_opt_revision_t *start_revision,
                      const svn_opt_revision_t *end_revision,
@@ -2347,8 +2348,8 @@ svn_client_diff_peg6(const apr_array_hea
   struct diff_cmd_baton diff_cmd_baton = { 0 };
 
   /* setup callback and baton */
-  diff_cmd_baton.orig_path_1 = path;
-  diff_cmd_baton.orig_path_2 = path;
+  diff_cmd_baton.orig_path_1 = path_or_url;
+  diff_cmd_baton.orig_path_2 = path_or_url;
 
   SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
                                       ctx->config, pool));
@@ -2371,15 +2372,16 @@ svn_client_diff_peg6(const apr_array_hea
   diff_cmd_baton.anchor = NULL;
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
-                 path, path, start_revision, end_revision, peg_revision,
+                 path_or_url, path_or_url, start_revision, end_revision,
+                 peg_revision,
                  depth, ignore_ancestry, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
 svn_error_t *
-svn_client_diff_summarize2(const char *path1,
+svn_client_diff_summarize2(const char *path_or_url1,
                            const svn_opt_revision_t *revision1,
-                           const char *path2,
+                           const char *path_or_url2,
                            const svn_opt_revision_t *revision2,
                            svn_depth_t depth,
                            svn_boolean_t ignore_ancestry,
@@ -2394,12 +2396,13 @@ svn_client_diff_summarize2(const char *p
   peg_revision.kind = svn_opt_revision_unspecified;
 
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
-                           path1, path2, revision1, revision2, &peg_revision,
+                           path_or_url1, path_or_url2, revision1, revision2,
+                           &peg_revision,
                            depth, ignore_ancestry, changelists, pool);
 }
 
 svn_error_t *
-svn_client_diff_summarize_peg2(const char *path,
+svn_client_diff_summarize_peg2(const char *path_or_url,
                                const svn_opt_revision_t *peg_revision,
                                const svn_opt_revision_t *start_revision,
                                const svn_opt_revision_t *end_revision,
@@ -2412,8 +2415,8 @@ svn_client_diff_summarize_peg2(const cha
                                apr_pool_t *pool)
 {
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
-                           path, path, start_revision, end_revision,
-                           peg_revision,
+                           path_or_url, path_or_url,
+                           start_revision, end_revision, peg_revision,
                            depth, ignore_ancestry, changelists, pool);
 }
 

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/externals.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/externals.c Mon Nov  7 11:09:51 2011
@@ -943,7 +943,7 @@ svn_client__handle_externals(apr_hash_t 
     {
       const char *item_abspath = svn__apr_hash_index_key(hi);
       const char *defining_abspath = svn__apr_hash_index_val(hi);
-      svn_wc_status3_t *defining_status;
+      const char *parent_abspath;
 
       svn_pool_clear(iterpool);
 
@@ -953,19 +953,29 @@ svn_client__handle_externals(apr_hash_t 
                                                        item_abspath, iterpool),
                           iterpool));
 
-      /* Is DEFINING_ABSPATH now an unversioned directory we can remove? */
-      SVN_ERR(svn_wc_status3(&defining_status, ctx->wc_ctx, defining_abspath,
-                             iterpool, iterpool));
-      if (defining_status->node_status == svn_wc_status_unversioned)
-        {
-          svn_error_t *err;
-
-          err = svn_io_dir_remove_nonrecursive(defining_abspath, iterpool);
-          if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
-            svn_error_clear(err);
-          else
-            SVN_ERR(err);
-        }
+      /* Are there any unversioned directories between the removed
+       * external and the DEFINING_ABSPATH which we can remove? */
+      parent_abspath = item_abspath;
+      do {
+        svn_wc_status3_t *parent_status;
+
+        parent_abspath = svn_dirent_dirname(parent_abspath, iterpool);
+        SVN_ERR(svn_wc_status3(&parent_status, ctx->wc_ctx, parent_abspath,
+                               iterpool, iterpool));
+        if (parent_status->node_status == svn_wc_status_unversioned)
+          {
+            svn_error_t *err;
+
+            err = svn_io_dir_remove_nonrecursive(parent_abspath, iterpool);
+            if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
+              {
+                svn_error_clear(err);
+                break;
+              }
+            else
+              SVN_ERR(err);
+          }
+      } while (strcmp(parent_abspath, defining_abspath) != 0);
     }
 
 

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/info.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/info.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/info.c Mon Nov  7 11:09:51 2011
@@ -187,14 +187,13 @@ same_resource_in_head(svn_boolean_t *sam
 {
   svn_error_t *err;
   svn_opt_revision_t start_rev, peg_rev;
-  svn_opt_revision_t *ignored_rev;
   const char *head_url;
 
   start_rev.kind = svn_opt_revision_head;
   peg_rev.kind = svn_opt_revision_number;
   peg_rev.value.number = rev;
 
-  err = svn_client__repos_locations(&head_url, &ignored_rev, NULL, NULL,
+  err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                     ra_session,
                                     url, &peg_rev,
                                     &start_rev, NULL,

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c Mon Nov  7 11:09:51 2011
@@ -928,7 +928,6 @@ filter_self_referential_mergeinfo(apr_ar
               for (j = 0; j < rangelist->nelts; j++)
                 {
                   svn_error_t *err2;
-                  svn_opt_revision_t *start_revision;
                   const char *start_url;
                   svn_opt_revision_t peg_rev, rev1_opt;
                   svn_merge_range_t *range =
@@ -949,10 +948,8 @@ filter_self_referential_mergeinfo(apr_ar
 
                   /* Check if PATH@BASE_REVISION exists at
                      RANGE->START on the same line of history. */
-                  err2 = svn_client__repos_locations(&start_url,
-                                                     &start_revision,
-                                                     NULL,
-                                                     NULL,
+                  err2 = svn_client__repos_locations(&start_url, NULL,
+                                                     NULL, NULL,
                                                      ra_session,
                                                      target_url,
                                                      &peg_rev,
@@ -3971,13 +3968,13 @@ calculate_remaining_ranges(svn_client__m
          from our own future return a helpful error. */
       svn_error_t *err;
       const char *start_url;
-      svn_opt_revision_t requested, pegrev, *start_revision;
+      svn_opt_revision_t requested, pegrev;
       requested.kind = svn_opt_revision_number;
       requested.value.number = child_base_revision;
       pegrev.kind = svn_opt_revision_number;
       pegrev.value.number = revision1;
 
-      err = svn_client__repos_locations(&start_url, &start_revision,
+      err = svn_client__repos_locations(&start_url, NULL,
                                         NULL, NULL, ra_session, url1,
                                         &pegrev, &requested,
                                         NULL, ctx, scratch_pool);
@@ -6461,13 +6458,13 @@ normalize_merge_sources(apr_array_header
   if (peg_revnum < youngest_requested)
     {
       const char *start_url;
-      svn_opt_revision_t requested, pegrev, *start_revision;
+      svn_opt_revision_t requested, pegrev;
       requested.kind = svn_opt_revision_number;
       requested.value.number = youngest_requested;
       pegrev.kind = svn_opt_revision_number;
       pegrev.value.number = peg_revnum;
 
-      SVN_ERR(svn_client__repos_locations(&start_url, &start_revision,
+      SVN_ERR(svn_client__repos_locations(&start_url, NULL,
                                           NULL, NULL,
                                           ra_session, source_url,
                                           &pegrev, &requested,
@@ -10529,7 +10526,6 @@ calculate_left_hand_side(const char **ur
          youngest_merged_rev, from TARGET_ABSPATH to the source.  Set
          *URL_LEFT and *REV_LEFT to cover the youngest part of this range. */
       svn_opt_revision_t peg_revision, youngest_rev;
-      svn_opt_revision_t *start_revision;
       const char *youngest_url;
 
       peg_revision.kind = svn_opt_revision_number;
@@ -10541,7 +10537,7 @@ calculate_left_hand_side(const char **ur
       *rev_left = youngest_rev.value.number;
 
       /* Get the URL of the target_url@youngest_merged_rev. */
-      SVN_ERR(svn_client__repos_locations(&youngest_url, &start_revision,
+      SVN_ERR(svn_client__repos_locations(&youngest_url, NULL,
                                           NULL, NULL, target_ra_session,
                                           target_url, &peg_revision,
                                           &youngest_rev, NULL,

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/patch.c?rev=1198703&r1=1198702&r2=1198703&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/patch.c Mon Nov  7 11:09:51 2011
@@ -811,13 +811,20 @@ write_file(void *baton, const char *buf,
  * with the fewest path components, the shortest basename, and the shortest
  * total file name length (in that order). In case of a tie, return the new
  * filename. This heuristic is also used by Larry Wall's UNIX patch (except
- * that it prompts for a filename in case of a tie). */
+ * that it prompts for a filename in case of a tie).
+ * Additionally, for compatibility with git, if one of the filenames
+ * is "/dev/null", use the other filename. */
 static const char *
 choose_target_filename(const svn_patch_t *patch)
 {
   apr_size_t old;
   apr_size_t new;
 
+  if (strcmp(patch->old_filename, "/dev/null") == 0)
+    return patch->new_filename;
+  if (strcmp(patch->new_filename, "/dev/null") == 0)
+    return patch->old_filename;
+
   old = svn_path_component_count(patch->old_filename);
   new = svn_path_component_count(patch->new_filename);