如何通过SHA-1检查提交是否存在于Git仓库中

bfnvny8b  于 2023-03-28  发布在  Git
关注(0)|答案(5)|浏览(159)

在类似的主题Validate if commit exists中,他们建议:

git rev-list HEAD..$sha

如果它没有错误代码而退出,则提交存在。
但是,仅仅为了验证,它是否足够有效?
我在考虑这个选择:

git cat-file commit $sha

它是否适合我的任务,还有其他想法吗?

yiytaume

yiytaume1#

你可以运行git cat-file -t $sha并检查它是否返回“commit”。你是对的,你不需要为它打印实际的对象。
我不是100%确定幕后发生的事情更有效率。
test $(git cat-file -t $sha) == commit

eit6fx6z

eit6fx6z2#

git 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.

这(1)表明这是cat-file的预期用例,(2)避免了实际输出任何提交内容的资源。
追加^{commit}可以确保对象是一个提交(即不是一个树或blob),或者正如remram指出的那样,解析为一个提交。
比如说

if git cat-file -e $sha^{commit}; then
  echo $sha exists
else
  echo $sha does not exist
fi
dy1byipe

dy1byipe3#

如果提交存在,此命令的错误代码将为0,如果不存在,则为1:

git rev-parse -q --verify "$sha^{commit}" > /dev/null

如果你想更容易阅读,附加&& echo "exists" || echo "doesn't exist"
git rev-parse文档:

--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.

作为奖励,如果你不抑制输出,你可以得到完整的sha。

pvcm50d1

pvcm50d14#

如果你确定sha是commit,那么cat-file -e可以用于以下例子:

if git cat-file -e $sha 2> /dev/null 
then 
  echo exists 
else 
  echo missing 
fi

这是非常有效的,因为这是一个内置的,除了检查sha是否存在之外,不做任何事情:

return !has_sha1_file(sha1);

否则,如果不确定sha是否是commit对象,你就需要使用git cat-file -t来确定类型。这只是性能稍差,因为git必须查看文件信息。这不像解压缩整个文件那么昂贵。

zfciruhq

zfciruhq5#

git 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也没有帮助(因为修订版确实存在于不同的分支中)。

相关问题