changeset 5668:ca4f10c76ea7

Fix chmod of writable but unowned files (issue530) This could happen e.g. in group writable local repositories where a file should become executable on update. (Patch by Benoit Boissinot attached to issue530)
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 25 Dec 2007 14:05:26 +0100
parents f29b7c8419cb
children a0eb8a418442 8e495dd6662e
files mercurial/util.py
diffstat 1 files changed, 13 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/util.py	Fri Dec 21 12:07:02 2007 +0100
+++ b/mercurial/util.py	Tue Dec 25 14:05:26 2007 +0100
@@ -1106,6 +1106,17 @@
         """check whether a file is executable"""
         return (os.lstat(f).st_mode & 0100 != 0)
 
+    def force_chmod(f, s):
+        try:
+            os.chmod(f, s)
+        except OSError, inst:
+            if inst.errno != errno.EPERM:
+                raise
+            # maybe we don't own the file, try copying it
+            new_f = mktempcopy(f)
+            os.chmod(new_f, s)
+            os.rename(new_f, f)
+
     def set_exec(f, mode):
         s = os.lstat(f).st_mode
         if stat.S_ISLNK(s) or (s & 0100 != 0) == mode:
@@ -1113,9 +1124,9 @@
         if mode:
             # Turn on +x for every +r bit when making a file executable
             # and obey umask.
-            os.chmod(f, s | (s & 0444) >> 2 & ~_umask)
+            force_chmod(f, s | (s & 0444) >> 2 & ~_umask)
         else:
-            os.chmod(f, s & 0666)
+            force_chmod(f, s & 0666)
 
     def set_link(f, mode):
         """make a file a symbolic link/regular file