Reputation: 4877
Sometimes someone on our team does a git push and breaks the build because his local build works but he has forgotten to commit all his local modifications and untracked files to git before he pushes.
I'd like to prevent this... I poured over the docs for an hour or so today and couldn't find anything built in.
Does anyone have any solutions?
Upvotes: 8
Views: 3134
Reputation: 23624
You can use the pre-push
hook (since git 1.8.2).
Your pre-push hook could check the exit code of git status
, returning 0 (OK to push) if git status
returns non-zero, otherwise returning 1 (do not allow push).
The man page for git-status
says:
If there is no path that is different between the index file and the current HEAD commit (i.e., there is nothing to commit by running git commit), the command exits with non-zero status.
Any repo created with git 1.8.2 or later will have pre-push.sample
in the .git/hooks
directory, which is a useful starting point for implementing your policy. There are more good examples of using the pre-push
hook here: http://blog.ittybittyapps.com/blog/2013/09/03/git-pre-push/
Be aware that the hook does not run on the upstream repo. Each clone would need to have this hook installed, to enforce your policy. (Hooks are not cloned as part of the repository. As hooks are executed by git, this design prevents malicious hooks running on a developer's machine. Malicious code should instead go into a Makefile or configure script, which developers run without looking.)
Upvotes: 8
Reputation: 4877
I ended up adding an ant target to our local build before pushing to our main repo... here's the target... in case someone else was looking for a step in the right direction.
Thanks to all who answered.
<target name="git-status-check">
<echo>Performing git working directory check for local modifications or untracked files.</echo>
<exec executable="git" failifexecutionfails="true"
outputproperty="git.check">
<arg value="status"/>
</exec>
<echo>${git.check}</echo>
<propertyregex property="dirty.working.dir" input="${git.check}" regexp="working directory clean"
select="\1" casesensitive="false" />
<fail message="Git status reports that you have local modifications or untracked changes in your working dir... did you forget to commit these changes? ${line.separator} ">
<condition>
<not>
<isset property="dirty.working.dir" />
</not>
</condition>
</fail>
<echo>Git status reported a clean working dir continuing build...</echo>
</target>
Upvotes: 0
Reputation: 17314
Maybe put an alias, either in your shell or git config, that replaces the default push command with a custom script that does git status first and checks for "working directory clean"? I don't know if overwriting push is possible, or if it would make it so that you couldn't then call the real push. Just an idea off the top of my head, so I don't have any idea whether it really works.
Upvotes: 0
Reputation: 46228
To automatically add changes, you might want to look into using the -a
flag. From the git-commit
man page:
Tell the command to automatically stage files that have been modified and deleted, but new files you have not told git about are not affected.
There doesn't seem to be any flags for git commit
that adds untracked files. Remembering to do a git add .
before the commit is the best solution I can think of.
Upvotes: 0
Reputation: 95609
You can use the various hooks (pre-receive, I believe) to determine if the push will break the build and reject it. In addition to that, you should tell your developers to run git status
before any commit or push operation, which is an incredibly sensible rule to have in place and would deter such problems.
Upvotes: 2