diff -r bcf29565d89f -r 95773237df7f mercurial/merge.py --- a/mercurial/merge.py Fri Feb 08 15:23:23 2013 +0000 +++ b/mercurial/merge.py Sat Feb 09 15:36:00 2013 +0000 @@ -224,7 +224,7 @@ m1['.hgsubstate'] += "+" break - prompts = [] + aborts, prompts = [], [] # Compare manifests for f, n in m1.iteritems(): if partial and not partial(f): @@ -285,15 +285,40 @@ 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 @@ _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,