有没有一种简单的方法,可以逐个推送功能分支上的所有提交(从master
开始),使每个提交都触发远程端的推送钩子?
这对于“测试优先”场景非常有用,因为您首先实现并提交失败的测试,然后再进行修复。
我知道我可以执行git push sha:remote-ref-name
,但手动操作很麻烦。
#!/bin/bash
if [ ! -d .git ]; then
echo "$(basename $0): not a git directory." 1>&2
exit 1
fi
# lbranch - name of local branch
# remote - name of remote
# rbranch - name of remote branch
lbranch=$(git rev-parse --abbrev-ref HEAD)
remote=$(git config branch.${lbranch}.remote)
rbranch=$(git config branch.${lbranch}.merge)
rbranch=${rbranch/refs\/heads\//}
for rev in $(git rev-list --reverse ${lbranch} --not --remotes);
do
git push ${remote} ${rev}:${rbranch}
done
#!/bin/bash
for rev in $(git rev-list --reverse origin/master..HEAD);
do
git push -f origin ${rev}:master
done
..
符号,省略了--not --remotes
并使用了强制推送。这些修改中哪一个使它对你起作用了? - krlmlrfor
语句时,只列出了三个提交,而我比主分支领先约200个提交(从SVN转换而来)。如果我回忆起来,当我手动尝试时,Git要求使用-f
。 - darda我不确定这对于测试优先的场景有什么好处,除非你指的是通过一次提交触发构建, 你实际上会看到构建失败然后成功。
话虽如此,你可以通过在服务器端使用更好的钩子脚本来达到你想要的效果。
post-receive
钩子脚本接收旧的 sha1 和新的 sha1,因此您可以计算其间的修订列表:
$ git rev-list OLD_SHA1..NEW_SHA1
这将包括从合并中带入的单个提交。您可以根据工作流程决定是否需要单独测试它们,因为它们可能已经经过测试。因此,您可以使用以下命令仅限于主干提交:
$ git rev-list --first-parent OLD_SHA1..NEW_SHA1
然而,还有一些特殊情况:
分支可能被变基。您是否要重新测试在分支先前版本中存在的新变基提交?
该分支可能是新的。但您不想重新测试整个分支的历史记录。那么,您用哪个分支来确定已经测试过什么了呢?master
?
该分支可能被删除。这种情况很容易...您可能什么也不需要做。
这里是在post-receive
钩子中读取更新的引用的示例:
#!/bin/bash
# The current working directory will be in the bare repo being updated.
while read oldrev newrev refname
do
# Skip deleted branches.
if [ "$newrev" != "0000000000000000000000000000000000000000"]
then
if [ "$oldrev" == "0000000000000000000000000000000000000000"]
then
# New branch. Test all commits in the branch by using master
# as a base. If this was master being created, then nothing will
# get triggered.
oldrev=$(git merge-base master $newrev)
fi
for sha1 in $(git rev-list ${oldrev}..${newrev})
do
# Tip off build server for each commit between oldrev and newrev
tip-off-build-server $sha1
done
fi
done
$refname
(它是引用的完整名称,而不是缩写版本)。 您可能需要对此进行一些修改以适应您的构建服务器。x
个提交时,您可能不希望采用此方法。 想象一下拉入另一个项目的历史记录。 它可能有数千个提交,您可能不希望在这种情况下单独测试它们。 当分支分歧并计算需要测试的修订版时,也可能存在一些问题。 您需要更加彻底地测试以确保它表现出您想要的行为。git rev-list
,其中$newrev
将是您本地分支的当前末尾。$oldrev
可能会采用master
(或develop
)或@{upstream}
如果之前已经推送了该分支。重点是您可以使用git rev-list
来帮助列出要推送的提交列表,然后逐个推送。我不建议这种方法,但它是可行的。rev-list
和githooks的参考是最有用的),但它可能对其他人有用,或者在未来的问题中对我有所帮助。非常感谢! - krlmlr
git push ref:remote-branch
语法并避免使用reset --hard
? - krlmlrgit push origin SHA1:REMOTE_BRANCH
命令即可(正如我在我的答案中所建议的)。 - John Szakmeisteripush
,类似于imerge
;-) - krlmlr