# HG changeset patch # User Kostia Balytskyi # Date 1467387775 -7200 # Node ID 1e4512eac59e0114bc60ecbcdc4157fc0fa0439d # Parent 5d16ebe7b14f9809c31faaed85cffd1f3ca1ee6b update: teach hg to override untracked dir with a tracked file on update This is a fix to an old problem when Mercurial got confused by an untracked folder with the same name as one of the files in a commit hg was trying to update to. It is pretty safe to remove this folder if it is empty. Backing up an empty folder seems to go against Mercurial's "don't track dirs" philosophy. diff -r 5d16ebe7b14f -r 1e4512eac59e mercurial/merge.py --- a/mercurial/merge.py Fri Jul 01 14:09:53 2016 +0200 +++ b/mercurial/merge.py Fri Jul 01 17:42:55 2016 +0200 @@ -1076,15 +1076,14 @@ absf = repo.wjoin(f) orig = scmutil.origpath(ui, repo, absf) try: - # TODO Mercurial has always aborted if an untracked - # directory is replaced by a tracked file, or generally - # with file/directory merges. This needs to be sorted out. if repo.wvfs.isfileorlink(f): util.rename(absf, orig) except OSError as e: if e.errno != errno.ENOENT: raise + if repo.wvfs.isdir(f): + repo.wvfs.removedirs(f) wwrite(f, fctx(f).data(), flags, backgroundclose=True) if i == 100: yield i, f diff -r 5d16ebe7b14f -r 1e4512eac59e tests/test-merge1.t --- a/tests/test-merge1.t Fri Jul 01 14:09:53 2016 +0200 +++ b/tests/test-merge1.t Fri Jul 01 17:42:55 2016 +0200 @@ -24,9 +24,10 @@ $ hg update 0 0 files updated, 0 files merged, 1 files removed, 0 files unresolved -Test interrupted updates by exploiting our non-handling of directory collisions +Test interrupted updates by having a non-empty dir with the same name as one +of the files in a commit we're updating to - $ mkdir b + $ mkdir b && touch b/nonempty $ hg up abort: *: '$TESTTMP/t/b' (glob) [255] @@ -38,10 +39,10 @@ parent: 0:538afb845929 commit #0 branch: default - commit: (interrupted update) + commit: 1 unknown (interrupted update) update: 1 new changesets (update) phases: 2 draft - $ rmdir b + $ rm b/nonempty $ hg up 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg sum diff -r 5d16ebe7b14f -r 1e4512eac59e tests/test-update-names.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-update-names.t Fri Jul 01 17:42:55 2016 +0200 @@ -0,0 +1,55 @@ +Test update logic when there are renames or weird same-name cases between dirs +and files + +Update with local changes across a file rename + + $ hg init r1 && cd r1 + + $ echo a > a + $ hg add a + $ hg ci -m a + + $ hg mv a b + $ hg ci -m rename + + $ echo b > b + $ hg ci -m change + + $ hg up -q 0 + + $ echo c > a + + $ hg up + merging a and b to b + warning: conflicts while merging b! (edit, then use 'hg resolve --mark') + 0 files updated, 0 files merged, 0 files removed, 1 files unresolved + use 'hg resolve' to retry unresolved file merges + [1] + +Test update when local untracked directory exists with the same name as a +tracked file in a commit we are updating to + $ hg init r2 && cd r2 + $ echo root > root && hg ci -Am root # rev 0 + adding root + $ echo text > name && hg ci -Am "name is a file" # rev 1 + adding name + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkdir name + $ hg up 1 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test update when local untracked directory exists with some files in it and has +the same name a tracked file in a commit we are updating to. In future this +should be updated to give an friendlier error message, but now we should just +make sure that this does not erase untracked data + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkdir name + $ echo text > name/file + $ hg st + ? name/file + $ hg up 1 + abort: *: '$TESTTMP/r1/r2/name' (glob) + [255] + $ cd .. diff -r 5d16ebe7b14f -r 1e4512eac59e tests/test-update-renames.t --- a/tests/test-update-renames.t Fri Jul 01 14:09:53 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -Test update logic when there are renames - -Update with local changes across a file rename - - $ hg init - - $ echo a > a - $ hg add a - $ hg ci -m a - - $ hg mv a b - $ hg ci -m rename - - $ echo b > b - $ hg ci -m change - - $ hg up -q 0 - - $ echo c > a - - $ hg up - merging a and b to b - warning: conflicts while merging b! (edit, then use 'hg resolve --mark') - 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - use 'hg resolve' to retry unresolved file merges - [1]