Code SnippetsA git hook to prevent pushes with untracked source files Syndicate content

Fri, 08/08/2014 - 13:40

Hey all,

do you know this: You work on something locally in git, ensure everything compiles and the tests pass, then commit and hit git push.What could possibly go wrong at that point, eh? Well, far too often I forgot to git add some new source file. Best-case I’ll notice this directly, worst-case I’ll see my CI complaining. But, like yesterday in kdev-clang, I might be afk at that point and someone else will have to revert my change and I’ll have to fix it up the day after, polluting the git history while at it…

Thanks to some simple shell scripting and the powerful git hook architecture, it is pretty simple to protect oneself against such issues:

  1. #!/bin/sh
  3. #
  4. # A hook script to verify that a push is not done with untracked source file
  5. #
  6. # To use it, either symlink this script to $your-git-clone/.git/hooks/pre-push
  7. # or include it in your existing pre-push script.
  8. #
  10. # Perl-style regular expression which limits the files we interpret as source files.
  11. # The default pattern here excludes CMakeLists.txt files and any .h/.cpp/.cmake files.
  12. # Extend/adapt this to your needs. Alternatively, set the pattern in your repo via:
  13. # git config hooks.prepush.sourcepattern "$your-pattern"
  14. pattern=$(git config --get hooks.prepush.sourcepattern)
  15. if [ -z "$pattern" ]; then
  16. pattern="(?:(?:^|/)CMakeLists\.txt|\.h|\.cpp|\.cmake)$"
  17. fi
  19. files=$(git status -u --porcelain --no-column | sed "s/^?? //" | grep -P "$pattern")
  20. if [ -z "$files" ]; then
  21. exit 0
  22. fi
  24. echo
  25. echo "ERROR: Preventing push with untracked source files:"
  26. echo
  27. echo "$files" | sed "s/^/ /"
  28. echo
  29. echo "Either include these files in your commits, add them to .gitignore"
  30. echo "or stash them with git stash -u."
  31. echo
  32. exit 1

Note: The last version of the above code can be found on GitHub: pre-push-check-untracked

When you then try to push with some untracked source files, i.e. files matched by the regex pattern which can be configured via git config hooks.prepush.sourcepattern, you’ll see output like this:

  1. # to show the current status, note the untracked bar file which is not included as a source file
  2. $ git status
  3. On branch master
  4. Your branch is up-to-date with 'origin/master'.
  6. Untracked files:
  7. (use "git add <file>..." to include in what will be committed)
  9. CMakeLists.txt
  10. bar
  11. foo/
  13. nothing added to commit but untracked files present (use "git add" to track)
  15. # now try to push something
  17. $ git push
  19. ERROR: Preventing push with untracked source files:
  21. CMakeLists.txt
  22. foo/asdf.h
  24. Either include these files in your commits, add them to .gitignore
  25. or stash them with git stash -u.
  27. error: failed to push some refs to '/tmp/repo'

Happy hacking!


This is a very good idea. Wed, 08/13/2014 - 22:04 — Anonymous

This is a very good idea. Thanks for sharing it!

Nice one! :) Fri, 08/08/2014 - 22:35 — Anonymous

Nice one! :)

Post new comment

  • You can use Markdown syntax to format and style the text. Also see Markdown Extra for tables, footnotes, and more.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <pre>.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options