Mercurial > hg
changeset 34552:33c8a6837181
merge: check for path conflicts when updating (issue5628)
When updating to a new revision, check for path conflicts caused by unknown
files in the working directory, and handle these by backing up the file or
directory and replacing it.
Differential Revision: https://phab.mercurial-scm.org/D781
author | Mark Thomas <mbthomas@fb.com> |
---|---|
date | Mon, 02 Oct 2017 14:05:30 -0700 |
parents | 1609a5afc4f5 |
children | 0217d66846f7 |
files | mercurial/merge.py tests/test-merge1.t tests/test-pathconflicts-basic.t tests/test-update-names.t |
diffstat | 4 files changed, 20 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/merge.py Mon Oct 02 14:05:30 2017 -0700 +++ b/mercurial/merge.py Mon Oct 02 14:05:30 2017 -0700 @@ -676,6 +676,7 @@ choose a different action. """ fileconflicts = set() + pathconflicts = set() warnconflicts = set() abortconflicts = set() unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown') @@ -691,11 +692,15 @@ if m in ('c', 'dc'): if _checkunknownfile(repo, wctx, mctx, f): fileconflicts.add(f) + elif f not in wctx: + path = _checkunknowndirs(repo, f) + if path is not None: + pathconflicts.add(path) elif m == 'dg': if _checkunknownfile(repo, wctx, mctx, f, args[0]): fileconflicts.add(f) - allconflicts = fileconflicts + allconflicts = fileconflicts | pathconflicts ignoredconflicts = set([c for c in allconflicts if repo.dirstate._ignore(c)]) unknownconflicts = allconflicts - ignoredconflicts @@ -745,8 +750,9 @@ repo.ui.warn(_("%s: replacing untracked file\n") % f) for f, (m, args, msg) in actions.iteritems(): - backup = f in fileconflicts if m == 'c': + backup = (f in fileconflicts or f in pathconflicts or + any(p in pathconflicts for p in util.finddirs(f))) flags, = args actions[f] = ('g', (flags, backup), msg)
--- a/tests/test-merge1.t Mon Oct 02 14:05:30 2017 -0700 +++ b/tests/test-merge1.t Mon Oct 02 14:05:30 2017 -0700 @@ -30,17 +30,17 @@ $ mkdir b && touch b/nonempty $ hg up - abort: *: '$TESTTMP/t/b' (glob) + b: untracked file differs + abort: untracked files in working directory differ from files in requested revision [255] $ hg ci - abort: last update was interrupted - (use 'hg update' to get a consistent checkout) - [255] + nothing changed + [1] $ hg sum parent: 0:538afb845929 commit #0 branch: default - commit: 1 unknown (interrupted update) + commit: 1 unknown (clean) update: 1 new changesets (update) phases: 2 draft $ rm b/nonempty
--- a/tests/test-pathconflicts-basic.t Mon Oct 02 14:05:30 2017 -0700 +++ b/tests/test-pathconflicts-basic.t Mon Oct 02 14:05:30 2017 -0700 @@ -37,7 +37,8 @@ $ mkdir a $ echo 3 > a/b $ hg up file - abort: *: '$TESTTMP/repo/a' (glob) + a: untracked file differs + abort: untracked files in working directory differ from files in requested revision [255] $ hg up --clean file abort: *: '$TESTTMP/repo/a' (glob) @@ -53,13 +54,9 @@ $ hg up -q 0 $ echo untracked > a $ hg up --config merge.checkunknown=warn dir - abort: *: '$TESTTMP/repo/a/b' (glob) - [255] - -Repo is in a very bad state now - recover manually - - $ rm -f a - $ hg up -q --clean 0 + a: replacing untracked file + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark dir) Basic clean update - local directory conflicts with changed remote file
--- a/tests/test-update-names.t Mon Oct 02 14:05:30 2017 -0700 +++ b/tests/test-update-names.t Mon Oct 02 14:05:30 2017 -0700 @@ -50,7 +50,8 @@ $ hg st ? name/file $ hg up 1 - abort: *: '$TESTTMP/r1/r2/name' (glob) + name: untracked file differs + abort: untracked files in working directory differ from files in requested revision [255] $ cd ..