diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -987,6 +987,19 @@ proxy. Optional. Always use the proxy, even for localhost and any entries in ``http_proxy.no``. (default: False) +``merge`` +--------- + +This section specifies behavior during merges and updates. + +``checkunknown`` + Controls behavior when an unknown file on disk has the same name as a tracked + file in the changeset being merged or updated to, and has different + contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``, + abort on such files. With ``warn``, warn on such files and back them up as + .orig. With ``ignore``, don't print a warning and back them up as + .orig. (default: ``abort``) + ``merge-patterns`` ------------------ diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -573,6 +573,14 @@ def _checkunknownfiles(repo, wctx, mctx, """ conflicts = set() if not force: + config = repo.ui.config('merge', 'checkunknown', default='abort') + valid = ['abort', 'ignore', 'warn'] + if config not in valid: + validstr = ', '.join(["'" + v + "'" for v in valid]) + raise error.ConfigError(_("merge.checkunknown not valid " + "('%s' is none of %s)") + % (config, validstr)) + for f, (m, args, msg) in actions.iteritems(): if m in ('c', 'dc'): if _checkunknownfile(repo, wctx, mctx, f): @@ -581,16 +589,21 @@ def _checkunknownfiles(repo, wctx, mctx, if _checkunknownfile(repo, wctx, mctx, f, args[0]): conflicts.add(f) - for f in sorted(conflicts): - repo.ui.warn(_("%s: untracked file differs\n") % f) - if conflicts: - raise error.Abort(_("untracked files in working directory differ " - "from files in requested revision")) + if config == 'abort': + for f in sorted(conflicts): + repo.ui.warn(_("%s: untracked file differs\n") % f) + if conflicts: + raise error.Abort(_("untracked files in working directory " + "differ from files in requested revision")) + elif config == 'warn': + for f in sorted(conflicts): + repo.ui.warn(_("%s: replacing untracked file\n") % f) for f, (m, args, msg) in actions.iteritems(): + backup = f in conflicts if m == 'c': flags, = args - actions[f] = ('g', (flags, False), msg) + actions[f] = ('g', (flags, backup), msg) elif m == 'cm': fl2, anc = args different = _checkunknownfile(repo, wctx, mctx, f) @@ -598,7 +611,7 @@ def _checkunknownfiles(repo, wctx, mctx, actions[f] = ('m', (f, f, None, False, anc), "remote differs from untracked local") else: - actions[f] = ('g', (fl2, False), "remote created") + actions[f] = ('g', (fl2, backup), "remote created") def _forgetremoved(wctx, mctx, branchmerge): """ diff --git a/tests/test-merge1.t b/tests/test-merge1.t --- a/tests/test-merge1.t +++ b/tests/test-merge1.t @@ -124,7 +124,43 @@ symlinks shouldn't be followed $ echo This is file b2 > b #endif -merge of b expected +bad config + $ hg merge 1 --config merge.checkunknown=x + abort: merge.checkunknown not valid ('x' is none of 'abort', 'ignore', 'warn') + [255] +this merge should fail + $ hg merge 1 --config merge.checkunknown=abort + b: untracked file differs + abort: untracked files in working directory differ from files in requested revision + [255] + +this merge should warn + $ hg merge 1 --config merge.checkunknown=warn + b: replacing untracked file + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ cat b.orig + This is file b2 + $ hg up --clean 2 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mv b.orig b + +this merge should silently ignore + $ cat b + This is file b2 + $ hg merge 1 --config merge.checkunknown=ignore + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + + $ cat b.orig + This is file b2 + $ hg up --clean 2 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mv b.orig b + +this merge of b should work + $ cat b + This is file b2 $ hg merge -f 1 merging b merging for b