[PATCH STABLE] commit: remove reverse search for copy source when not in parent (issue4476)

Ryan McElroy rm at fb.com
Tue Jan 20 23:18:32 UTC 2015


# HG changeset patch
# User Ryan McElroy <rmcelroy at fb.com>
# Date 1421795144 28800
#      Tue Jan 20 15:05:44 2015 -0800
# Branch stable
# Node ID a1980031bc26fa95f4fd953f85282df8cbf19ed1
# Parent  ca6cfc2f81978211751ed15956f64926ac447e90
commit: remove reverse search for copy source when not in parent (issue4476)

Previously, we had weird, nonsensical behavior when committing a file move
with a missing source. This removes that weird logic and tests that the bug
this strange behavior caused is fixed. Also adds a longish comment to prevent
some poor soul from accidentally re-implementing the bug in the future.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1206,14 +1206,14 @@ class localrepository(object):
                         crev = manifest2[cfname]
                         newfparent = fparent1
 
-            # find source in nearest ancestor if we've lost track
-            if not crev:
-                self.ui.debug(" %s: searching for copy revision for %s\n" %
-                              (fname, cfname))
-                for ancestor in self[None].ancestors():
-                    if cfname in ancestor:
-                        crev = ancestor[cfname].filenode()
-                        break
+            # Here, we used to search backwards through history to try to find
+            # where the file copy came from if the source of a copy was not in
+            # the parent diretory. However, this doesn't actually make sense to
+            # do (what does a copy from something not in your working copy even
+            # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
+            # the user that copy information was dropped, so if they didn't
+            # expect this outcome it can be fixed, but this is the correct
+            # behavior in this circumstance.
 
             if crev:
                 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -606,6 +606,7 @@ Transplants of grafts can find a destina
   
 ... grafts of grafts unfortunately can't
   $ hg graft -q 13
+  warning: can't find ancestor for 'b' copied from 'a'!
   $ hg log -r 'destination(13)'
 All copies of a cset
   $ hg log -r 'origin(13) or destination(origin(13))'
@@ -636,7 +637,7 @@ All copies of a cset
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     2
   
-  changeset:   22:1313d0a825e2
+  changeset:   22:e95864da75a0
   branch:      dev
   tag:         tip
   user:        foo
@@ -648,24 +649,28 @@ graft works on complex revset
 
   $ hg graft 'origin(13) or destination(origin(13))'
   skipping ancestor revision 21:7e61b508e709
-  skipping ancestor revision 22:1313d0a825e2
-  skipping revision 2:5c095ad7e90f (already grafted to 22:1313d0a825e2)
+  skipping ancestor revision 22:e95864da75a0
+  skipping revision 2:5c095ad7e90f (already grafted to 22:e95864da75a0)
   grafting 7:ef0ef43d49e7 "2"
+  warning: can't find ancestor for 'b' copied from 'a'!
   grafting 13:9db0f28fd374 "2"
+  warning: can't find ancestor for 'b' copied from 'a'!
   grafting 19:9627f653b421 "2"
   merging b
