[PATCH 1 of 1] merge: confirm continuation when conflict of divergent operations is detected
FUJIWARA Katsunori
foozy at lares.dti.ne.jp
Mon Nov 11 23:38:56 CST 2013
# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1384234132 -32400
# Tue Nov 12 14:28:52 2013 +0900
# Node ID a1fd26f1794b1158021ba09cd3bab7aff6296418
# Parent c38c3fdc8b9317ba09e03ab09364c3800da7c50c
merge: confirm continuation when conflict of divergent operations is detected
Before this patch, "hg merge" just shows warning message, when
conflict of divergent operations (multiple renaming, or renaming and
deleting) on same file is detected.
This (silently) successful divergence in merging may be overlooked and
confuse users long after merging.
This patch confirms about allowance for detected conflict of divergent
operations on same file, and abort merging if users don't allow it.
This patch shouldn't break existing tool chains, because default value
of confirmation for non-interactive mode is 'yes' and it doesn't abort
merging.
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -166,13 +166,11 @@
opmap = {
"a": addop,
"d": renameop,
- "dr": nop,
"e": nop,
"f": addop, # untracked file should be kept in working directory
"g": addop,
"m": mergeop,
"r": removeop,
- "rd": nop,
}
for f, m, args, msg in actions:
op = opmap.get(m)
@@ -208,7 +206,7 @@
"""
overwrite = force and not branchmerge
- actions, copy, movewithdir = [], {}, {}
+ criticals, copy, movewithdir = [], {}, {}
followcopies = False
if overwrite:
@@ -228,9 +226,9 @@
ret = copies.mergecopies(repo, wctx, p2, pa)
copy, movewithdir, diverge, renamedelete = ret
for of, fl in diverge.iteritems():
- actions.append((of, "dr", (fl,), "divergent renames"))
+ criticals.append((of, "dr", (fl,)))
for of, fl in renamedelete.iteritems():
- actions.append((of, "rd", (fl,), "rename and delete"))
+ criticals.append((of, "rd", (fl,)))
repo.ui.note(_("resolving manifests\n"))
repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
@@ -248,7 +246,7 @@
m1['.hgsubstate'] += "+"
break
- aborts, prompts = [], []
+ actions, aborts, prompts = [], [], []
# Compare manifests
fdiff = dicthelpers.diff(m1, m2)
flagsdiff = m1.flagsdiff(m2)
@@ -361,6 +359,27 @@
else:
_checkcollision(repo, m1, actions, prompts)
+ for f, m, args in sorted(criticals):
+ if m == "dr": # divergent renames
+ fl, = args
+ query = _("possible conflict - %s was renamed multiple times to:\n"
+ " %s\n"
+ "allow this conflict and continue merging? [Yn]"
+ "$$ &Yes $$ &No") % (f, "\n ".join(fl))
+ if repo.ui.promptchoice(query):
+ raise util.Abort(_("resolve divergent operations "
+ "before merging: %s") % f)
+ elif m == "rd": # rename and delete
+ fl, = args
+ query = _("possible conflict - %s was deleted and renamed to:\n"
+ " %s\n"
+ "allow this conflict and continue merging? [Yn]"
+ "$$ &Yes $$ &No") % (f, "\n ".join(fl))
+ if repo.ui.promptchoice(query):
+ raise util.Abort(_("resolve divergent operations"
+ " before merging: %s") % f)
+ else: assert False, m
+
for f, m in sorted(prompts):
if m == "cd":
if acceptremote:
@@ -534,18 +553,6 @@
repo.ui.note(_("getting %s to %s\n") % (f2, fd))
repo.wwrite(fd, mctx.filectx(f2).data(), flags)
updated += 1
- elif m == "dr": # divergent renames
- fl, = args
- repo.ui.warn(_("note: possible conflict - %s was renamed "
- "multiple times to:\n") % f)
- for nf in fl:
- repo.ui.warn(" %s\n" % nf)
- elif m == "rd": # rename and delete
- fl, = args
- repo.ui.warn(_("note: possible conflict - %s was deleted "
- "and renamed to:\n") % f)
- for nf in fl:
- repo.ui.warn(" %s\n" % nf)
elif m == "e": # exec
flags, = args
audit(f)
diff --git a/tests/test-bundle-r.t b/tests/test-bundle-r.t
--- a/tests/test-bundle-r.t
+++ b/tests/test-bundle-r.t
@@ -294,9 +294,10 @@
$ cd ../test
$ hg merge 7
- note: possible conflict - afile was renamed multiple times to:
+ possible conflict - afile was renamed multiple times to:
anotherfile
adifferentfile
+ allow this conflict and continue merging? [Yn] y
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m merge
diff --git a/tests/test-issue1175.t b/tests/test-issue1175.t
--- a/tests/test-issue1175.t
+++ b/tests/test-issue1175.t
@@ -13,9 +13,10 @@
$ hg mv a a2
$ hg up
- note: possible conflict - a was renamed multiple times to:
+ possible conflict - a was renamed multiple times to:
a2
a1
+ allow this conflict and continue merging? [Yn] y
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg ci -m2
diff --git a/tests/test-rename-merge1.t b/tests/test-rename-merge1.t
--- a/tests/test-rename-merge1.t
+++ b/tests/test-rename-merge1.t
@@ -21,6 +21,14 @@
$ hg ci -m "modify"
created new head
+ $ hg merge --config ui.interactive=true <<EOF
+ > n
+ > EOF
+ possible conflict - a2 was renamed multiple times to:
+ c2
+ b2
+ allow this conflict and continue merging? [Yn] abort: resolve divergent operations before merging: a2
+ [255]
$ hg merge -y --debug
searching for copies back to rev 1
unmatched files in local:
@@ -36,22 +44,21 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
+ possible conflict - a2 was renamed multiple times to:
+ c2
+ b2
+ allow this conflict and continue merging? [Yn] y
a: remote moved to b -> m
preserving a for resolve of b
- a2: divergent renames -> dr
b2: remote created -> g
removing a
getting b2
- updating: b2 1/3 files (33.33%)
- updating: a 2/3 files (66.67%)
+ updating: b2 1/2 files (50.00%)
+ updating: a 2/2 files (100.00%)
picked tool 'internal:merge' for b (binary False symlink False)
merging a and b to b
my b at 044f8520aeeb+ other b at 85c198ef2f6c ancestor a at af1939970a1c
premerge successful
- updating: a2 3/3 files (100.00%)
- note: possible conflict - a2 was renamed multiple times to:
- c2
- b2
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@@ -171,6 +178,13 @@
$ hg rm file
$ hg commit -m "deleted file"
created new head
+ $ hg merge --config ui.interactive=true <<EOF
+ > n
+ > EOF
+ possible conflict - file was deleted and renamed to:
+ newfile
+ allow this conflict and continue merging? [Yn] abort: resolve divergent operations before merging: file
+ [255]
$ hg merge --debug
searching for copies back to rev 1
unmatched files in other:
@@ -181,13 +195,12 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
- file: rename and delete -> rd
+ possible conflict - file was deleted and renamed to:
+ newfile
+ allow this conflict and continue merging? [Yn] y
newfile: remote created -> g
getting newfile
- updating: newfile 1/2 files (50.00%)
- updating: file 2/2 files (100.00%)
- note: possible conflict - file was deleted and renamed to:
- newfile
+ updating: newfile 1/1 files (100.00%)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg status
diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t
--- a/tests/test-rename-merge2.t
+++ b/tests/test-rename-merge2.t
@@ -376,17 +376,16 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
- a: divergent renames -> dr
+ possible conflict - a was renamed multiple times to:
+ b
+ c
+ allow this conflict and continue merging? [Yn] y
c: remote created -> g
rev: versions differ -> m
preserving rev for resolve of rev
getting c
- updating: c 1/3 files (33.33%)
- updating: a 2/3 files (66.67%)
- note: possible conflict - a was renamed multiple times to:
- b
- c
- updating: rev 3/3 files (100.00%)
+ updating: c 1/2 files (50.00%)
+ updating: rev 2/2 files (100.00%)
picked tool 'python ../merge' for rev (binary False symlink False)
merging rev
my rev at 02963e448370+ other rev at fe905ef2c33e ancestor rev at 924404dff337
More information about the Mercurial-devel
mailing list