Selecting "diff-full" doesn't show the correct diff during interactive merge
conflict resolution on a cherry pick. Also happens in 1.6.

A small reproduction script is attached as 'diff-full'.

This is what I get from it, a little whitespace added:

[[[
[...]
+ svn merge -c7 '^/branch' trunk/
Conflict discovered in '/tmp/diff-full.A7B/wc/trunk/a'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:
                              df<CR>

--- /tmp/svn-qww3lB     Thu Sep 29 02:27:42 2011
+++ /tmp/diff-full.A7B/wc/.svn/tmp/a.tmp        Thu Sep 29 02:27:42 2011
@@ -1,6 +1,11 @@
-apples
-oranges
-tomatoes
+r3
+r5
+r4
 cheese
-r6
+potatoes

+<<<<<<< .working
+pasta r5
+=======
+pie r7
+>>>>>>> .merge-right.r7


Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:
                              p<CR>

--- Merging r7 into 'trunk':
C    trunk/a
--- Recording mergeinfo for merge of r7 into 'trunk':
 U   trunk
Summary of conflicts:
  Text conflicts: 1


+ svn diff
Index: trunk
===================================================================
--- trunk       (revision 8)
+++ trunk       (working copy)

Property changes on: trunk
___________________________________________________________________
Added: svn:mergeinfo
   Merged /branch:r7
Index: trunk/a
===================================================================
--- trunk/a     (revision 8)
+++ trunk/a     (working copy)
@@ -4,4 +4,8 @@
 cheese
 potatoes

+<<<<<<< .working
 pasta r5
+=======
+pie r7
+>>>>>>> .merge-right.r7
]]]


The diff upon 'df' drastically differs from 'svn diff' afterwards. 'svn
diff' is right and 'df' is wrong in that shows changes that already are in
in the WC's BASE.

I got much larger such diff divergences, getting completely unrelated diff
chunks, trying to merge -c1174693 to 1.7.x. The second and third attached
files show the differnt outputs on client/externals.c only, i.e.:

  cd wc_1.7.x/
  svn up                # if you're far in the future, try -r 1177000
  svn merge -c1174693 \
      ^/subversion/trunk/subversion/libsvn_client/externals.c \
      subversion/libsvn_client/externals.c
   df<CR>
   p<CR>
  svn diff

If I extrapolate above small test, these weird diff chunks should also all
be trivially applied to the WC, but I haven't checked all of them in detail.
They are highly confusing, that's for sure.

Any ideas / stuff I'm not aware of?

~Neels
#!/usr/bin/env bash

## TO MAKE THIS RUN YOUR CUSTOM COMPILED SVN, two simple options:
## 1. Adjust your PATH to point at your custom installed location:
##      export PATH="$HOME/prefix/svn_trunk/bin:$PATH"
## OR
## 2. Uncomment the four lines below to use aliases into your
##    built source tree. The next line is the only line you should
##    need to adjust.
# SVNDIR=/path/to/built_subversion_source_tree
# function svn() { "$SVNDIR/subversion/svn/svn" "$@"; }
# function svnserve() { "$SVNDIR/subversion/svnserve/svnserve" "$@"; }
# function svnadmin() { "$SVNDIR/subversion/svnadmin/svnadmin" "$@"; }

set -e

svn --version
BASE="$(mktemp -d "/tmp/$(basename "$0").XXX")"
echo "BASE = $BASE"
REPOS="$BASE/repos"
WC="$BASE/wc"
URL="file://$REPOS"
svnadmin create "$REPOS"

svn co -q "$URL" "$WC"

set +e
set -x
cd "$WC"

## ACTUAL TEST

mkdir trunk
echo "apples
oranges
tomatoes
cheese
potatoes
" > trunk/a
svn add trunk
svn ci -m1
svn cp -m2 ^/trunk ^/branch
svn up

change() {
  sed -i "s/^$1\$/$2/" a
  svn ci -mm
}

cd trunk
  change apples r3
  change tomatoes r4
  echo pasta r5 >> a
  change oranges r5
cd ..

cd branch
  change potatoes r6
  echo pie r7 >> a
  svn ci -m7
  change cheese r8
cd ..

svn up
echo -e "df\np\n" | svn merge -c7 ^/branch trunk/
svn diff

