在没有克隆的情况下检查git revision是在origin / master之前吗?

时间:2018-01-19 13:51:48

标签: git continuous-integration continuous-deployment git-clone

我已经设置了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");

问题是这需要很长时间......

有没有更好的方法可以做到这一点而无需克隆?

我还应该提一下,构建发生在云服务器上,并在每次发布后都会被刷新并拆除。所以我们不能坚持回购。

1 个答案:

答案 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