How to disable git push when there are TODOs in code?
Asked Answered
F

3

15

We are having an issue in our team and we have decided to check if there is a way or git command to reject git push where there are TODOs in the code. Any ideas? Thanks in advance.

Falange answered 14/12, 2012 at 11:8 Comment(1)
F
21

EDIT: because of grep behaviour in if statement we needed to edit our script:

#!/bin/sh

for FILE in `git diff --name-only --cached`; do
    grep 'TODO' $FILE 2>&1 >/dev/null
    if [ $? -eq 0 ]; then
        echo $FILE ' contains TODO'
        exit 1
    fi
done
exit

Is not possible use pre-receive hooks in github, so we are using instead pre-commit hook in client side: http://git-scm.com/book/en/Customizing-Git-Git-Hooks#Client-Side-Hooks

Our pre-commit script (based on http://mark-story.com/posts/view/using-git-commit-hooks-to-prevent-stupid-mistakes) looks like:

#!/bin/sh

for FILE in `git diff-index -p -M --name-status HEAD -- | cut -c3-` ; do
    if [ "grep 'TODO' $FILE" ]
    then
        echo $FILE ' contains TODO'
        exit 1
    fi
done
exit

We have this script under our control version system, and create a symbolic link to it in .git/hooks

Thanks for the help :)

Falange answered 17/12, 2012 at 10:33 Comment(2)
Don't forget to chmod +x .git/hooks/pre-commit after creating the fileReceptacle
Note that this pre-commit hook will complain even for TODOs that were already in the file (i.e. were committed earlier). This may or may not be what you want.Buffalo
O
4

Pre-receive hook on the server, grep the files and abort the push :)

More info on the pre-receive hook can be found here: http://git-scm.com/book/en/Customizing-Git-Git-Hooks#Server-Side-Hooks

Orientate answered 14/12, 2012 at 11:11 Comment(1)
Any ideas or link where to read about this working in github? Our project is hosted on github and I only see the post-receive hook :? Of course we can use client-side hooks (like the pre-commit hook), but then we need to create it in all our machines. Thanks for your help :)Falange
B
2

Old question, but anyway... update for 2023.

As of 2023, git offers a pre-push hook, which does exactly what the question asks. Instead of using a pre-commit hook, as in hosseio's answer, which interferes with committing TODOs, the pre-push hook will let you freely commit and rebase TODOs in the code, and will only prevent pushing them.

Example pre-push hook:

#!/bin/sh
# Pre-push hook to prevent pushing code with TODOs.

zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')

while read local_ref local_oid remote_ref remote_oid; do
    if test "$remote_oid" = "$zero"; then
        # New branch, examine all commits
        range="$local_oid"
    else
        # Update to existing branch, examine new commits
        range="$remote_oid..$local_oid"
    fi

    # Check for WIP commit
    commit=$(git log --oneline -STODO "$range")
    if test -n "$commit"
    then
            echo >&2 "Found TODO commit, not pushing:"
            echo >&2 "$commit"
            exit 1
    fi
done

exit 0

Remarks:

  • As I could not find a quick, convenient way to check the contents of commits, I used git log -S to find commits containing "TODO". This means that the hook will also reject commits that remove TODOs - probably not what you want. Of course, if you never push TODOs, you will never need to remove them. Otherwise, just push with --no-verify.
  • On the other hand, in contrast to the hook from hosseio's answer, this hook will allow changing and pushing files with existing TODOs, as long as no new TODOs are added (or removed, see above). Whether that is right or wrong is a matter of definition.
  • Since the hook checks every commit being pushed, it will also trigger if you push the result of a merge and some commit being merged contains TODOs. This is arguably correct, but may be confusing if you did not author the commit yourself.
Buffalo answered 21/9, 2023 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.