是否有一种简单的方法来逐个推送所有提交的特征分支(从master
开始),以便每次提交都会触发一个推送远程方面? 当您首先执行并提交失败的测试,然后进行修复时,这对于“测试优先”场景很有用。单独推送一个分支的所有提交,一个接一个
我知道我可以做git push sha:remote-ref-name
,但手动操作很繁琐。
是否有一种简单的方法来逐个推送所有提交的特征分支(从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
我不确定为什么这对测试优先的场景很好,除非你的意思是通过触发你的构建一次提交,你会发现 构建失败,然后成功。
也就是说,只要有一个更好的钩子脚本 服务器端,你可以得到你想要的。该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
的提交时,您可能不想采取这种方法。想象一下拉动另一个项目的历史。它可能是成千上万的提交,并且您可能不希望在这种情况下单独测试它们。当分支分歧并计算需要测试的修订 时, 也可能是一些问题。您需要更仔细地测试一下 ,确保它展示您想要的行为。
顺便说一下,githooks对于确定 传递到脚本中的内容很有用。
你也可以在客户端进行个别推送,但不是没有 某些脚本。您可以使用类似于上述的git rev-list
,其中 $newrev
将是您当地分支的当前技巧。 $oldrev
可能采取 master
(或develop
)或@{upstream}
如果您之前推过分支。 关键是你可以使用git rev-list
来帮助提交到 的提交列表,然后单独推送每一个。我不推荐这种方法,但可以做到 。
不幸的是,推钩(实际上,在GitHub上的特拉维斯CI钩)不*完全*在我的控制下,所以我真的更喜欢客户端解决方案。否则,是的,我相信一个合适的服务器端钩子是一条可行的路线。 – krlmlr
这对于预先知道会非常有帮助。 – jszakmeister
对不起。然而,尽管大多数的文章都不能帮助我解决当前的问题(尽管对rev-list和githook的引用最为有用),但它对其他人可能会有所帮助,或者可以帮助我解决将来的问题。所以,非常感谢! – krlmlr
@ cforbish的承诺清单并没有做什么,我觉得提问者(和我)需要:获取一个列表,以便形成最旧到最新,提交的是还没有推到。这奏效了,我(他欣赏的脚本,我在这里省略通过硬连线的一般性的一些事情):
#!/bin/bash
for rev in $(git rev-list --reverse origin/master..HEAD);
do
git push -f origin ${rev}:master
done
这看起来不错,谢谢。任何你可以使用'git push ref:remote-branch'语法并避免'reset --hard'的机会? – krlmlr
@krlmlr你不需要创建一个新的分支,也不需要做任何重置。您只需循环并将各个SHA1推送到远程分支。正如你所建议的(和我在我的回答中建议的)类似'git push origin SHA1:REMOTE_BRANCH'。 – jszakmeister
@krlmr我已更新脚本以不创建新分支。 – cforbish