我已经设置了CI / CD系统,并且我正在尝试确保在发布任何内容之前,针对该版本存储的特定提交目前是在master之前。
目前我能找到的唯一方法是:
git clone -q https://$USERNAME:$PASSWORD@$GITREPOSITORYURL s
cd s
git checkout -q $revisionhash
git merge origin/master | grep "Already up-to-date." || (>&2 echo "You are behind master");
问题是这需要很长时间......
有没有更好的方法可以做到这一点而无需克隆?
我还应该提一下,构建发生在云服务器上,并在每次发布后都会被刷新并拆除。所以我们不能坚持回购。
答案 0 :(得分:0)
除非您用来托管遥控器的服务器提供一些高级查询功能(例如通过webapi),否则您将需要本地回购。这并不一定意味着一个完整的克隆,但你仍然只有有限的能力表达你想要它复制的git。此外,即使您确实要求有限的历史记录,我也不确定服务器实施是否有义务最大限度地减少网络流量,或者是否有一个聪明的"服务器可能会尝试向您发送包含您要求的所有内容的现有包(可能还有更多)。
因此,如果您确定release
至少包含一项不在master
内的提交,那么您可以启动一个地方
git clone --bare -b release --single-branch --shallow-exclude master -q https://$USERNAME:$PASSWORD@$GITREPOSITORYURL s
注意我已使用--bare
来取消默认结帐,因为您不应该为此而需要它,这可以节省一点时间。现在,这里的想法是,仅作为起点,仅获取发布分支中的提交,但master
中不。
"但是等等,你说,"为什么不相反?"毕竟,您正在尝试具体确定"是否在主服务器中提交但未在发布中提交"是空集;所以只是取这个,对吧?问题是,如果-b
参数中的引用可以从--shallow-exclude
参数中的ref到达,那么最终会提取完整的历史记录 - 这正是我们试图避免的。 (确切的推理可能只是积极的参考覆盖了否定参考,但结果是,如果排除会给你一个空集,你会得到一个完整的历史。)这就是为什么你这样做的原因。我想确切地知道release
至少有一个提交无法从master
发送。
(我玩了几种方法试图添加一个"支持",以便最多获取有限的历史;我无法使其工作,但我怀疑这可能反映了如何计算排除的错误。或者这可能是解释的问题。无论如何......)
好吧,如果您已经成功获取了发布分支,那么您需要的下一件事就是找到它的第一个提交。这是否应该起作用存在争议,但似乎在我的测试中:
git log --max-parents=0 --format="%H"
我说如果这应该有用是值得商榷的,因为你的克隆中的第一次提交并非真正根提交。提交对象仍然要列出其父ID(我们稍后会看到),但对于某些命令,git显然"不计数"这个父母(大概是因为它不在当地的回购中),我想我们可以在这里利用它。
现在你真正想要的是看到第一个提交的父ID,这就是忽略父级的git命令是一把双刃剑。因为
git log --format="%P" <first-commit>
没有工作;它表现得好像没有父母。所以我们可以
git cat-file -p $(git log --max-parents=0 --format="%H") |grep '^parent' |cut -c8-
从COMMIT
对象本身读取父哈希。
现在我们知道我们刚提取的ID是release
可以从master
到达的第一次提交的ID(因为&# 34;可以从master
&#34;到达,这是提交将从我们的克隆中排除的唯一原因)。我们还可以说,从master
可以访问的提交,可以从release
到达 last 。
所以我们的问题是:提交ID是否等于master
ref。
我们可以用
回答这个问题git ls-remote https://$USERNAME:$PASSWORD@$GITREPOSITORYURL |grep refs/heads/master$ |cut -c-40