我遇到了一个git问题,需要在我的pre-receive中运行"git --no-pager diff --name-only {oldrev} {newrev}"
命令以比较两个commit之间的差异,但是当oldrev为"000000000000000000000000000000000000000000"时,会出现错误的对象错误。请问如何解决这个问题?
我遇到了一个git问题,需要在我的pre-receive中运行"git --no-pager diff --name-only {oldrev} {newrev}"
命令以比较两个commit之间的差异,但是当oldrev为"000000000000000000000000000000000000000000"时,会出现错误的对象错误。请问如何解决这个问题?
git
因为提交记录不存在而将其报告为000[…]000
。这是一个刚创建且没有任何历史记录的分支/仓库的状态。因此,git diff 000[…]000..master
会给出错误提示,因为您想要比较的“提交”不存在。
在某些情况下,与空树进行比较可能会有所帮助:
git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904..master
这会给你一个包含当前 master
分支状态的差异。在这里,神秘的数字 4b825dc642cb6eb9a060e54bf8d69288fbee4904
只是空树的 SHA-1 值,根据定义它是一个真正的全局常量(感谢 @hvd 发现了该哈希值)。git
已经默认知道了这个空树,因此您不需要将任何内容提交到 git
中,它就可以正确地解析该哈希。
cmaster的回答向您展示了如何与空树进行差异比较,这可能是您想要在此处执行的操作。不过,值得注意的是,您的pre-receive钩子中的全零哈希值代表着什么。同样的“null hash ID”也会出现在update、post-receive和post-update钩子中。您应该根据实际情况处理这些内容。在处理钩子中的null-hash-ID时,没有单一正确的答案。
Git引用——分支名称、标签名称或任何可以通过git fetch
或git push
发送的名称——总是标识一个(1)对象(通常是一个提交对象,除了指向提交对象的注释标签对象)。如果引用是分支名称,则可能认为其他附加提交“在分支上”,更正确地说是从分支名称可达到。 (有关更多信息,请参见Think Like (a) Git。)另一种思考方式是提交包含在分支中:通常,一个特定的提交包含在许多分支中。(对于既不是分支名称也不是标签名称的名称,Git没有关于强制与非强制更新的内置规则 - 除非它使用分支规则来更新refs/notes/
名称空间;我没有为这个答案检查这一点。)
请注意,还有一种引用更新,即删除请求或命令。在这种情况下,另一个Git要求或命令你的Git删除一些引用。您的钩子将接收该引用的名称,其当前对象以及所有零哈希ID作为新ID,以指示其他Git正在请求或命令删除操作。
在 pre-receive 或 update 钩子中,您可以通过以零状态退出来允许操作,或通过以非零状态退出来禁止操作。pre-receive 钩子在其标准输入上一次性获取整个提案 - 所有创建、删除和更新。update 钩子逐个获取一个建议的更改作为参数。因此,pre-receive 钩子要么允许所有更新(然后可以在 update 钩子中逐个选择拒绝),要么禁止所有更新(使发起 git push 的人再试一次,可能使用较小的更新集)。
git gc
将它们丢弃。
4b825dc642cb6eb9a060e54bf8d69288fbee4904
是你要找的那个。这应该对 OP 有用作为一个答案,如果你把它发布为这样的话,我会很高兴点赞的。 - user743382