跳过先前已处理的post接收挂钩中的Git修订的处理
我有一个git post receive钩子,它提取在“git推送”过程中添加的所有修订,并对每个修订进行一些处理(例如发送通知电子邮件)。这非常有效,除非在合并时;e、 g:跳过先前已处理的post接收挂钩中的Git修订的处理,git,git-post-receive,Git,Git Post Receive,我有一个git post receive钩子,它提取在“git推送”过程中添加的所有修订,并对每个修订进行一些处理(例如发送通知电子邮件)。这非常有效,除非在合并时;e、 g: 我在branch1上进行了一些提交,然后推动branch1。post接收钩子正确处理提交 我将branch1合并到branch2,然后推动branch2。post-receive钩子第二次处理所有合并的提交 我怎样才能避免这种情况?下面是post-receive钩子的开头,在这里我提取了应该处理的提交(在$commits
我们要做的是将先前处理的提交的散列保存在文本文件中。每次钩子运行时,它都会在该文件中检查给定的提交是否已被处理。如果它尚未处理该提交,请处理它,然后将该提交记录到文件中
这不是非常可伸缩的,因为文本文件只会随着更多提交添加到存储库而增长,并且检查给定提交的时间也会增长。我们通过让post receive钩子在遇到合并提交(具有两个或多个父级的提交)时停止处理来实现这一点。这需要在推动合并时遵守一些规则,以确保不会抛出其他“真正的”提交。规则是在合并之前总是推送,然后分别推送合并。看看
$(前缀)/share/git core/contrib/hooks/post receive email
,这正是(我认为)你想要的。基本上,它对每个ref使用git
来查找所有分支的名称,然后排除从某个分支(更新的分支除外)可以访问的每个提交:
if [ "$change_type" = create ]
then
# Show all revisions exclusive to this (new) branch.
revspec=$newrev
else
# Branch update; show revisions not part of $oldrev.
revspec=$oldrev..$newrev
fi
other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
grep -F -v $refname)
git rev-parse --not $other_branches | git rev-list --pretty --stdin $revspec
(我在这里简化了它,希望在我的剪切粘贴工作中不会损坏任何东西。这里的输入是:
$change\u type
是create
,如果$oldrev
都是零,否则它是update
;$oldrev
是最近从stdin读取的行中的旧版本SHA1;$newrev
是新版本HA1;$refname
是全名,例如,refs/heads/topic
)我在一个post接收钩子中完全实现了这一点。它只通知trac自上次获取以来的新提交,而不重复,无论新提交是同时推送到单个分支还是多个分支。此方法在git目录中保留一个名为trac\u HEAD
的文件以供tra使用正在检查已处理的提交
建议在启用挂钩之前,在.git
目录中运行cat refs/heads/*>TRAC HEAD
!/bin/sh
#
#仅读取并通知trac尚未处理的新提交。
#
#“接收后”脚本在接收包接受包后运行
#并且存储库已经更新。它是通过参数传入的
#格式中的stdin
#
#例如:
#aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814参考/页眉/母版
#
TRAC_PATH=“/PATH/to/TRAC/env”
#读取标准输入
在读取oldrev newrev refname;时
echo“处理分支:$refname”
#从TRAC_HEAD读取每个分支的最新修订
除外条款=$(cat TRAC|U HEAD | uniq | sed-e's/^/^/'-e's//^/g'| xargs echo)
回显“排除列表:$Exclutions”
git版本列表——在读取版本时撤销$newrev$排除项
trac admin$trac_路径变更集已添加“(默认)’$rev
echo“已处理:$rev”
完成
#将此分支的最新版本添加到排除文件中
echo$newrev>>跟踪头
完成
#更新TRAC_头文件
cat参考/头部/*>TRAC\u头部
改进此方法的一个方法是定期修剪文件,与您关于合并分支频率的政策保持一致。感谢您的回答。我将使用上面torek的解决方案,但您的回答也可以避免我在这里提到的剩余角落案例。不过,在文本文件中跟踪提交更为有效这比我现在要介绍的要复杂得多。多亏了这一点,它正好满足了我的需要。使用此代码,剩下的情况是,当您进行提交时,将其合并到另一个分支中,然后将两个更改同时推送到一起。在这种情况下,每个分支中的修订都可以从另一个分支访问,因此不会进行处理完全可以。但是,这对我们来说现在是可以接受的,因为这是一个相对少见的情况。有趣!如果你在pre-receive钩子中而不是post-receive中这样做,它可能会扫描这两次,因为两个ref都不会被更新。也许如果你在update钩子中这样做,它会只扫描一次?(显然,我自己没有试过。)
if [ "$change_type" = create ]
then
# Show all revisions exclusive to this (new) branch.
revspec=$newrev
else
# Branch update; show revisions not part of $oldrev.
revspec=$oldrev..$newrev
fi
other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
grep -F -v $refname)
git rev-parse --not $other_branches | git rev-list --pretty --stdin $revspec