【发布时间】:2010-11-03 22:29:09
【问题描述】:
有没有办法在 Git 中签出新分支后触发挂钩?
【问题讨论】:
有没有办法在 Git 中签出新分支后触发挂钩?
【问题讨论】:
如果这些钩子中的一个不能做到这一点,我会感到惊讶:
https://schacon.github.io/git/githooks.html
也许this one:
结帐后
当一个 git-checkout 之后运行 更新了工作树。钩子是 给定三个参数: previous HEAD,新 HEAD 的 ref (可能会或可能不会改变), 和一个标志,指示是否 结帐是一个分支结帐 (更改分支,flag=1)或文件 结帐(从 索引,标志=0)。这个钩子不能 影响 git-checkout 的结果。
【讨论】:
post-checkout 钩子也适用于 git switch,而 post-switch 钩子没有(从 git 2.25 开始)。
git hook 是放置在存储库的特殊位置的脚本,该位置是:
.git/钩子
脚本可以是您可以在您的环境中执行的任何类型,例如 bash、python、ruby 等。
结帐后执行的钩子是post-checkout。来自文档:
...钩子被赋予三个参数...
示例:
创建钩子(脚本):
touch .git/hooks/post-checkout
chmod u+x .git/hooks/post-checkout
Hook 示例内容:
#!/bin/bash
set -e
printf '\npost-checkout hook\n\n'
prevHEAD=$1
newHEAD=$2
checkoutType=$3
[[ $checkoutType == 1 ]] && checkoutType='branch' ||
checkoutType='file' ;
echo 'Checkout type: '$checkoutType
echo ' prev HEAD: '`git name-rev --name-only $prevHEAD`
echo ' new HEAD: '`git name-rev --name-only $newHEAD`
注意:第一行的shebang表示脚本的类型。
这个脚本(git hook)只会捕获传递的三个参数,并以人性化的格式打印出来。
【讨论】:
name-rev 只给出按字母顺序排在第一位的名称。因此,在签出一个名称按字母顺序位于原始分支名称之前的分支后,prev HEAD 行将给出新分支的名称。解决方法:thisBranchName=$(git rev-parse --abbrev-ref HEAD); for branch in $(git branch --color=never --contains $1 | sed -e 's/^..//'); do if [ "$(git show-ref -s $branch )" == $1 ] && [ "$branch" != "$thisBranchName" ]; then parentBranchName=$branch; break; fi; done
chmod u+x .git/hooks/post-checkout 部分让我受益匪浅。
post-checkouthook接收三个参数:
0) 还是分支检出 (1)您可以利用从当前 HEAD 创建的分支将具有相同的参数 1 和 2 值这一事实。
cat > .git/hooks/post-checkout <<"EOF"
if [ "$3" == "0" ]; then exit; fi
if [ "$1" == "$2" ]; then
echo "New branch created. (Probably)."
fi
EOF
chmod u+x .git/hooks/post-checkout
限制:
【讨论】:
与其他类似,但验证分支已签出一次。
#!/bin/bash
# this is a file checkout – do nothing
if [ "$3" == "0" ]; then exit; fi
BRANCH_NAME=$(git symbolic-ref --short -q HEAD)
NUM_CHECKOUTS=`git reflog --date=local | grep -o ${BRANCH_NAME} | wc -l`
#if the refs of the previous and new heads are the same
#AND the number of checkouts equals one, a new branch has been created
if [ "$1" == "$2" ] && [ ${NUM_CHECKOUTS} -eq 1 ]; then
git push origin ${BRANCH_NAME}
fi
【讨论】: