]> thyrsus.com Git - src.git/commitdiff
Propagare the eecutable bit on checkin.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 18 Dec 2014 19:09:12 +0000 (14:09 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 18 Dec 2014 19:09:12 +0000 (14:09 -0500)
NEWS
src
srctest

diff --git a/NEWS b/NEWS
index c770954e018d7a130fe9eed02a7cd9cac6415dd7..81542d47222c467607ff648a995255153d9f0785 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
 
 Repository head:
    Allow -- as an argument ender in src diff.
+   Changes to a workfile's x bits are propagated to its master on checkin.
 
 0.15: 2014-12-08
    Deal gracefully with directories passed as arguments.
diff --git a/src b/src
index eee254e5fb0d4cd1b607265931e08b38f41aa350..7f5a98f020cef65cdc1161155fc0d411f0c35c97 100755 (executable)
--- a/src
+++ b/src
@@ -1740,6 +1740,22 @@ class RCS:
     def checkin(self, arg, comment):
         "Check in a commit, with comment."
         comment = "'" + comment.replace("'", r"'\''") + "'"
+        # If the user changed the executable bit while modifying the
+        # workfile, propagate this change to the master.  Without this
+        # hack, the sequence (1) Commit workfile (2) Make workfile
+        # executable, (3) checkin workfile fails to work as expected
+        # because RCS doesn't propagate the changed executable bit to
+        # the master, leading to misbehavior on the next checkout.
+        if os.path.exists(arg + ",v"):
+            oldmastermode = newmastermode = os.stat(arg + ",v").st_mode
+            userworkmode = os.stat(arg).st_mode
+            for bitmask in (stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH):
+               if bitmask & userworkmode: 
+                   newmastermode |= bitmask
+               else:
+                   newmastermode &=~ bitmask
+            if newmastermode != oldmastermode:
+                os.chmod(self.history(arg), newmastermode)
         # By unlocking the file before checkin we invoke the following
         # property described on the rcs(1) manual page: "If rev is
         # omitted and the caller has no lock, but owns the file and
diff --git a/srctest b/srctest
index fa8f66a0b28d2d121f99429a41fe50a1f7699c69..c88dc0b63ee8035eb18ece0fa6900ed321cf94ba 100755 (executable)
--- a/srctest
+++ b/srctest
@@ -647,6 +647,16 @@ src $TESTOPTS cat -- 23 >tryit
 diff -u randomcontent tryit
 check "cat of file with numeric name"
 
+echo "Should not be executable" >exectest
+src $TESTOPTS commit -m "First comment on exectest" exectest >/dev/null
+check "first commit of exectest"
+chmod a+x exectest
+echo "Should be executable" >exectest
+src $TESTOPTS commit -m "Second comment on exectest" exectest >/dev/null
+check "second commit of exectest"
+ls -l exectest | grep 'x' >/dev/null
+check "propagation of exec bit"
+
 echo "srctest: all tests succeeded"
 
 rm -fr $SANDBOX