scratch/git-hooks f80108ea480 2/2: Simplify commit msg file hook

Jim Porter <[email protected]> Thu, 30 Jul 2026 18:04:46 -0400 (EDT)
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: scratch/git-hooks
commit f80108ea480dbab993c833b300dcb70dcfd70de4
Author: Jim Porter <[email protected]>
Commit: Jim Porter <[email protected]>

    Simplify commit msg file hook
    
    * build-aux/git-hooks/commit-msg-files.awk (get_commit_changes): Use
    "git diff-tree" to simplify parsing of touched files.
    
    * build-aux/git-hooks/pre-push: Use a simpler invocation of "git
    rev-list" to get all commits to be pushed.
    
    * bad-file.txt: This is an invalid listing.
---
 build-aux/git-hooks/commit-msg-files.awk | 20 +++++------
 build-aux/git-hooks/pre-push             | 62 +++++++++-----------------------
 2 files changed, 24 insertions(+), 58 deletions(-)

diff --git a/build-aux/git-hooks/commit-msg-files.awk b/build-aux/git-hooks/commit-msg-files.awk
index 852488b551e..52df7b746ce 100644
--- a/build-aux/git-hooks/commit-msg-files.awk
+++ b/build-aux/git-hooks/commit-msg-files.awk
@@ -30,20 +30,16 @@
 
 ### Code:
 
-function get_commit_changes(commit_sha, changes,    cmd, i, j, len, \
+function get_commit_changes(commit_sha, changes,    cmd, i, len, \
                             bits, filename) {
-  # Collect all the files touched in the specified commit.
-  cmd = ("git show --name-status --first-parent --format= " commit_sha)
+  # Collect all the files and their parent directories touched in the
+  # specified commit.
+  cmd = ("git diff-tree --no-commit-id --name-only -r " commit_sha)
   while ((cmd | getline) > 0) {
-    for (i = 2; i <= NF; i++) {
-      len = split($i, bits, "/")
-      for (j = 1; j <= len; j++) {
-        if (j == 1)
-          filename = bits[j]
-        else
-          filename = filename "/" bits[j]
-        changes[filename] = 1
-      }
+    len = split($0, bits, "/")
+    for (i = 1; i <= len; i++) {
+      filename = i == 1 ? bits[i] : filename "/" bits[i]
+      changes[filename] = 1
     }
   }
   close(cmd)
diff --git a/build-aux/git-hooks/pre-push b/build-aux/git-hooks/pre-push
index 81ba85697c3..80cdf82af62 100755
--- a/build-aux/git-hooks/pre-push
+++ b/build-aux/git-hooks/pre-push
@@ -32,6 +32,8 @@
 ### Code:
 
 HOOKS_DIR=`dirname "$0"`
+REMOTE_NAME="$1"
+NULL_SHA="0000000000000000000000000000000000000000"
 
 # Prefer gawk if available, as it handles NUL bytes properly.
 if type gawk >/dev/null 2>&1; then
@@ -40,49 +42,17 @@ else
   awk="awk"
 fi
 
-# Standard input receives lines of the form:
-#   <local ref> SP <local sha> SP <remote ref> SP <remote sha> LF
-$awk -v origin_name="$1" '
-  # If the local SHA is all zeroes, ignore it.
-  $2 ~ /^0{40}$/ {
-    next
-  }
-
-  # Check any lines with a valid local SHA and whose remote ref is
-  # master or an emacs-NN release branch.  (We want to avoid checking
-  # feature or scratch branches here.)
-  $2 ~ /^[a-z0-9]{40}$/ && $3 ~ /^refs\/heads\/(master|emacs-[0-9]+)$/ {
-    newref = $2
-    # If the remote SHA is all zeroes, this is a new object to be
-    # pushed (likely a branch)...
-    if ($4 ~ /^0{40}$/) {
-      back = 0
-      # ... Go backwards until we find a SHA on an origin branch.
-      # Stop trying after 1000 commits, just in case...
-      for (back = 0; back < 1000; back++) {
-        cmd = ("git branch -r -l '\''" origin_name "/*'\''" \
-               " --contains " newref "~" back)
-        rv = (cmd | getline)
-        close(cmd)
-        if (rv > 0)
-          break;
-      }
-
-      cmd = ("git rev-parse " newref "~" back)
-      cmd | getline oldref
-      if (!(oldref ~ /^[a-z0-9]{40}$/)) {
-        # The SHA is misformatted!  Skip this line.
-        next
-      }
-      close(cmd)
-    } else if ($4 ~ /^[a-z0-9]{40}$/)  {
-      oldref = $4
-    } else {
-      # The SHA is misformatted!  Skip this line.
-      next
-    }
-
-    # Print every SHA after oldref, up to (and including) newref.
-    system("git rev-list --first-parent --reverse " oldref ".." newref)
-  }
-' | $awk -v reason=pre-push -f "$HOOKS_DIR"/commit-msg-files.awk
+while read local_ref local_sha remote_ref remote_sha; do
+  if [ "$local_sha" = $NULL_SHA ]; then # Deleted the ref.
+    continue
+  fi
+
+  # Check any lines whose remote ref is master or an emacs-NN release
+  # branch.  (We want to avoid checking feature or scratch branches
+  # here.)
+  if echo "$remote_ref" | grep -Eq "^refs/heads/(master|emacs-[0-9]+)$"; then
+    # List the SHAs of all commits to be pushed to the remote for the
+    # current local SHA.
+    git rev-list "$local_sha" --not --remotes="$REMOTE_NAME"
+  fi
+done | $awk -v reason=pre-push -f "$HOOKS_DIR"/commit-msg-files.awk