Add a with_lock function to ensure commitnumber appends do not interweave.
authorStephen Haberman <stephen@exigencecorp.com>
Mon, 29 Sep 2008 14:55:20 +0000 (09:55 -0500)
committerStephen Haberman <stephen@exigencecorp.com>
Mon, 29 Sep 2008 14:55:20 +0000 (09:55 -0500)
server/functions
server/post-receive-assign-commit-numbers

index b5065d3..4557d76 100644 (file)
@@ -173,3 +173,37 @@ function set_describe_tags() {
        fi
 }
 
+# Takes a lockfile path and command to execute once the lock is acquired.
+#
+# Retries every second for 5 minutes.
+#
+# with_lock "foo.lock" "echo a"             # Works
+# with_lock "foo.lock" "echo b1 ; echo b2"  # Work
+# function several() {
+# echo several1 ; echo several2
+# }
+# with_lock "foo.lock" several              # Works
+#
+function with_lock() {
+       lockfile="$1"
+       block="$2"
+       with_lock_has_lock=1
+
+       trap with_lock_unlock_if_held INT TERM EXIT
+       lockfile -1 -r 300 "$lockfile"
+       with_lock_has_lock=$?
+       if [ $with_lock_has_lock -ne 0 ] ; then
+               exit $?
+       fi
+       eval "$block"
+       rm -f "$lockfile"
+       with_lock_has_lock=1
+}
+
+function with_lock_unlock_if_held() {
+       if [[ "$with_lock_has_lock" -eq 0 ]] ; then
+               rm -f "$lockfile"
+       fi
+}
+
+
index 46cd45a..39c3f48 100644 (file)
@@ -2,13 +2,11 @@
 
 . $(dirname $0)/functions
 
-touch "$GIT_DIR/commitnumbers"
-
 while read oldrev newrev refname ; do
        set_new_commits
        echo "$new_commits" | git rev-list --reverse --stdin | while read commit ; do
-               if [[ $(grep "$commit" "$GIT_DIR/commitnumbers") == "" ]] ; then
-                       echo "$commit" >> "$GIT_DIR/commitnumbers"
+               if [[ $(grep "$commit" "$GIT_DIR/commitnumbers" 2>/dev/null) == "" ]] ; then
+                       with_lock "$GIT_DIR/commitnumbers.lock" 'echo "$commit" >> "$GIT_DIR/commitnumbers"'
                        number=$(grep --max-count=1 --line-number "$commit" "$GIT_DIR/commitnumbers" | grep -oP "^\d+(?=:)")
                        git tag "r/$number" "$commit"
                fi