我想确定远程 git 存储库(来源)是否包含特定提交。我的用例如下:
我正准备创建一个公开版本。我想包含代表原始代码库的提交的 SHA-1,我从中构建版本。
我还想确保提交不仅仅是本地提交,而且它实际上已被推送到中央存储库(来源)。
我认为
git pull --all & git branch --contains commit-hash
然后检查输出以查看它是否包含当前分支的跟踪分支,可以工作,但看起来相当麻烦。我正在寻找更简洁的东西,例如
git remote --contains origin commit-hash
或 git cat-file origin commit-hash
。我认为 Git 在确定推或拉过程中需要传输哪些对象时必须使用一些管道命令 - 我只是对内部结构不够熟悉。
感谢您的帮助。
怎么样:
git fetch && git branch -r --contains <commit-id>
我可能也忽略了一些管道,但据我所知,测试 commitA 是否是 commitB 的祖先的最直接方法是检查
git merge-base commitA commitB
是否为 commitA
。首先获取,然后因为它们可能是分支,所以使用 rev-parse 获取 commitA 的 SHA1:
if [ "$(git rev-parse $commitA)" == "$(git merge-base $commitA $commitB)" ]; then ...; else ...; fi
将其包装在别名中,您就应该被设置了。
至于推送和获取(拉)期间,这些是用 C 实现的,因此它们不会直接调用任何公开的管道命令。
git fetch
+ git branch -r
是你能得到的最好的。
您可以破解 git 协议 来给出此结果,但据我所知,没有可以使用的管道。详细信息请参见第 5 节。只需破解“have”命令并检查服务器是否NAK即可。
一个更简单的黑客就是尝试推送该提交,看看服务器是否需要它。
可以从正在审查但尚未合并的 gerrit 分支中看到它吗?获取后, git 分支 --all --contains 将列出所有分支,但是,审阅页面上的提交不会显示。
如果任何分支包含提交,建议的解析分支的解决方案
git fetch && branch -r --contains <commit-id>
将解决该问题。
如果任务是在存储库中的任何位置(例如在隐藏的引用中)查找提交,则它将不起作用。
自版本 v2.33.0 git 已记录
--negotiate-only
fetch 参数以查看远程存储库是否知道提交。当提交已知时,它会出现在命令行输出中:
$ git fetch origin --negotiate-only --negotiation-tip=60fadf8bd2abe6bede48bcf42377f6c8b7c1d0bb
60fadf8bd2abe6bede48bcf42377f6c8b7c1d0bb
如果我创建一个新的提交,对于服务器来说是未知的,这是通常和协商获取的输出:
$ git commit -m 'Empty commit' --allow-empty && git rev-parse HEAD
[master f14208fc92] Empty commit
f14208fc9259f8704bded1f7f80ac01dded55553
$ git fetch origin --negotiate-only --negotiation-tip=f14208fc9259f8704bded1f7f80ac01dded55553
e09f1254c54329773904fe25d7c545a1fb4fa920
$ git fetch origin f14208fc9259f8704bded1f7f80ac01dded55553
From github.com:git/git
* branch f14208fc9259f8704bded1f7f80ac01dded55553 -> FETCH_HEAD