在一个类似主题验证提交是否存在中,他们建议:
git rev-list HEAD..$sha
如果未出现错误代码,则提交存在。
但仅仅为了验证而言,这样是否足够高效呢?
我在考虑这个选项:
git cat-file commit $sha
这对我的任务来说正确吗?还有其他的想法吗?
git cat-file -t $sha
命令并检查它是否返回"commit"。你是对的,你不需要实际打印该对象... 我不能100%确定背后发生的事情更有效率。使用命令test $(git cat-file -t $sha) == commit
。git cat-file commit $sha
,因为如果 $sha
不代表一个提交记录,它会返回一个错误,所以我不需要测试标准输出(在我的情况下,我还需要修剪它,因为它在 "commit" 的末尾添加了换行符)。 - skovalyov[[ $(git rev-parse --symbolic-full-name $sha) = refs/* ]]
。 - remramgit cat-file -e $sha^{commit}
来自于 git cat-file
的文档:
这表明了-e Suppress all output; instead exit with zero status if <object> exists and is a valid object.
cat-file
的一个预期用例,并避免了实际输出任何提交内容的资源消耗。(1)
添加^{commit}
可以确保对象是一个提交(即不是树或blob),或者-如remram所指出的那样-解析为提交。(2)
例如,if git cat-file -e $sha^{commit}; then echo $sha exists else echo $sha does not exist fi
^{commit}
表示解析为提交,而不是确保原始对象具有该类型。我的答案确保它是一个提交,尽管我不确定 OP 是否关心这个区别(他自己的版本与你的版本存在相同的问题)。 - remram$sha
是一个SHA-1哈希值,完整或缩写。如果$sha
实际上不是SHA哈希,而是任意标识符,则事情有些模糊,因为OP从未明确说明他是否想要解析标识符(就像在这个答案中)还是不想解析。 - Paul Draperif git cat-file... >& /dev/null
以避免将“fatal: Not a valid object name”输出到 stderr
。 - Joshua Goldberg如果提交存在,此命令的错误代码将为0,否则为1:
git rev-parse -q --verify "$sha^{commit}" > /dev/null
如果你想要更容易的阅读体验,可以添加&& echo "存在" || echo "不存在"
。
来自git rev-parse
文档:
作为奖励,如果您不抑制输出,您可以获得完整的sha。--verify Verify that exactly one parameter is provided, and that it can be turned into a raw 20-byte SHA-1 that can be used to access the object database. If so, emit it to the standard output; otherwise, error out. If you want to make sure that the output actually names an object in your object database and/or can be used as a specific type of object you require, you can add the ^{type} peeling operator to the parameter. For example, git rev-parse "$VAR^{commit}" will make sure $VAR names an existing object that is a commit-ish (i.e. a commit, or an annotated tag that points at a commit). To make sure that $VAR names an existing object of any type, git rev-parse "$VAR^{object}" can be used. -q, --quiet Only meaningful in --verify mode. Do not output an error message if the first argument is not a valid object name; instead exit with non-zero status silently. SHA-1s for valid object names are printed to stdout on success.
git rev-parse $committish
呢?(如果哈希值未找到,则会出现错误) - run_the_racegit rev-parse -q --verify HEAD^{commit}
似乎没有报错?所以我认为这并不能区分提交哈希和指向它们的东西。 - Ben Millwoodgit rev-parse --verify
似乎也可以接受任何完整的 SHA 哈希值。 - Ben Millwoodcat-file -e
,例如:if git cat-file -e $sha 2> /dev/null
then
echo exists
else
echo missing
fi
return !has_sha1_file(sha1);
否则,如果无法确定sha是提交对象,则需要像其他答案一样使用git cat-file -t
来确定类型。这只比git查看文件信息稍微慢一些,但不像解包整个文件那么耗费资源。
git rev-parse --verify
仅检查标识符是否为有效的哈希值。 git rev-parse --verify 1234567890123456789012345678901234567890
将始终返回 true。 - knittlgit rev-parse $sha
,但事实证明它会在任何有效的哈希值上成功退出。 - skovalyovgit rev-list HEAD..$sha
将检查 $sha 是否与 HEAD
相关。
git cat-file commit $sha
将检查 $sha 是否存在于仓库中。
因此,这将取决于您的用例。
一个需要第一种选项的用例是:检查上游是否有新提交。
# FETCH_HEAD = 2d9dbaa
$ git rev-list main..2d9dbaa
2d9dbaad0aad8e63b99235448c5aa4f82e9b1837
...
fb44705de992b19efd77af6e2f05e4fc1a79b568
$ git rev-list FETCH_HEAD..2d9dbaa
$ git cat-file -e 2d9dbaa && echo exists
exists
使用 rev-list
我可以验证 main
没有修订版本 2d9dbaa
,而 cat-file
无法帮助(因为修订版本存在于不同的分支中)。
git merge-base <commit> <the-same-commit> >/dev/null 2>&1
。如果没有2>&1
,它会给出很好的错误信息,无需进一步调整。 - Palec