[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