裸露的接收后挂钩

时间:2019-08-20 14:48:32

标签: bash git git-bash

我有一个空库。我有一个非裸仓库。 在我的裸仓库中,我有以下内容:

git --work-tree=/C:/user/gitlab/data diff-tree --name-status -r master develop

在这里,我们在非裸仓库中拥有master和development分支 当我在工作树(非裸仓库)中运行它时,效果很好

在接收后将其放入我的裸仓库(/user/gitlab/shared.git/hooks)中时,它不起作用。

我尝试了以上内容。 我不知道如何精确地比较我的master分支和我的develop分支并显示其状态。

while read oldrev newrev ref
do 
      git --work-tree=/C:/user/gitlab/data/ diff-tree --name-status -r master develop
done

在非裸存储库上推送到裸存储库时,是否可以比较两个分支? (这是在提交文件后)

1 个答案:

答案 0 :(得分:0)

鉴于您正在使用裸存储库中的钩子,因此需要注意,您实际上从未比较过两个分支。无论您对 branch 一词使用哪个定义,这都是正确的(请参见What exactly do we mean by "branch"?)。您在这里与git diff-tree进行的真正比较是两个 commits 1

从根本上讲,像master(实际上是refs/heads/master)或v2.1(实际上是refs/tags/v2.1)这样的名称仅包含一个提交哈希ID。这是 a 哈希ID,就像一个唯一的哈希ID。有关一个哈希ID如何表示一个以上提交的信息,请参见链接的问题。

git diff系列中的那些想要查看 commit 的命令一样,会将名称转换为原始哈希ID,然后像输入原始哈希ID一样继续进行操作。因此,如果您运行:

git rev-parse master

并显示7c20df84bd21ec0215358381844274fa10515017,无论您在哪里写master,都可以写一个丑陋的哈希ID。 分支名称的特殊之处在于它们移动并自动执行—但是,当您处于接收前和接收后挂钩中时,您必须格外小心之所以这样,是因为它们移动时的很棘手。这就是为什么您应该使用如下循环:

while read oldrev newrev ref; do ...; done

这些循环读入三个项目:两个哈希ID和一个完整的引用名称。这两个哈希ID是引用的上一个值(以前是完整引用名的解析方式的哈希)和 new 值,即引用的哈希ID。参考将很快出现。最后一项是全名:refs/heads/masterrefs/tags/v2.1,依此类推。名称的前半部分告诉您名称是什么种类,去掉前半部分后,名称的其余部分就是分支,标签或其他名称。

pre-receive update 挂钩中,名称本身根本没有更改,因此名称应解析为旧哈希。您的工作是验证是否应允许这些建议的更新。在接收后挂钩中,名称本身已经更改。您应该使用哈希ID,而不是现在将名称解析为哈希ID,因为另一更改可能正在挂起或已经发生,具体取决于接收后挂钩本身的速度。

您在预接收或更新挂钩中生成的任何输出都将复制到正在执行git push操作的任何人中,该操作触发了挂钩。 (此输出将以单词remote:为前缀,并且在发送完整行之前不会显示。)在后接收挂钩中生成的任何输出都将被丢弃!如果要将其保存在服务器上,则必须将其发送到日志文件或日志服务或类似文件。

不需要--work-tree参数(使用一个参数可能是不明智的),但是您可能需要在预接收或更新挂钩中进行工作,并适当地使用原始哈希ID 。由您决定是否要更新refs/heads/master refs/heads/develop的值(如果建议更新这两个名称)。如果建议 git diff-tree refs/heads/master都不更新,则是否打印refs/heads/develop的结果也取决于您。


1 您可以直接比较树,并且git diff-tree的形式会产生两个以上树的 combined 差异,但是使用{{1 }},您可以很清楚地选择master developmaster的小费。