假设我有一个文件,可能已经存在于Git仓库中,并且它可能存在于多个路径下,甚至在同一个提交中。
如何找到所有包含与该文件对应哈希值的blob的提交,并列出每个提交中文件所在的路径名?
是否有一种按哈希查找文件的技术,也可以搜索索引和工作目录?
假设我有一个文件,可能已经存在于Git仓库中,并且它可能存在于多个路径下,甚至在同一个提交中。
如何找到所有包含与该文件对应哈希值的blob的提交,并列出每个提交中文件所在的路径名?
是否有一种按哈希查找文件的技术,也可以搜索索引和工作目录?
好的,进一步解释被接受的答案…
如果要找到所有包含路径名的提交,那么被接受的答案中的脚本唯一没有为您完成的就是打印路径名。但不用担心,这很容易修改。
如果您进入附近的Git存储库并运行git ls-tree -r HEAD
,您会看到该命令转储由命名提交(在我们的情况下为HEAD
)引用的整个树层次结构,其中包括SHA-1名称和“常规”文件名。答案中的脚本只是使用grep
搜索此输出以查找SHA-1名称并忽略其余部分。
因此,我们可以将其修改为:
#!/bin/sh
obj_name="$1"
shift
git log "$@" --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
git ls-tree -r "$commit" | while read _ _ sha name; do \
if [ "$sha" == "$obj_name" ]; then
echo "$sha\t$name"
break
fi
done
done
现在,它还将打印与目标blob关联的文件名称以及提交名称。
git ls-tree -r <commit>
显示的路径名是相对于此提交所在存储库的根目录,这是我认为很自然(实际上也是唯一可能的)的事情。你期望的是什么?或许透过你的期望,问题会更加清晰明了。 - kostix-r
标志确实使 ls-tree
输出路径(不仅是基本名称)。但是,为了找到所有出现的情况,难道您还需要 --full-tree
选项吗? - lionel我猜你可能可以在这里找到答案这里(重复)。
总结:
git rev-list <commit-list> | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <SHA1> && echo X"
--all
代替<commit-list>
来查看所有提交。
git hash-object -w filename
命令,它 a) 实际上将文件内容转换为一个 blob;b) 将其写入对象存储(如果尚未存在);c) 打印 blob 的 SHA-1 名称。然而,唯一的区别在于,blob 只包含数据,通常被压缩,并且没有与之相关联的元数据。 - kostix