0

I've written a pre-commit hook to remove trailing whitespace with git for Windows 2.27.0.windows.1. It seems like a well researched subject, but unfortunately, I cannot get it to work as it should. This is my .git\hooks\pre-commit file:

#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=$(git hash-object -t tree /dev/null)
fi

git diff --cached --name-only --diff-filter=ACM -z $against | xargs -0 | while read LINE
do 
    if [ -n "$LINE" ]; then
        remove_whitespace "$LINE"
        git add "$LINE"
    fi
done

Assume I have a file test.txt already committed and it has no trailing whitespace. Now I add trailing whitespace somewhere to it and I want the pre-commit to remove that whitespace and not commit anything (since there were no changes). But this is what happens:

C:\> git status
On branch test
Your branch is ahead of 'origin/test' by 17 commits.
(use "git push" to publish your local commits)

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

C:\> git commit test.txt -m test
test.txt
[test 30cb9c0] test

C:\> git status
On branch test
Your branch is ahead of 'origin/test' by 18 commits.
(use "git push" to publish your local commits)

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
        modified:   test.txt

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

C:\> git add test.txt

C:\> git status
On branch test
Your branch is ahead of 'origin/test' by 18 commits.
(use "git push" to publish your local commits)

nothing to commit, working tree clean        

It really did remove trailing whitespace from test.txt, since when I add the cleaned up file with git add test.txt it shows no more changes. But the pre-commit hook seems to cause a file with trailing whitespace to be in the staged area and a file without trailing whitespace not yet staged for commit.

How can I process all files that are about to be committed, commit output of said processing, but only if that caused a change to the already committed version?

cxxl
  • 4,939
  • 3
  • 31
  • 52
  • Why `git diff -z | xargs -0 | while read LINE`? Why not just `git diff | while read LINE`? – phd Nov 18 '20 at 17:37
  • Otherwise filenames with spaces will cause trouble. – cxxl Nov 19 '20 at 08:57
  • 1
    Perhaps add `-n 1` to the `xargs` arguments, to make sure it processes only one file at a time, as I'm pretty sure that's what you want. (Also, for clarity, I'd rename `$LINE` to `$FILE`. ) – Mort Dec 08 '20 at 13:35

0 Answers0