[PATCH] update: do not remove cwd
Stanislau Hlebik
stash at fb.com
Tue Aug 30 13:41:20 EDT 2016
Yeap, Augie already noted it.
Warning is probably fine (it’s better than nothing).
Another option is to try to save cwd before update and try to restore it after.
On 8/30/16, 5:45 PM, "Durham Goode" <durham at fb.com> wrote:
On 8/29/16 11:50 AM, Stanislau Hlebik wrote:
> # HG changeset patch
> # User Stanislau Hlebik <stash at fb.com>
> # Date 1472496038 25200
> # Mon Aug 29 11:40:38 2016 -0700
> # Node ID e1962781ce84040746ef79c0084b8fd70cfcd4b4
> # Parent 318e2b600b80e4ed3c6f37df46ec7544f60d4c0b
> update: do not remove cwd
>
> During update directories are deleted as soon as they have no entries.
> But current working directory shouldn't be deleted because it
> causes problems for users after hg finishes. Also it makes complex commands
> like 'hg split' fail.
Won't this cause update to fail if the parent directory is to be deleted
and replaced with a file? I'd almost err towards just printing a
warning message when the current working directory is deleted (and
recommending they cd to the root of their repo).
>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -1043,7 +1043,7 @@
> repo.ui.note(_("removing %s\n") % f)
> audit(f)
> try:
> - unlink(wjoin(f), ignoremissing=True)
> + unlink(wjoin(f), ignoremissing=True, donotremovecwd=True)
> except OSError as inst:
> repo.ui.warn(_("update failed to remove %s: %s!\n") %
> (f, inst.strerror))
> diff --git a/mercurial/posix.py b/mercurial/posix.py
> --- a/mercurial/posix.py
> +++ b/mercurial/posix.py
> @@ -23,6 +23,7 @@
> from .i18n import _
> from . import (
> encoding,
> + osutil,
> )
>
> posixfile = open
> @@ -496,7 +497,31 @@
> def makedir(path, notindexed):
> os.mkdir(path)
>
> -def unlinkpath(f, ignoremissing=False):
> +def removedirs(name, donotremovecwd=False):
> + """special version of os.removedirs that does not remove symlinked
This mentions symlinks are also affected. That seems unrelated to the
purpose of this patch though, and I think we do want to allow symlinks
to be deleted if their target contains files.
> + directories or junction points if they actually contain files"""
> + if not donotremovecwd:
> + return os.removedirs(name)
> +
> + cwd = os.getcwd()
> + if cwd == name:
> + return
> + if osutil.listdir(name):
> + return
> + os.rmdir(name)
> + head, tail = os.path.split(name)
> + if not tail:
> + head, tail = os.path.split(head)
> + while head and tail:
> + try:
> + if osutil.listdir(head) or cwd == head:
> + return
> + os.rmdir(head)
> + except (ValueError, OSError):
> + break
> + head, tail = os.path.split(head)
> +
> +def unlinkpath(f, ignoremissing=False, donotremovecwd=False):
> """unlink and remove the directory if it is empty"""
> try:
> os.unlink(f)
> @@ -505,7 +530,7 @@
> raise
> # try removing directories that might now be empty
> try:
> - os.removedirs(os.path.dirname(f))
> + removedirs(os.path.dirname(f), donotremovecwd)
> except OSError:
> pass
>
> diff --git a/mercurial/windows.py b/mercurial/windows.py
> --- a/mercurial/windows.py
> +++ b/mercurial/windows.py
> @@ -369,11 +369,14 @@
> If gid is None, return the name of the current group."""
> return None
>
> -def removedirs(name):
> +def removedirs(name, donotremovecwd=False):
> """special version of os.removedirs that does not remove symlinked
> directories or junction points if they actually contain files"""
> if osutil.listdir(name):
> return
> + cwd = os.getcwd()
> + if donotremovecwd and cwd == name:
> + return
> os.rmdir(name)
> head, tail = os.path.split(name)
> if not tail:
> @@ -382,12 +385,14 @@
> try:
> if osutil.listdir(head):
> return
> + if donotremovecwd and cwd == head:
> + return
> os.rmdir(head)
> except (ValueError, OSError):
> break
> head, tail = os.path.split(head)
>
> -def unlinkpath(f, ignoremissing=False):
> +def unlinkpath(f, ignoremissing=False, donotremovecwd=False):
> """unlink and remove the directory if it is empty"""
> try:
> unlink(f)
> @@ -396,7 +401,7 @@
> raise
> # try removing directories that might now be empty
> try:
> - removedirs(os.path.dirname(f))
> + removedirs(os.path.dirname(f), donotremovecwd)
> except OSError:
> pass
>
> diff --git a/tests/test-update-names.t b/tests/test-update-names.t
> --- a/tests/test-update-names.t
> +++ b/tests/test-update-names.t
> @@ -72,3 +72,13 @@
> $ cd ..
>
> #endif
> +
> +Test that cwd is not deleted during update
> + $ hg init r4 && cd r4
> + $ mkdir dir
> + $ cd dir
> + $ echo a > a
> + $ hg add a
> + $ hg ci -m "file and dir"
> + $ hg up -q null
> + $ cd .
More information about the Mercurial-devel
mailing list