[PATCH] fix symlinks on symlink-capable os but non-capable filesystem (issue1149)

Dov Feldstern dfeldstern at fastimap.com
Thu Jul 10 15:49:11 CDT 2008


# HG changeset patch
# User Dov Feldstern <dfeldstern at fastimap.com>
# Date 1215722678 -10800
# Node ID 41adb937dd0f800314a500801bf85c54b26cfa1b
# Parent  694223a29ad494fbd2cee69ebdceadfc6ac127cf
fix symlinks on symlink-capable os but non-capable filesystem (issue1149)

1. write a symlink directly as a symlink (currently it's being written as a
   file, and only then switched to a symlink by set_flags); note that writing
   as a symlink already makes sure that the fs supports symlinks.
2. set_flags should only switch a file to a symlink on a symlink-capable fs.

diff -r 694223a29ad4 -r 41adb937dd0f hgext/convert/subversion.py
--- a/hgext/convert/subversion.py	Thu Jul 03 20:53:14 2008 -0700
+++ b/hgext/convert/subversion.py	Thu Jul 10 23:44:38 2008 +0300
@@ -976,7 +976,7 @@
             fp = open(hook, 'w')
             fp.write(pre_revprop_change)
             fp.close()
-            util.set_flags(hook, "x")
+            util.set_flags(hook, "x", self.wopener._can_symlink)
 
         xport = transport.SvnRaTransport(url=geturl(path))
         self.uuid = svn.ra.get_uuid(xport.ra)
@@ -1003,7 +1003,8 @@
                 # systematically is just as expensive and much simpler.
                 was_exec = 'x' not in flags
 
-            util.set_flags(self.wjoin(filename), flags)
+            util.set_flags(self.wjoin(filename), flags,
+                           self.wopener._can_symlink)
             if was_exec:
                 if 'x' not in flags:
                     self.delexec.append(filename)
diff -r 694223a29ad4 -r 41adb937dd0f mercurial/localrepo.py
--- a/mercurial/localrepo.py	Thu Jul 03 20:53:14 2008 -0700
+++ b/mercurial/localrepo.py	Thu Jul 10 23:44:38 2008 +0300
@@ -565,8 +565,11 @@
             os.unlink(self.wjoin(filename))
         except OSError:
             pass
-        self.wopener(filename, 'w').write(data)
-        util.set_flags(self.wjoin(filename), flags)
+        if 'l' in flags:
+            self.wopener.symlink(data, filename)
+        else:
+            self.wopener(filename, 'w').write(data)
+        util.set_flags(self.wjoin(filename), flags, self.wopener._can_symlink)
 
     def wwritedata(self, filename, data):
         return self._filter("decode", filename, data)
diff -r 694223a29ad4 -r 41adb937dd0f mercurial/merge.py
--- a/mercurial/merge.py	Thu Jul 03 20:53:14 2008 -0700
+++ b/mercurial/merge.py	Thu Jul 10 23:44:38 2008 +0300
@@ -337,7 +337,7 @@
                 repo.ui.warn(" %s\n" % nf)
         elif m == "e": # exec
             flags = a[2]
-            util.set_flags(repo.wjoin(f), flags)
+            util.set_flags(repo.wjoin(f), flags, repo.wopener._can_symlink)
 
     return updated, merged, removed, unresolved
 
diff -r 694223a29ad4 -r 41adb937dd0f mercurial/patch.py
--- a/mercurial/patch.py	Thu Jul 03 20:53:14 2008 -0700
+++ b/mercurial/patch.py	Thu Jul 10 23:44:38 2008 +0300
@@ -1108,7 +1108,7 @@
             if ctype == 'ADD' and not os.path.exists(dst):
                 repo.wwrite(gp.path, '', flags)
             else:
-                util.set_flags(dst, flags)
+                util.set_flags(dst, flags, repo.wopener._can_symlink)
     cmdutil.addremove(repo, cfiles)
     files = patches.keys()
     files.extend([r for r in removes if r not in files])
diff -r 694223a29ad4 -r 41adb937dd0f mercurial/util.py
--- a/mercurial/util.py	Thu Jul 03 20:53:14 2008 -0700
+++ b/mercurial/util.py	Thu Jul 10 23:44:38 2008 +0300
@@ -1069,7 +1069,7 @@
         '''return False if pid dead, True if running or not known'''
         return True
 
-    def set_flags(f, flags):
+    def set_flags(f, flags, can_symlink):
         pass
 
     def set_binary(fd):
@@ -1216,12 +1216,12 @@
         """check whether a file is executable"""
         return (os.lstat(f).st_mode & 0100 != 0)
 
-    def set_flags(f, flags):
+    def set_flags(f, flags, can_symlink):
         s = os.lstat(f).st_mode
         x = "x" in flags
         l = "l" in flags
         if l:
-            if not stat.S_ISLNK(s):
+            if can_symlink and not stat.S_ISLNK(s):
                 # switch file to link
                 data = file(f).read()
                 os.unlink(f)


More information about the Mercurial-devel mailing list