How would you write a pre-push hook that rejects pushing when the overall diff introduces a specific word/sentence/string?
Motivating use-case:
- committing
TODO
notes (marking tasks to complete before pushing) - letting git prevent me from forgetting to address said notes when pushing
Notes:
- I have seen a lot of different questions and answers but none come close. The ones that try quickly fail on edge cases (e.g. this and this).
- notice that "overall diff" means that commits adding
TODO
would be allowed as long as the string was removed in subsequent commits being pushed (such that the overall delta did not contain it) - the main difficulty is finding a range to pass to
git diff
that works in all cases. - only additions of
TODO
are to be blocked, removals should be allowed in the diff - modifications of lines previously containing
TODO
that maintain it, imply aTODO
addition (even if simultaneous with a removal) and should therefore be blocked (rationale: no objective way to distinguish whether the introducedTODO
is the same as the removed one). - such a hook should cope with all valid pushes, checking only deltas corresponding to ranges of new commits (e.g. nothing to check in
push --delete
). Some particular cases to consider:- new branches
- deleted branches
- renamed branches
- branching off of something other than master (so no
merge-base origin/master
) - splits/merges
- tags
- force pushes
- Bonus variation: prevent pushing any commits adding
TODO
(rather than in the overall diff).