Patchwork D8243: copies: stop recording buggy file merge when new file overwrite an old one

login
register
mail settings
Submitter phabricator
Date March 6, 2020, 11:52 p.m.
Message ID <a893f6dc407a8957ddd4ebb84b530c67@localhost.localdomain>
Download mbox | patch
Permalink /patch/45599/
State Not Applicable
Headers show

Comments

phabricator - March 6, 2020, 11:52 p.m.
marmoute added a comment.
marmoute retitled this revision from "copies: stop recoding buggy file merge when new file overwrite an old one" to "copies: stop recording buggy file merge when new file overwrite an old one".
marmoute updated this revision to Diff 20595.


  series update after Martin feedback

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8243?vs=20550&id=20595

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8243/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8243

AFFECTED FILES
  mercurial/localrepo.py
  tests/test-convert-hg-source.t
  tests/test-copies-chain-merge.t

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: martinvonz, mercurial-devel

Patch

diff --git a/tests/test-copies-chain-merge.t b/tests/test-copies-chain-merge.t
--- a/tests/test-copies-chain-merge.t
+++ b/tests/test-copies-chain-merge.t
@@ -212,7 +212,7 @@ 
   (branch merge, don't forget to commit)
   $ hg ci -m 'mBDm-0 simple merge - one way'
   $ hg up 'desc("d-2")'
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("b-1")'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -314,8 +314,7 @@ 
      rev linkrev nodeid       p1           p2
        0       2 01c2f5eabdc4 000000000000 000000000000
        1      10 b004912a8510 000000000000 000000000000
-       2      15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
-       3      22 c72365ee036f 000000000000 000000000000
+       2      22 c72365ee036f 000000000000 000000000000
   $ hg up 'desc("b-1")'
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("f-2")'
@@ -323,7 +322,7 @@ 
   (branch merge, don't forget to commit)
   $ hg ci -m 'mBFm-0 simple merge - one way'
   $ hg up 'desc("f-2")'
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("b-1")'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -537,17 +536,12 @@ 
 - one with change to an unrelated file
 - one deleting and recreating the change
 
-Note:
-| In this case, one of the merge wrongly record a merge while there is none.
-| This lead to bad copy tracing information to be dug up.
-
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBDm-0")'
   M d
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mDBm-0")'
   M d
   $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mBDm-0")'
   M b
-  M d
   $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDBm-0")'
   M b
   $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBDm-0")'
@@ -557,18 +551,14 @@ 
   M b
   M d
 
-The bugs makes recorded copy is different depending of where we started the merge from since
+
+The result must be the same for both merges
 
   $ hg manifest --debug --rev 'desc("mBDm-0")' | grep '644   d'
-  0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 644   d
+  b004912a8510032a0350a74daa2803dadfb00e12 644   d
   $ hg manifest --debug --rev 'desc("mDBm-0")' | grep '644   d'
   b004912a8510032a0350a74daa2803dadfb00e12 644   d
 
-The 0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 entry is wrong, since the file was
-deleted on one side (then recreate) and untouched on the other side, no "merge"
-has happened. The resulting `d` file is the untouched version from branch `D`,
-not a merge.
-
   $ hg manifest --debug --rev 'desc("d-2")' | grep '644   d'
   b004912a8510032a0350a74daa2803dadfb00e12 644   d
   $ hg manifest --debug --rev 'desc("b-1")' | grep '644   d'
@@ -577,29 +567,16 @@ 
      rev linkrev nodeid       p1           p2
        0       2 01c2f5eabdc4 000000000000 000000000000
        1      10 b004912a8510 000000000000 000000000000
-       2      15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
-       3      22 c72365ee036f 000000000000 000000000000
-       4      23 863d9bc49190 01c2f5eabdc4 c72365ee036f
-       5      25 7bded9d9da1f 01c2f5eabdc4 000000000000
-       6      26 f04cac32d703 b004912a8510 7bded9d9da1f
-       7      27 d7a5eafb9322 7bded9d9da1f b004912a8510
-       8      28 2ed7a51aed47 c72365ee036f 7bded9d9da1f
-
-(This `hg log` output if wrong, since no merge actually happened).
+       2      22 c72365ee036f 000000000000 000000000000
+       3      25 7bded9d9da1f 01c2f5eabdc4 000000000000
+       4      26 f04cac32d703 b004912a8510 7bded9d9da1f
+       5      27 d7a5eafb9322 7bded9d9da1f b004912a8510
+       6      28 2ed7a51aed47 c72365ee036f 7bded9d9da1f
 
   $ hg log -Gfr 'desc("mBDm-0")' d
-  o    15 mBDm-0 simple merge - one way]
-  |\
-  o :  14 d-2 re-add d]
-  :/
-  o  2 i-2: c -move-> d]
+  o  14 d-2 re-add d]
   |