+  warning: can't find ancestor for 'b' copied from 'a'!
 
 graft with --force (still doesn't graft merges)
 
   $ hg graft 19 0 6
   skipping ungraftable merge revision 6
   skipping ancestor revision 0:68795b066622
-  skipping already grafted revision 19:9627f653b421 (22:1313d0a825e2 also has origin 2:5c095ad7e90f)
+  skipping already grafted revision 19:9627f653b421 (22:e95864da75a0 also has origin 2:5c095ad7e90f)
   [255]
   $ hg graft 19 0 6 --force
   skipping ungraftable merge revision 6
   grafting 19:9627f653b421 "2"
   merging b
+  warning: can't find ancestor for 'b' copied from 'a'!
   grafting 0:68795b066622 "0"
 
 graft --force after backout
@@ -674,12 +679,12 @@ graft --force after backout
   $ hg ci -m 28
   $ hg backout 28
   reverting a
-  changeset 29:484c03b8dfa4 backs out changeset 28:6c56f0f7f033
+  changeset 29:8389853bba65 backs out changeset 28:cd42a33e1848
   $ hg graft 28
-  skipping ancestor revision 28:6c56f0f7f033
+  skipping ancestor revision 28:cd42a33e1848
   [255]
   $ hg graft 28 --force
-  grafting 28:6c56f0f7f033 "28"
+  grafting 28:cd42a33e1848 "28"
   merging a
   $ cat a
   abc
@@ -689,7 +694,7 @@ graft --continue after --force
   $ echo def > a
   $ hg ci -m 31
   $ hg graft 28 --force --tool internal:fail
-  grafting 28:6c56f0f7f033 "28"
+  grafting 28:cd42a33e1848 "28"
   abort: unresolved conflicts, can't continue
   (use hg resolve and hg graft --continue)
   [255]
@@ -702,7 +707,7 @@ graft --continue after --force
   $ hg resolve -m a
   (no more unresolved files)
   $ hg graft -c
-  grafting 28:6c56f0f7f033 "28"
+  grafting 28:cd42a33e1848 "28"
   $ cat a
   abc
 
@@ -723,5 +728,5 @@ Empty graft
   $ hg tag -f something
   $ hg graft -qr 27
   $ hg graft -f 27
-  grafting 27:3aaa8b6725f0 "28"
-  note: graft of 27:3aaa8b6725f0 created no changes to commit
+  grafting 27:3d35c4c79e5a "28"
+  note: graft of 27:3d35c4c79e5a created no changes to commit
diff --git a/tests/test-issue1175.t b/tests/test-issue1175.t
--- a/tests/test-issue1175.t
+++ b/tests/test-issue1175.t
@@ -30,11 +30,10 @@ http://mercurial.selenic.com/bts/issue11
   $ hg ci --debug --traceback -Am5 b
   committing files:
   b
-   b: searching for copy revision for a
-   b: copy a:b80de5d138758541c5f05265ad144ab9fa86d1db
+  warning: can't find ancestor for 'b' copied from 'a'!
   committing manifest
   committing changelog
-  committed changeset 5:732aafbecb501a198b3cc9323ad3899ff04ccf95
+  committed changeset 5:83a687e8a97c80992ba385bbfd766be181bfb1d1
 
   $ hg verify
   checking changesets
@@ -48,10 +47,50 @@ http://mercurial.selenic.com/bts/issue11
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 732aafbecb501a198b3cc9323ad3899ff04ccf95
+  # Node ID 83a687e8a97c80992ba385bbfd766be181bfb1d1
   # Parent  1d1625283f71954f21d14c3d44d0ad3c019c597f
   5
   
   diff --git a/b b/b
   new file mode 100644
 
+http://bz.selenic.com/show_bug.cgi?id=4476
+
+  $ hg init foo
+  $ cd foo
+  $ touch a && hg ci -Aqm a
+  $ hg mv a b
+  $ echo b1 >> b
+  $ hg ci -Aqm b1
+  $ hg up 0
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg mv a b
+  $ echo b2 >> b
+  $ hg ci -Aqm b2
+  $ hg graft 1
+  grafting 1:5974126fad84 "b1"
+  merging b
+  warning: conflicts during merge.
+  merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
+  abort: unresolved conflicts, can't continue
+  (use hg resolve and hg graft --continue)
+  [255]
+  $ echo a > b
+  $ echo b3 >> b
+  $ hg resolve --mark b
+  (no more unresolved files)
+  $ hg graft --continue
+  grafting 1:5974126fad84 "b1"
+  warning: can't find ancestor for 'b' copied from 'a'!
+  $ hg log -f b -T 'changeset:   {rev}:{node|short}\nsummary:     {desc}\n\n'
+  changeset:   3:376d30ccffc0
+  summary:     b1
+  
+  changeset:   2:416baaa2e5e4
+  summary:     b2
+  
+  changeset:   0:3903775176ed
+  summary:     a
+  
+
+


More information about the Mercurial-devel mailing list