[PATCH] chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof
koen.van_hoof at nokia.com
Thu Apr 27 07:32:22 UTC 2017
# HG changeset patch
# User Koen Van Hoof <koen.van_hoof at nokia.com>
# Date 1493215522 -7200
# Wed Apr 26 16:05:22 2017 +0200
# Branch stable
# Node ID e47e40bff9e07095076753e3e5288625951776ea
# Parent 6e0368b6e0bb2aa5210daec091c0200583553a78
chmod: create a new file when flags are set on a hardlinked file
For performance reasons we have several repositories where the files in the working
directory of 1 repo are hardlinks to the files of the other repo
When an update in one repo results in a chmod of a such a file, the hardlink
has to be deleted and replaced by a regular file to make sure that the change
does not happen in the other repo
diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -98,7 +98,8 @@ def isexec(f):
return (os.lstat(f).st_mode & 0o100 != 0)
def setflags(f, l, x):
- s = os.lstat(f).st_mode
+ st = os.lstat(f)
+ s = st.st_mode
if l:
if not stat.S_ISLNK(s):
# switch file to link
@@ -124,6 +125,14 @@ def setflags(f, l, x):
fp.close()
s = 0o666 & ~umask # avoid restatting for chmod
+ if st.st_nlink > 1: # the file is a hardlink, break the hardlink
+ fpin = open(f,"r")
+ unlink(f)
+ fpout = open(f, "w")
+ fpout.write(fpin.read())
+ fpin.close()
+ fpout.close()
+
sx = s & 0o100
if x and not sx:
# Turn on +x for every +r bit when making a file executable
@@ -132,6 +141,8 @@ def setflags(f, l, x):
elif not x and sx:
# Turn off all +x bits
os.chmod(f, s & 0o666)
+ elif st.st_nlink > 1: # new file still needs its stat to be copied
+ os.chmod(f, s)
def copymode(src, dst, mode=None):
'''Copy the file mode from the file at path src to dst.
More information about the Mercurial-devel
mailing list