Triggering post-checkout hook after “git checkout -b” command

我的未来我决定 提交于 2021-02-08 10:28:32

问题


Same question was asked here before however both answers didn't help me much.

I couldn't get my post-checkout hook to differ git checkout from git checkout -b command as $1 (sha1 of previous HEAD) and $2 (sha1 of new HEAD) are same for both calls.

Here is my post-checkout script:

#!/bin/bash

echo "old HEAD: $1"
echo "new HEAD: $2"
echo "checkout type: $3"

I executed following commands:

> ozgur@ozgurv:~/project (master)$ git checkout -b new_branch
old HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
new HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
checkout type: 1

> ozgur@ozgurv:~/project (new_branch)$ git checkout my_branch
old HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
new HEAD: e86423aa9f45053cb45b8ec15d463bb9684526a2
checkout type: 1

What I am trying to achieve is to execute the logic in post-checkout hook only when a new local branch is created, not when it is checked out.


回答1:


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.



来源:https://stackoverflow.com/questions/33643299/triggering-post-checkout-hook-after-git-checkout-b-command

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!