是否有一种简单的方法可以逐个推送功能分支的所有提交(例如,从master
开始),以便每个提交触发远程端的推送挂钩?
当您首先实现并提交失败的测试然后修复时,这对于“测试优先”场景非常有用。
我知道我可以做git push sha:remote-ref-name
,但手动做是很乏味的。
答案 0 :(得分:1)
我不确定为什么这对测试优先方案有好处,除非你的意思 是通过一次触发你的构建一个提交,你实际上会看到 构建失败然后成功。
也就是说,只需拥有一个更好的钩子脚本就可以得到你想要的东西
服务器端。 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
中更新了ref的名称(而且它是
ref的全名,而不是缩短版本)。你可能需要这样做
不知怎的,你的构建服务器。
这一切都取决于您的特定设置。如果你的构建服务器简单
轮询存储库的分支,然后您无法避免测试多个
一次提交。如果它在推动时倾斜,那么它不会太多
更进一步,使它更聪明。您可能需要更多逻辑。你可以
当推送中有超过x
次提交时,不想采用这种方法。
想象一下,拉进另一个项目的历史。它可能是成千上万的
提交,在这种情况下你可能不想单独测试它们。那里
当分支机构分歧并计算修订时,也可能存在一些问题
需要测试。你想要更彻底地测试一下
确保它表现出你想要的行为。
顺便说一下,githooks对于确定很有用 什么被传递到剧本。
您也可以在客户端进行单独推送,但不是没有
一些脚本。您可以使用类似于上面的git rev-list
,其中
$newrev
将是您当地分支的当前提示。 $oldrev
可以接受
master
(或develop
)或@{upstream}
,如果您之前推过了分支。
关键是你可以使用git rev-list
来帮助提交列表
推,然后逐个推动每一个。我不推荐这种方法,但是
它可以做到。
答案 1 :(得分:1)
此脚本应该有效:
#!/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
答案 2 :(得分:1)
@cforbish的提交列表没有做我认为提问者(和我)所需要的:从最旧到最新的顺序获取一个没有被推送的提交的列表然而。这对我来说很有把握(欣赏他的剧本的一般性,我通过硬连接某些东西来省略这些):
#!/bin/bash
for rev in $(git rev-list --reverse origin/master..HEAD);
do
git push -f origin ${rev}:master
done