repo.opener() no longer follows symlinks

Greg Ward greg at gerg.ca
Thu Nov 25 19:56:40 UTC 2010


On Thu, Nov 25, 2010 at 12:58 PM, Adrian Buehlmann <adrian at cadifra.com> wrote:
> Could you please test the patch below? (warning: use only on testrepos)
>
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -891,9 +891,12 @@ class opener(object):
>             try:
>                 if 'w' in mode:
>                     st_mode = os.lstat(f).st_mode & 0777
> -                    os.unlink(f)
> -                    nlink = 0
> -                else:
> +                    if stat.S_ISLNK(st_mode):
> +                        st_mode = None

Not quite.  The "& 0777" masks off the symlink bit.  Here's a revised
version that works for me:

"""
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -890,10 +890,13 @@
                 return atomictempfile(f, mode, self.createmode)
             try:
                 if 'w' in mode:
-                    st_mode = os.lstat(f).st_mode & 0777
-                    os.unlink(f)
-                    nlink = 0
-                else:
+                    st_mode = os.lstat(f).st_mode
+                    if stat.S_ISLNK(st_mode):
+                        st_mode = None
+                    else:
+                        os.unlink(f)
+                        nlink = 0
+                if st_mode is None:
                     # nlinks() may behave differently for files on Windows
                     # shares if the file is open.
                     fd = open(f)
@@ -913,7 +916,7 @@
             if st_mode is None:
                 self._fixfilemode(f)
             else:
-                os.chmod(f, st_mode)
+                os.chmod(f, st_mode & 0777)
         return fp

     def symlink(self, src, dst):

"""

I'm running the test suite now.  Probably wouldn't hurt if you ran it
too.  Would be even better if someone could run it on Windows!

Greg



More information about the Mercurial-devel mailing list