You can't really tell the difference, in a post-checkout hook.1 In any case you might not want to try to tell the difference. Consider:
$ git branch newbr # make a new branch
$ git checkout newbr # and now check it out
It probably makes sense to do whatever you would have done for git checkout -b newbr
here, and if so, checking for the -b
flag (if you can get it to work) is probably counterproductive. (Consider as well git checkout feature
when origin/feature
exists and local branch feature
does not, which creates feature
as a new branch that tracks origin/feature
, even though again there is no -b
flag.)
Let's look at this again, and I'll suggest a different approach:
only when a new local branch is created
What if, in your hook, you kept a list of "all seen-so-far local branches" saved in a file? (Perhaps .git/ozgur/branchlist
would be a reasonable place to keep this. We want something that follows the repository around, that git itself is unlikely to use.) Then, if the checkout is a branch-style checkout ($3
is 1
), compare the current branch with the list:
git_dir=$(git rev-parse --git-dir) || exit 1
branchlist=$git_dir/ozgur/branchlist
if [ "$3" = 1 ]; then
# Checked out a branch - what branch are we on now?
# (Skip rest of code if we're on a detached HEAD.)
curbranch=$(git symbolic-ref --short HEAD) || return
# Is $curbranch in our branch list? Create empty
# branch list first if needed. Can just "touch" but
# this avoids changing the mod-time unnecessarily.
[ -f $branchlist ] || : > $branchlist
if ! grep "^$curbranch$" $branchlist > /dev/null; then
echo "switching to as-yet-unvisited-branch $curbranch"
echo $curbranch >> $branchlist # now we've visited it
fi
fi
This still has a bit of a flaw: if you delete a branch, it may remain in the branchlist file. We could fix that by filtering away deleted branches fairly regularly (compare the $branchlist
contents to appropriate git for-each-ref refs/heads
output), perhaps in additional git hooks as well. But it might suffice for your purposes as-is.
1Actually, there is a way to tell, at least on systems that will let you look at a process tree, and look at their command arguments. From the hook, find your parent git checkout
process and see if it has a -b
flag. But then it doesn't work on the two-step git branch ...; git checkout
sequence, nor on branches automatically created from an upstream branch.