我使用以下命令将文件添加到索引:
git add somefile.txt
我随后使用以下命令获取了该文件的SHA1:
git hash-object somefile.txt
我现在有一个SHA1值,我想使用这个SHA1值从索引中检索对象的文件名。
git show 5a5bf28dcd7944991944cc5076c7525439830122
这个命令返回文件内容,但不包含文件名。
如何从SHA1中获取完整的文件名和路径?
在git中,没有直接的映射关系可以从SHA1哈希值中获取文件名,因为文件名是包含该文件的树对象的一部分,而不是文件内容的blob对象。
想要从SHA1哈希值中检索文件名并不是一个常见的操作,也许你可以提供一个实际使用案例来详细说明一下?
如果你正在查看当前文件(即HEAD提交),你可以尝试以下方法。
git ls-tree -r HEAD | grep <SHA1>
如果你想查找以前提交的内容,你需要做类似于这样的事情。
git rev-list <commit-list> | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <SHA1> && echo X"
<commit-list>
中输入什么, --all
会在代码库的所有分支中进行搜索。 - EoghanMgit ls-tree
只接受一个修订版本作为参数 (git v1.7.4.4)。我将你的版本改编成了 for rev in $(git rev-list --all); do git ls-tree -r $rev | grep $SHA; done | uniq
。 - Daniel Böhmerls-tree
都只需要一个修订参数,这就是为什么我在 xargs
中使用 -n1
的原因。 - CB Bailey有一个很棒的一行代码可以实现这个:
git rev-list --objects --all | grep <blob sha1>
git describe <sha1>
更好? - Harold#!/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 a b 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
git rev-list <commit-list>
不会包括任何被rebase -i
移除并且现在仅由reflog引用的提交,因此如果上述命令未找到blob,则应该检查reflog,例如:
git reflog --all | \
cut -d\ -f1 | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <BLOB_SHA> && echo X"
在另一个答案中,@Harold的评论得到了拓展。这个命令将会给你文件被引入的提交和该提交上文件的路径:
git describe --always <blob-hash>
测试于 git 版本 2.30.2。
提交文件并记录提交对象的sha1哈希值。之后使用
git ls-tree <commit-sha1>
然后您将获得带有哈希值的文件名称。
查看手册页面以获取更多选项。