# HG changeset patch # User Gábor Stefanik # Date 2016-10-11 02:39:47 # Node ID 1894c830ee7433740c4d802f10c5f3f884b41103 # Parent b94b92f0c683dcb897f0302520e847c07e58000d copies: make _checkcopies handle copy sequences spanning the TCA (issue4028) When working in a rotated DAG (for a graftlike merge), there can be files that are renamed both between the base and the topological CA, and between the TCA and the endpoint farther from the base. Such renames span the TCA (and thus need both passes of _checkcopies to be fully detected), but may not necessarily be divergent. Make _checkcopies return "incomplete copies" and "incomplete divergences" in this case, and let mergecopies recombine them once data from both passes of _checkcopies is available. With this patch, all known cases involving renames and grafts pass. (Developed together with Pierre-Yves David) diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -611,6 +611,7 @@ def _checkcopies(ctx, f, m1, m2, base, t """ mb = base.manifest() + mta = tca.manifest() # Might be true if this call is about finding backward renames, # This happens in the case of grafts because the DAG is then rotated. # If the file exists in both the base and the source, we are not looking @@ -665,8 +666,17 @@ def _checkcopies(ctx, f, m1, m2, base, t break return - if of in mb: - data['diverge'].setdefault(of, []).append(f) + if of in mta: + if backwards or remotebase: + data['incomplete'][of] = f + else: + for sf in seen: + if sf in mb: + if tca == base: + data['diverge'].setdefault(sf, []).append(f) + else: + data['incompletediverge'][sf] = [of, f] + return def duplicatecopies(repo, rev, fromrev, skiprev=None): '''reproduce copies from fromrev to rev in the dirstate diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -957,15 +957,6 @@ two renames actually converge to the sam grafting 2:f58c7e2b28fa "C0" merging f1a and f1b to f1a merging f5a - warning: conflicts while merging f5a! (edit, then use 'hg resolve --mark') - abort: unresolved conflicts, can't continue - (use 'hg resolve' and 'hg graft --continue') - [255] - $ hg resolve f5a -t ':other' # XXX work around failure - (no more unresolved files) - continue: hg graft --continue - $ hg graft --continue # XXX work around failure - grafting 2:f58c7e2b28fa "C0" warning: can't find ancestor for 'f5a' copied from 'f5b'! $ hg status --change . M f1a @@ -975,7 +966,7 @@ two renames actually converge to the sam $ hg cat f1a c1c $ hg cat f1b - f1b: no such file in rev 43e4b415492d + f1b: no such file in rev c9763722f9bd [1] Test the cases A.0 (f4x) and A.6 (f3x) @@ -997,23 +988,23 @@ Set up the repository for some further t $ hg mv f5a f5b $ hg ci -qAm "E0" $ hg log -G - @ changeset: 6:ebba59d1fb02 + @ changeset: 6:6bd1736cab86 | tag: tip | parent: 0:11f7a1b56675 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: E0 | - | o changeset: 5:4f4ba7a6e606 + | o changeset: 5:560daee679da | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: D1 | | - | o changeset: 4:43e4b415492d + | o changeset: 4:c9763722f9bd |/ parent: 0:11f7a1b56675 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: C0 + | summary: C1 | | o changeset: 3:b69f5839d2d9 | | user: test @@ -1041,34 +1032,24 @@ and A.3 with a local content change to b $ HGEDITOR="echo C2 >" hg graft -r 'desc("C0")' --edit grafting 2:f58c7e2b28fa "C0" - other [graft] changed f1b which local [local] deleted - use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u + merging f1e and f1b to f1e merging f2a and f2c to f2c merging f5b and f5a to f5a - abort: unresolved conflicts, can't continue - (use 'hg resolve' and 'hg graft --continue') - [255] - $ hg resolve f1b -t ':other' # XXX work around failure - (no more unresolved files) - continue: hg graft --continue - $ hg graft --continue # XXX work around failure - grafting 2:f58c7e2b28fa "C0" - grafting 4:43e4b415492d "C0" - merging f1e and f1a to f1e - merging f2c - warning: can't find ancestor for 'f2c' copied from 'f2a'! Test the cases A.1 (f4x) and A.7 (f3x). $ HGEDITOR="echo D2 >" hg graft -r 'desc("D0")' --edit grafting 3:b69f5839d2d9 "D0" + note: possible conflict - f3b was renamed multiple times to: + f3e + f3d merging f4e and f4a to f4e warning: can't find ancestor for 'f3d' copied from 'f3b'! Check the results of the grafts tested $ hg log -CGv --patch --git - @ changeset: 9:100f4d78e056 + @ changeset: 8:93ee502e8b0a | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 @@ -1090,12 +1071,13 @@ Check the results of the grafts tested | -c4a | +c4d | - o changeset: 8:84915a7da133 + o changeset: 7:539cf145f496 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 - | files: f1e f5a.orig + | files: f1e f2a f2c f5a f5b + | copies: f2c (f2a) f5a (f5b) | description: - | C0 + | C2 | | | diff --git a/f1e b/f1e @@ -1104,32 +1086,6 @@ Check the results of the grafts tested | @@ -1,1 +1,1 @@ | -c1a | +c1c - | diff --git a/f5a.orig b/f5a.orig - | deleted file mode 100644 - | --- a/f5a.orig - | +++ /dev/null - | @@ -1,5 +0,0 @@ - | -<<<<<<< local: 11f7a1b56675 - test: A0 - | -c5a - | -======= - | -c5c - | ->>>>>>> graft: f58c7e2b28fa - test: C0 - | - o changeset: 7:dc778749ee9a - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | files: f1b f2a f2c f5a f5b - | copies: f2c (f2a) f5a (f5b) - | description: - | C0 - | - | - | diff --git a/f1b b/f1b - | new file mode 100644 - | --- /dev/null - | +++ b/f1b - | @@ -0,0 +1,1 @@ - | +c1c | diff --git a/f2a b/f2c | rename from f2a | rename to f2c @@ -1142,11 +1098,11 @@ Check the results of the grafts tested | -c5a | +c5c | - o changeset: 6:ebba59d1fb02 + o changeset: 6:6bd1736cab86 | parent: 0:11f7a1b56675 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 - | files: f1a f1e f2a f3a f3e f4a f4e f5a f5a.orig f5b + | files: f1a f1e f2a f3a f3e f4a f4e f5a f5b | copies: f1e (f1a) f3e (f3a) f4e (f4a) f5b (f5a) | description: | E0 @@ -1167,21 +1123,11 @@ Check the results of the grafts tested | diff --git a/f4a b/f4e | rename from f4a | rename to f4e - | diff --git a/f5a.orig b/f5a.orig - | new file mode 100644 - | --- /dev/null - | +++ b/f5a.orig - | @@ -0,0 +1,5 @@ - | +<<<<<<< local: 11f7a1b56675 - test: A0 - | +c5a - | +======= - | +c5c - | +>>>>>>> graft: f58c7e2b28fa - test: C0 | diff --git a/f5a b/f5b | rename from f5a | rename to f5b | - | o changeset: 5:4f4ba7a6e606 + | o changeset: 5:560daee679da | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | files: f3d f4a @@ -1202,14 +1148,14 @@ Check the results of the grafts tested | | -c4a | | +c4d | | - | o changeset: 4:43e4b415492d + | o changeset: 4:c9763722f9bd |/ parent: 0:11f7a1b56675 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | files: f1a f2a f2c f5a | copies: f2c (f2a) | description: - | C0 + | C1 | | | diff --git a/f1a b/f1a