Reputation: 483
Because of a tool that I use, certain comment lines keeps being added to my code.
// Added by blahblah
Since I can't turn off this behavior, I want to configure Git to automatically remove that comment line from both local file and commit.
I want to configure Git to do these:
// Added by blahblah
comment linesSo, after Git completes its job, the comment lines must be removed from both local file and commit (and remote repository too).
First thing I've tried was using IDEA's File Watchers plugin.
If I register a script that removes that comment line, the problem would be solved because the comment line is removed before Git creates commit and the commit won't have that comment line.
So 'No comment in local file, No comment in commit too'.
I wrote a bash script for it.
#!/bin/bash
# this script is located at '.script' directory
scriptdir="$(dirname -- "$0")"
cd "$scriptdir/../src" || exit
java_files=$(find . -type f -name "*.java")
for java_file in $java_files; do
sed -i '/^[[:space:]]*\/\/ Added by blahblah/d' "$java_file"
done
But File Watchers kept running when I enable my watcher task.
I expected the task to be run only once for every file save, but it kept running infinitely.
Because File Watchers task is executed every seconds, it conflicted with currently opened editor's content. This prevented me to edit code at all.
So I gave up using File Watchers plugin.
Next thing I've tried was using Git Hooks.
In my theory, if I set Git Hooks correctly, Git would edit my local files before making any commit. Since my local files are edited before commit, both local files and files in the commit won't have such comment lines.
I wrote prepare-commit-msg
like this.
#!/bin/bash
# this script is located at '.git/hooks' directory
print "$PWD"
scriptdir="$(dirname -- "$0")"
cd "$scriptdir/../../src" || exit
echo "$PWD"
java_files=$(find . -type f -name "*.java")
for java_file in $java_files; do
sed -i '/^[[:space:]]*\/\/ Added by blahblah/d' "$java_file"
done
But nothing were changed as if there was no such hook present. pre-commit
also didn't work.
Here is updated version of the prepare-commit-msg
, but this doesn't work either.
#!/bin/bash
TMP_FILE=$(mktemp)
for FILE in $(git diff --cached --name-only --diff-filter=AM); do
if [[ $FILE == *.java ]]; then
sed -e '/^[[:space:]]*\/\/ Added by blahblah/d' "$FILE" > "$TMP_FILE"
cat "$TMP_FILE" > "$FILE"
git add "$FILE"
# This doesn't work neither
#sed -i -e '/^[[:space:]]*\/\/ Added by blahblah/d' "$FILE"
#git add "$FILE"
fi
done
exit 0
Last thing I've tried was to use .gitattributes
's filter
.
I added these line into .gitconfig
.
[filter "nocomment"]
clean = "sed -i -e '/^[[:space:]]*\\/\\/ Added by blahblah/d' %f"
smudge = ""
required = true
And this line to .gitattributes
.
*.java filter=nocomment
Since I only need to 'remove' lines, not 'restore' them, I left smudge
as empty.
But this didn't remove the comment line from local file. Git might remove that line for commit, but that's not what I want.
(I'm using Git for Windows, and this might be the reason of something doesn't work properly...?)
Here is working pre-commit
script's content.
#!/bin/bash
set -x # This thing is new... Thanks for the information!
for FILE in $(git diff --cached --name-only --diff-filter=ACM); do # '--diff-filter' is needed
if [[ $FILE == *.java ]]; then # I only have to process java file
echo Removing comment from ${FILE}
sed -i '/^[[:space:]]*\/\/ Added by blahblah/d' "$FILE"
git add "$FILE" # This line was already in second attempt
fi
done
The reason that Git hooks didn't run as if they weren't present was I set git config --global core.hooksPath
before. This prevented hooks in .git/hooks
from running...
Now everything works as intended. Thank you!
Upvotes: 4
Views: 443
Reputation: 67852
I'm not going to comment on the IDEA FileWatcher plugin, because an IDE is not a substitute for proper automation.
Next thing I've tried was using Git Hooks.
These are well-documented, here.
I wrote prepare-commit-msg like this
But the linked docs explicitly say
It should not be used as replacement for
pre-commit
hook.
It's just for altering the message, after the staged changes are final. Let's pretend you wrote your script as the correct hook instead, pre-commit
.
There are a few mistakes in both of your attempts, but you could have debugged them all quickly by adding set -x
at the top and just running the script. You don't need git to invoke it for you, just test it yourself.
If we combine the unbroken parts of both, it is only missing one thing: you changed the working tree, but didn't stage your changes for inclusion in the commit.
useless@stackoverflow:~/Source/so/pchook $ cat .git/hooks/pre-commit
#!/bin/sh
#
set -x
for FILE in $(git diff --cached --name-only)
do
sed -i '/^[[:space:]]*\/\/ Added by blahblah/d' "$FILE"
git add "$FILE" ### this was missing
done
Proof:
useless@stackoverflow:~/Source/so/pchook $ git diff
diff --git a/test.txt b/test.txt
index f2affac..d8767dd 100644
--- a/test.txt
+++ b/test.txt
@@ -5,7 +5,7 @@ should be
unaffected // or with comments excluding the special phrase
// added by "blahblah"
except without quotes. // like // Added by blahblah
-
+ // Added by blahblah
EOF or something
useless@stackoverflow:~/Source/so/pchook $ git commit -am'test'
+ git diff --cached --name-only
+ sed -i /^[[:space:]]*\/\/ Added by blahblah/d test.txt
+ git add test.txt
[master 7ba7949] test
1 file changed, 1 deletion(-)
useless@stackoverflow:~/Source/so/pchook $ git show HEAD
commit 7ba79490edbf9afc54ac5e4458323f25803ddba3 (HEAD -> master)
Author: Useless <[email protected]>
Date: Wed Aug 16 21:23:45 2023 +0100
test
diff --git a/test.txt b/test.txt
index f2affac..66b45b6 100644
--- a/test.txt
+++ b/test.txt
@@ -5,7 +5,6 @@ should be
unaffected // or with comments excluding the special phrase
// added by "blahblah"
except without quotes. // like // Added by blahblah
-
EOF or something
useless@stackoverflow:~/Source/so/pchook $
Upvotes: 1