Only allow `git commit -a` when nothing is staged
So I'm really messy with the command line, and I'll sometimes run a commit -a
when I have files staged for a normal commit... yeah, I'm terrible.
Anyways, to prevent that, I delved into the core of git, and extracted the follow git pre-commit snippet. It's a little hacky, depending on the pre-commit being a direct child process of the git binary and then uses procfs to extract the original git arguments. I could base it solely on the GIT_*
environment vars, but I'll only need to fix that if it breaks.
Now, git does a bit of magic when doing some (aka. pretty much anything other than normal) types of commit. Git will create a copy of the index, called index.lock
(a magical binary file that I don't yet understand), and tell itself to use that, rather than the default index (aptly named index
). So, when I need to check if I have files currently staged, I have to unset the GIT_INDEX_FILE
environment variable, so that git uses index
rather than index.lock
.
So here's the result! :
# don't allow --all when we have staged files. It's usually a mistake
# depends on procfs and won't work through gitaliases
while read -d $'\0' arg ; do
if [[ "$arg" == -a* || "$arg" == -[b-zB-Z]*a* || "$arg" == '--all' ]] ; then
if (( $((unset GIT_INDEX_FILE; git diff --cached --name-only)|wc -l) > 0 )) ; then
echo 'using --all while files are cached. don'\''t do that.'
exit 1
fi
fi
done < /proc/$PPID/cmdline