Git – 从SHA1中find一个文件名

我添加了一个文件索引:

git add somefile.txt 

然后我得到了这个文件的SHA1:

 git hash-object somefile.txt 

我现在有一个SHA1,我想使用SHA1检索索引中的对象的文件名。

 git show 5a5bf28dcd7944991944cc5076c7525439830122 

该命令返回文件内容,但不返回文件的名称。

我如何从SHA1获取完整的文件名和path?

在git中没有这样的直接映射,因为文件的名称是包含文件的树对象的一部分,而不是文件内容的blob对象的一部分。

从SHA1哈希中检索文件名是不正常的操作,所以也许你可以扩展一个真实世界的用例呢?

如果您正在查看当前文件(即HEAD提交),则可以尝试以下操作。

 git ls-tree -r HEAD | grep <SHA1> 

如果你想在以前的提交中find内容,你需要做更多的事情。

 git rev-list <commit-list> | \ xargs -n1 -iX sh -c "git ls-tree -r X | grep <SHA1> && echo X" 

伟大的一行来做到这一点:

 git rev-list --objects --all | grep <blob sha1> 

下面的shell脚本主要基于哪个提交有这个blob? 以及亚里士多德·帕加尔提斯所提供的答案。

 #!/bin/sh obj_hash=$1 # go over all trees git log --pretty=format:'%T %h %s' \ | while read tree commit subject ; do git ls-tree -r $tree | grep "$obj_hash" \ | while read ab hash filename ; do if [ "$hash" == "$obj_hash" ]; then f=$filename echo $f break fi if $f ; then break; fi done if $f; then break; fi done 

我确定有人可以美化这个脚本,但它确实有效。 这个想法是看所有的树木,并search你的具体散列。

git rev-list <commit-list>不会包含任何被rebase -i删除的提交,现在只被reflog引用,所以如果blob没有被上面的命令find,你也应该检查一下reflog,例如:

 git reflog --all | \ cut -d\ -f1 | \ xargs -n1 -iX sh -c "git ls-tree -r X | grep <BLOB_SHA> && echo X" 

提交文件并记下提交对象的sha1哈希值。 之后使用

 git ls-tree <commit-sha1> 

你将得到与哈希文件的名称。

检查手册页以获取更多选项。