[PATCH 4 of 4 V3] manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal
sid0 at fb.com
Sat Feb 9 09:48:56 CST 2013
# HG changeset patch
# User Siddharth Agarwal <sid0 at fb.com>
# Date 1360424160 0
# Node ID a8047ff53c9e754629baf8347008ef456b713447
# Parent 0e6b206adfdd78e87dfb4f81c37a6b79f521ea18
manifestmerge: handle abort on local unknown, remote created files
This replaces the _checkunknown call in calculateupdates with a more
performant version. On a repository with over 150,000 files, this speeds up an
update by 0.6-0.8 seconds, which is up to 25%.
This does not introduce any UI changes. There is existing test coverage for
every case, mostly in test-merge*.t.
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -224,7 +224,7 @@ def manifestmerge(repo, p1, p2, pa, bran
m1['.hgsubstate'] += "+"
break
- prompts = []
+ aborts, prompts = [], []
# Compare manifests
for f, n in m1.iteritems():
if partial and not partial(f):
@@ -285,15 +285,40 @@ def manifestmerge(repo, p1, p2, pa, bran
actions.append((f2, "m", (f, f, True),
"remote moved to " + f))
elif f not in ma:
- if (not overwrite
- and _checkunknownfile(repo, p1, p2, f)):
- actions.append((f, "m", (f, f, False),
- "remote differs from untracked local"))
+ # local unknown, remote created: the logic is described by the
+ # following table:
+ #
+ # force branchmerge different | action
+ # n * n | get
+ # n * y | abort
+ # y n * | get
+ # y y n | get
+ # y y y | merge
+ #
+ # Checking whether the files are different is expensive, so we
+ # don't do that when we can avoid it.
+ if force and not branchmerge:
+ actions.append((f, "g", (m2.flags(f),), "remote created"))
else:
- actions.append((f, "g", (m2.flags(f),), "remote created"))
+ different = _checkunknownfile(repo, p1, p2, f)
+ if force and branchmerge and different:
+ actions.append((f, "m", (f, f, False),
+ "remote differs from untracked local"))
+ elif not force and different:
+ aborts.append((f, "ud"))
+ else:
+ actions.append((f, "g", (m2.flags(f),), "remote created"))
elif n != ma[f]:
prompts.append((f, "dc")) # prompt deleted/changed
+ for f, m in sorted(aborts):
+ if m == "ud":
+ repo.ui.warn(_("%s: untracked file differs\n") % f)
+ else: assert False, m
+ if aborts:
+ raise util.Abort(_("untracked files in working directory differ "
+ "from files in requested revision"))
+
for f, m in sorted(prompts):
if m == "cd":
if repo.ui.promptchoice(
@@ -447,8 +472,6 @@ def calculateupdates(repo, tctx, mctx, a
_checkcollision(mctx, None)
else:
_checkcollision(mctx, (tctx, ancestor))
- if not force:
- _checkunknown(repo, tctx, mctx)
if tctx.rev() is None:
actions += _forgetremoved(tctx, mctx, branchmerge)
actions += manifestmerge(repo, tctx, mctx,
More information about the Mercurial-devel
mailing list