hosseio
hosseio

Reputation: 1222

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

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.

Upvotes: 15

Views: 4515

Answers (3)

sleske
sleske

Reputation: 83635

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.

Upvotes: 4

hosseio
hosseio

Reputation: 1222

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 :)

Upvotes: 21

Christopher Valles
Christopher Valles

Reputation: 133

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

Upvotes: 4

Related Questions