wiki:GitTips

Automatically start commit messages with the branch name

You can use these two scripts to automatically put the branch name at the start of your commit messages. Not only does it make sure you don't forget this, it can also be a nice reminder of which branch you're committing to ;)

Create a file .git/hooks/prepare-commit-msg with the following contents:

#!/bin/sh

BRANCH=`git branch | grep '^\*' | cut -b3- | sed -e 's/^trac//'`
/bin/echo -n "[$BRANCH] " > "$1.msg"
cat "$1" >> "$1.msg"
cat "$1.msg" > "$1"

This will modify your default commit message to add the branch name.

Also create a file .git/hooks/commit-msg with the following contents:

#!/bin/sh

if diff "$1" "$1.msg" > /dev/null; then
	echo >&2 Aborting commit due to unchanged commit message.
	rm "$1.msg"
	exit 1
else
	rm "$1.msg"
fi

This will check if you have changed anything in the message, and abort if you have not (otherwise, to abort the commit, you'd have to delete the line we added in the previous script). It will also clean up the file we left in .git for this check.

Pushing only the current branch

Not sure if this has changed over versions, but at least for git 1.7.1, 'git push' without any arguments will push all branches with the same name upstream. This may result in rejection error messages if those branches have had updates upstream (and you have to fast-forward them first). You can set git to only push the current branch by setting the configuration option push.default to 'tracking':

git config --global push.default tracking

There are other options as well, see the manpage git-config.

Reviewing complicated branch with merges

If a branch contains a merge (eg. „sync with master“ or something like that) in the middle, it isn't easy to generate the diff of the branch (not because git would be stupid, it's just unclear what the diff should include). We can say that the diff would be the changes it would do to master if we merged it and we can ask for it just that way. Therefore we create a temporary branch, merge inside it and see the diff against the master parent.

git checkout origin/master -b temporary --no-track # The no-track is to prevent accidental push to master
git merge origin/trac<reviewed-branch>
git diff HEAD^

The HEAD^ means parent (first one, if there are more) of current commit on top of the branch and because master is the first parent in the merge commit, we view the changes on the edge between master and this merge.

After everything is reviewed, we can just delete the branch.

git checkout master
git branch -D temporary # -D forces the deletion, the branch is not merged and we lose commit this way (the temporary merge one)

If there are conflicts (or are expected), then the author of branch probably should merge master into his branch to solve them. Then the diff can be reviewed on that merge (the merge commit already exist, we don't need to create it). But because the master might have changed in between, we can't call git diff master, and it is the second, therefore git diff HEAD^ gives the other edge than we want, we would call the diff this way (the number after the carret means which parent we want):

git diff HEAD^2
Last modified 3 years ago Last modified on Apr 17, 2015, 11:42:12 PM