## END
set +x
echo "BASE = $BASE"
--- /home/neels/pat/1.7.x/src/subversion/libsvn_client/svn-JsHo0I       Thu Sep 
29 00:59:53 2011
+++ /home/neels/pat/1.7.x/src/.svn/tmp/externals.c.3.tmp        Thu Sep 29 
00:59:53 2011
@@ -126,8 +126,8 @@
 static svn_error_t *
 switch_dir_external(const char *local_abspath,
                     const char *url,
+                    const svn_opt_revision_t *revision,
                     const svn_opt_revision_t *peg_revision,
-                    const svn_opt_revision_t *revision,
                     const char *defining_abspath,
                     svn_boolean_t *timestamp_sleep,
                     svn_client_ctx_t *ctx,
@@ -135,18 +135,10 @@
 {
   svn_node_kind_t kind;
   svn_error_t *err;
-  svn_revnum_t external_peg_rev = SVN_INVALID_REVNUM;
-  svn_revnum_t external_rev = SVN_INVALID_REVNUM;
   apr_pool_t *subpool = svn_pool_create(pool);
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  if (peg_revision->kind == svn_opt_revision_number)
-    external_peg_rev = peg_revision->value.number;
-
-  if (revision->kind == svn_opt_revision_number)
-    external_rev = revision->value.number;
-
   /* If path is a directory, try to update/switch to the correct URL
      and revision. */
   SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
@@ -238,8 +230,8 @@
                                                 svn_uri_skip_ancestor(
                                                             repos_root_url,
                                                             url, subpool),
-                                                external_peg_rev,
-                                                external_rev,
+                                                SVN_INVALID_REVNUM,
+                                                SVN_INVALID_REVNUM,
                                                 subpool));
 
               svn_pool_destroy(subpool);
@@ -296,8 +288,8 @@
                                       repos_root_url, repos_uuid,
                                       svn_uri_skip_ancestor(repos_root_url,
                                                             url, pool),
-                                      external_peg_rev,
-                                      external_rev,
+                                      SVN_INVALID_REVNUM,
+                                      SVN_INVALID_REVNUM,
                                       pool));
   }
 
@@ -512,10 +504,8 @@
   return svn_error_trace(err);
 }
 
-/* Return the scheme of @a uri in @a scheme allocated from @a pool.
-   If @a uri does not appear to be a valid URI, then @a scheme will
-   not be updated.  */
 static svn_error_t *
