Patchwork D10120: copies: filter out copies grafted from another branch

login
register
mail settings
Submitter phabricator
Date March 6, 2021, 12:41 a.m.
Message ID <differential-rev-PHID-DREV-6dusdgzkyndchwfubtyc-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48435/
State Superseded
Headers show

Comments

phabricator - March 6, 2021, 12:41 a.m.
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Consider this simple history:
  
    @  3 modify y
    |
    o  2 copy x to y, modify x
    |
    | o  1 copy x to y, modify x
    |/
    o  0 add x
  
  If we now rebase commit 3 onto 1, Mercurial will look for copies
  between commit 2 and commit 1. It does that by going backwards from 2
  to 0 and then forwards from 0 to 1. It will find that x was copied to
  y, since that was what happened on the path between them (namely in
  commit 1). That leads Mercurial to do a 3-way merge between y@3 and
  y@1 with x@2 as base. We want to use y@2 as base instead. That's also
  what happened until commit 1d6d1a15 <https://phab.mercurial-scm.org/rHG1d6d1a15a96344a505645991794333f26761ca79>. This patch fixes the regression
  by adding another filtering step when chaining copies via a
  diffbase. The new filtering step removes copies that were the same
  between the two branches (same source and destination, but not
  necessarily the same contents).

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/copies.py
  tests/test-copies.t
  tests/test-graft.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -223,10 +223,6 @@ 
   committing changelog
   updating the branch cache
   grafting 5:97f8bfe72746 "5"
-    all copies found (* = to merge, ! = divergent, % = renamed and deleted):
-     on local side:
-      src: 'c' -> dst: 'b' 
-    checking for directory renames
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
@@ -240,10 +236,6 @@ 
   $ HGEDITOR=cat hg graft 4 3 --log --debug
   scanning for duplicate grafts
   grafting 4:9c233e8e184d "4"
-    all copies found (* = to merge, ! = divergent, % = renamed and deleted):
-     on local side:
-      src: 'c' -> dst: 'b' 
-    checking for directory renames
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
diff --git a/tests/test-copies.t b/tests/test-copies.t
--- a/tests/test-copies.t
+++ b/tests/test-copies.t
@@ -398,11 +398,8 @@ 
   x -> y
   $ hg debugp1copies -r 2
   x -> y
-BROKEN: These two should not report any copies
   $ hg debugpathcopies 1 2
-  x -> y
   $ hg debugpathcopies 2 1
-  x -> y
 
 Copy x to y on one side of merge, create y and rename to z on the other side.
   $ newrepo
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -763,6 +763,11 @@ 
             base = x
         x_copies = _forwardcopies(a, x)
         y_copies = _forwardcopies(a, y, base, match=match)
+        same_keys = set(x_copies) & set(y_copies)
+        for k in same_keys:
+            if x_copies.get(k) == y_copies.get(k):
+                del x_copies[k]
+                del y_copies[k]
         x_backward_renames = _reverse_renames(x_copies, x, match)
         copies = _chain(
             x_backward_renames,