diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -563,10 +563,23 @@ fullorigpath = repo.wjoin(origbackuppath, filepathfromroot) origbackupdir = repo.vfs.dirname(fullorigpath) - if not repo.vfs.exists(origbackupdir): + if not repo.vfs.isdir(origbackupdir): ui.note(_('creating directory: %s\n') % origbackupdir) + + # Remove any files that conflict with the backup file's path + for f in util.finddirs(fullorigpath): + if repo.vfs.exists(f): + if repo.vfs.isfile(f): + ui.note(_('removing conflicting file: %s\n') % f) + repo.vfs.unlink(f) + break + util.makedirs(origbackupdir) + if repo.vfs.isdir(fullorigpath): + ui.note(_('removing conflicting directory: %s\n') % fullorigpath) + repo.vfs.rmtree(fullorigpath, forcibly=True) + return fullorigpath class _containsnode(object): diff --git a/tests/test-origbackup-conflict.t b/tests/test-origbackup-conflict.t new file mode 100644 --- /dev/null +++ b/tests/test-origbackup-conflict.t @@ -0,0 +1,80 @@ +Set up repo + + $ cat << EOF >> $HGRCPATH + > [ui] + > origbackuppath=.hg/origbackups + > [merge] + > checkunknown=warn + > EOF + $ hg init repo + $ cd repo + $ echo base > base + $ hg add base + $ hg commit -m "base" + +Make a dir named b that contains a file + + $ mkdir -p b + $ echo c1 > b/c + $ hg add b/c + $ hg commit -m "c1" + $ hg bookmark c1 + +Peform an update that causes b/c to be backed up + + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + (leaving bookmark c1) + $ mkdir -p b + $ echo c2 > b/c + $ hg up --verbose c1 + resolving manifests + b/c: replacing untracked file + getting b/c + creating directory: $TESTTMP/repo/.hg/origbackups/b + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark c1) + $ test -f .hg/origbackups/b/c + +Make a file named b + + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + (leaving bookmark c1) + $ echo b1 > b + $ hg add b + $ hg commit -m b1 + created new head + $ hg bookmark b1 + +Perform an update that causes b to be backed up - it should replace the backup b dir + + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + (leaving bookmark b1) + $ echo b2 > b + $ hg up --verbose b1 + resolving manifests + b: replacing untracked file + getting b + removing conflicting directory: $TESTTMP/repo/.hg/origbackups/b + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark b1) + $ test -f .hg/origbackups/b + +Perform an update the causes b/c to be backed up again - it should replace the backup b file + + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + (leaving bookmark b1) + $ mkdir b + $ echo c3 > b/c + $ hg up --verbose c1 + resolving manifests + b/c: replacing untracked file + getting b/c + creating directory: $TESTTMP/repo/.hg/origbackups/b + removing conflicting file: $TESTTMP/repo/.hg/origbackups/b + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark c1) + $ test -d .hg/origbackups/b