# HG changeset patch # User Martin von Zweigbergk # Date 2021-03-04 16:20:19 # Node ID 2803f94b74314f6c72edfe70868da745651477b8 # Parent 324ded1aa2ab683cfe794419b6f5d64b67443b03 copies: filter out copies grafted from another branch 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. 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). Differential Revision: https://phab.mercurial-scm.org/D10120 diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -763,6 +763,11 @@ def pathcopies(x, y, match=None): 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, 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 @@ should not report the copy. 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/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -223,10 +223,6 @@ Graft out of order, skipping a merge and 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 @@ Graft out of order, skipping a merge and $ 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