+<<<<<<< .working
 uri_scheme(const char **scheme, const char *uri, apr_pool_t *pool)
 {
   apr_size_t i;
@@ -538,10 +528,10 @@
 
 /* If the URL for @a item is relative, then using the repository root
    URL @a repos_root_url and the parent directory URL @parent_dir_url,
-   resolve it into an absolute URL and save it in @a *resolved_url.
+   resolve it into an absolute URL and save it in @a item.
 
    Regardless if the URL is absolute or not, if there are no errors,
-   the URL returned in @a *resolved_url will be canonicalized.
+   the URL in @a item will be canonicalized.
 
    The following relative URL formats are supported:
 
@@ -687,16 +677,16 @@
       return SVN_NO_ERROR;
     }
 
-  /* The remaining URLs are relative to either the scheme or server root
-     and can only refer to locations inside that scope, so backpaths are
-     not allowed. */
+  /* The remaining URLs are relative to the either the scheme or
+     server root and can only refer to locations inside that scope, so
+     backpaths are not allowed. */
   if (svn_path_is_backpath_present(url + 2))
     return svn_error_createf(SVN_ERR_BAD_URL, 0,
                              _("The external relative URL '%s' cannot have "
                                "backpaths, i.e. '..'"),
                              item->url);
 
-  /* Relative to the scheme: Build a new URL from the parts we know. */
+  /* Relative to the scheme: Build a new URL from the parts we know.  */
   if (0 == strncmp("//", url, 2))
     {
       const char *scheme;
@@ -709,7 +699,7 @@
     }
 
   /* Relative to the server root: Just replace the path portion of the
-     parent's URL. */
+     parent's URL.  */
   if (url[0] == '/')
     {
       parent_dir_uri.path = (char *)url;
@@ -726,6 +716,8 @@
 }
 
 static svn_error_t *
+=======
+>>>>>>> .merge-right.r1174693
 handle_external_item_removal(const struct external_change_baton_t *eb,
                              const char *defining_abspath,
                              const char *local_abspath,
@@ -832,10 +824,17 @@
      iterpool, since the hash table values outlive the iterpool and
      any pointers they have should also outlive the iterpool.  */
 
-  SVN_ERR(resolve_relative_external_url(&new_url,
-                                        new_item, eb->repos_root_url,
-                                        parent_dir_url,
-                                        scratch_pool, scratch_pool));
+<<<<<<< .working
+   SVN_ERR(resolve_relative_external_url(&new_url,
+                                         new_item, eb->repos_root_url,
+                                         parent_dir_url,
+                                         scratch_pool, scratch_pool));
+=======
+  SVN_ERR(svn_wc__resolve_relative_external_url(&new_url,
+                                                new_item, eb->repos_root_url,
+                                                parent_dir_url,
+                                                scratch_pool, scratch_pool));
+>>>>>>> .merge-right.r1174693
 
   /* If the external is being checked out, exported or updated,
      determine if the external is a file or directory. */
@@ -879,21 +878,17 @@
      the global case is hard, and it should be pretty obvious to a
      user when it happens.  Worst case: your disk fills up :-). */
 
-  /* First notify that we're about to handle an external. */
-  if (eb->ctx->notify_func2)
-    {
-      (*eb->ctx->notify_func2)(
-         eb->ctx->notify_baton2,
-         svn_wc_create_notify(local_abspath,
-                              svn_wc_notify_update_external,
-                              scratch_pool),
-         scratch_pool);
-    }
-
   if (! old_defining_abspath)
     {
       /* This branch is only used during a checkout or an export. */
 
+      /* First notify that we're about to handle an external. */
+      if (eb->ctx->notify_func2)
+        (*eb->ctx->notify_func2)(
+           eb->ctx->notify_baton2,
+           svn_wc_create_notify(local_abspath, svn_wc_notify_update_external,
+                                scratch_pool), scratch_pool);
+
       switch (ra_cache.kind)
         {
         case svn_node_dir:
@@ -910,11 +905,6 @@
                    scratch_pool));
           break;
         case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
           SVN_ERR(switch_file_external(local_abspath,
                                        new_url,
                                        &new_item->peg_revision,
@@ -936,6 +926,18 @@
     {
       /* This branch handles a definition change or simple update. */
 
+      /* First notify that we're about to handle an external. */
+      if (eb->ctx->notify_func2)
+        {
+          svn_wc_notify_t *nt;
+
+          nt = svn_wc_create_notify(local_abspath,
+                                    svn_wc_notify_update_external,
+                                    scratch_pool);
+
+          eb->ctx->notify_func2(eb->ctx->notify_baton2, nt, scratch_pool);
+        }
+
       /* Either the URL changed, or the exact same item is present in
          both hashes, and caller wants to update such unchanged items.
          In the latter case, the call below will try to make sure that
@@ -945,18 +947,13 @@
         {
         case svn_node_dir:
           SVN_ERR(switch_dir_external(local_abspath, new_url,
+                                      &(new_item->revision),
                                       &(new_item->peg_revision),
-                                      &(new_item->revision),
                                       parent_dir_abspath,
                                       eb->timestamp_sleep, eb->ctx,
                                       scratch_pool));
           break;
         case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
           SVN_ERR(switch_file_external(local_abspath,
                                        new_url,
                                        &new_item->peg_revision,
@@ -1054,9 +1051,6 @@
 
       svn_pool_clear(iterpool);
 
-      if (eb->ctx->cancel_func)
-        SVN_ERR(eb->ctx->cancel_func(eb->ctx->cancel_baton));
-
       target_abspath = svn_dirent_join(local_abspath, new_item->target_dir,
                                        iterpool);
 
@@ -1232,9 +1226,10 @@
           item_abspath = svn_dirent_join(local_abspath, item->target_dir,
                                          sub_iterpool);
 
-          SVN_ERR(resolve_relative_external_url(&new_url, item,
-                                                repos_root_url, dir_url,
-                                                sub_iterpool, sub_iterpool));
+          SVN_ERR(svn_wc__resolve_relative_external_url(&new_url, item,
+                                                        repos_root_url,
+                                                        dir_url, sub_iterpool,
+                                                        sub_iterpool));
 
           /* The target dir might have multiple components.  Guarantee
              the path leading down to the last component. */
--- subversion/libsvn_client/externals.c        (revision 1177098)
+++ subversion/libsvn_client/externals.c        (working copy)
@@ -504,10 +504,8 @@
   return svn_error_trace(err);
 }
 
-/* Return the scheme of @a uri in @a scheme allocated from @a pool.
-   If @a uri does not appear to be a valid URI, then @a scheme will
-   not be updated.  */
 static svn_error_t *
+<<<<<<< .working
 uri_scheme(const char **scheme, const char *uri, apr_pool_t *pool)
 {
   apr_size_t i;
@@ -718,6 +716,8 @@
 }
 
 static svn_error_t *
+=======
+>>>>>>> .merge-right.r1174693
 handle_external_item_removal(const struct external_change_baton_t *eb,
                              const char *defining_abspath,
                              const char *local_abspath,
@@ -824,10 +824,17 @@
      iterpool, since the hash table values outlive the iterpool and
      any pointers they have should also outlive the iterpool.  */
 
+<<<<<<< .working
    SVN_ERR(resolve_relative_external_url(&new_url,
                                          new_item, eb->repos_root_url,
                                          parent_dir_url,
                                          scratch_pool, scratch_pool));
+=======
+  SVN_ERR(svn_wc__resolve_relative_external_url(&new_url,
+                                                new_item, eb->repos_root_url,
+                                                parent_dir_url,
+                                                scratch_pool, scratch_pool));
+>>>>>>> .merge-right.r1174693
 
   /* If the external is being checked out, exported or updated,
      determine if the external is a file or directory. */
@@ -1219,9 +1226,10 @@
           item_abspath = svn_dirent_join(local_abspath, item->target_dir,
                                          sub_iterpool);
 
-          SVN_ERR(resolve_relative_external_url(&new_url, item,
-                                                repos_root_url, dir_url,
-                                                sub_iterpool, sub_iterpool));
+          SVN_ERR(svn_wc__resolve_relative_external_url(&new_url, item,
+                                                        repos_root_url,
+                                                        dir_url, sub_iterpool,
+                                                        sub_iterpool));
 
           /* The target dir might have multiple components.  Guarantee
              the path leading down to the last component. */

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to