repo.opener() no longer follows symlinks

Adrian Buehlmann adrian at cadifra.com
Thu Nov 25 11:58:48 CST 2010


On 2010-11-25 16:14, Greg Ward wrote:
> Hi all --
> 
> I have an extension that manages .hg/hgrc for my users.  Part of its
> contract is to *preserve* symlinks; we normally make .hg/hgrc in
> shared repos a symlink to the actual repo.  Up to *and including*
> Mercurial 1.7, this worked fine by using
> 
>   outfile = repo.opener('hgrc', 'w', text=True)
> 
> outfile ended up being the real file that the symlink .hg/hgrc points
> to, which is exactly what I wanted.
> 
> This broke in 1.7.1: repo.opener() now replaces the symlink with a
> real file.  I bisected and found:
> 
>   The first bad revision is:
>   changeset:   12922:6ff784de7c3a
>   branch:      stable
>   parent:      12913:ab93029ab622
>   user:        Adrian Buehlmann <adrian at cadifra.com>
>   date:        2010-11-04 09:04:37 +0100
>   summary:     util: refactor opener
> 
> I can obviously change my extension not to rely on this
> undocumented-and-no-longer-there feature.  But was this change
> intended?  Was it deliberate that repo.opener() would formerly follow
> symlinks, and no longer does?

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
+                    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)



More information about the Mercurial-devel mailing list