-  o  1 i-1: a -move-> c]
-  |
-  o  0 i-0 initial commit: a b h]
-  
-
-This `hg log` output is correct
+  ~
 
   $ hg log -Gfr 'desc("mDBm-0")' d
   o  14 d-2 re-add d]
@@ -609,7 +586,6 @@ 
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
   M b
   A d
-    a
   R a
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDBm-0")'
   M b
@@ -685,8 +661,7 @@ 
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBFm-0")'
   M b
   A d
-    a (true !)
-    h (false !)
+    h
   R a
   R h
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFBm-0")'
@@ -700,7 +675,6 @@ 
   R h
   $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBFm-0")'
   M b
-  M d
   $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBFm-0")'
   M b
   M d
@@ -718,16 +692,10 @@ 
 The following graphlog is wrong, the "a -> c -> d" chain was overwritten and should not appear.
 
   $ hg log -Gfr 'desc("mBFm-0")' d
-  o    23 mBFm-0 simple merge - one way]
-  |\
-  o :  22 f-2: rename i -> d]
-  | :
-  o :  21 f-1: rename h -> i]
-  :/
-  o  2 i-2: c -move-> d]
+  o  22 f-2: rename i -> d]
   |
-  o  1 i-1: a -move-> c]
-  |
+  o  21 f-1: rename h -> i]
+  :
   o  0 i-0 initial commit: a b h]
   
 
diff --git a/tests/test-convert-hg-source.t b/tests/test-convert-hg-source.t
--- a/tests/test-convert-hg-source.t
+++ b/tests/test-convert-hg-source.t
@@ -62,9 +62,9 @@ 
   6 make bar and baz copies of foo
   5 merge local copy
   4 merge remote copy
-  3 Added tag that for changeset 88586c4e9f02
+  3 Added tag that for changeset 8601262d7472
   2 Removed tag that
-  1 Added tag this for changeset c56a7f387039
+  1 Added tag this for changeset 706614b458c1
   0 mark baz executable
   updating bookmarks
   $ cd new
@@ -76,7 +76,7 @@ 
 #if execbit
   $ hg bookmarks
      premerge1                 3:973ef48a98a4
-     premerge2                 8:91d107c423ba
+     premerge2                 8:c4968fdf2e5d
 #else
 Different hash because no x bit
   $ hg bookmarks
@@ -96,19 +96,19 @@ 
   6 make bar and baz copies of foo
   5 merge local copy
   4 merge remote copy
-  3 Added tag that for changeset 88586c4e9f02
+  3 Added tag that for changeset 8601262d7472
   2 Removed tag that
-  1 Added tag this for changeset c56a7f387039
+  1 Added tag this for changeset 706614b458c1
   0 mark baz executable
   updating bookmarks
   $ hg -R new log -G -T '{rev} {desc}'
   o  8 mark baz executable
   |
-  o  7 Added tag this for changeset c56a7f387039
+  o  7 Added tag this for changeset 706614b458c1
   |
   o  6 Removed tag that
   |
-  o  5 Added tag that for changeset 88586c4e9f02
+  o  5 Added tag that for changeset 8601262d7472
   |
   o    4 merge remote copy
   |\
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2850,6 +2850,39 @@ 
                 fparent1, fparent2 = fparent2, nullid
             elif fparent2 in fparentancestors:
                 fparent2 = nullid
+            elif not fparentancestors:
+                # The two file seems entirely unrelated, one might be a full
+                # replacement of the other.
+                #
+                # At that point, the logic get complicated enough that we reuse
+                # the existing one.
+                #
+                # Ideally, we would store this information in the mergestate a
+                # simply reuse it. It could probably simplify the surounding
+                # code too.
+                p1ctx = fctx._changectx.p1()
+                p2ctx = fctx._changectx.p2()
+                matcher = matchmod.exact([fctx.path()])
+                if self.ui.configlist(b'merge', b'preferancestor') == [b'*']:
+                    cahs = self.changelog.commonancestorsheads(
+                        p1ctx.node(), p2ctx.node()
+                    )
+                    pas = [self[anc] for anc in (sorted(cahs) or [nullid])]
+                else:
+                    pas = [p1ctx.ancestor(p2ctx, warn=False)]
+                actionbyfile, __, __ = mergemod.calculateupdates(
+                    self,
+                    p1ctx,
+                    p2ctx,
+                    pas,
+                    branchmerge=True,
+                    force=True,
+                    acceptremote=False,
+                    followcopies=True,
+                    matcher=matcher,
+                )
+                if actionbyfile[fctx.path()][0] == mergemod.ACTION_GET:
+                    fparent1, fparent2 = fparent2, nullid
 
         # is the file changed?
         text = fctx.data()