从本地检出的单个文件中查找提交哈希

阿莫尔

在我的Go项目中,我有本地制作https://github.com/HouzuoGuo/tiedot副本这可能是几年前手动完成的。

我无法告诉您检出了哪个版本/标签,因为任何地方都无法维护。

有什么办法可以从单个文件的哈希中找到提交哈希?例如,一些散列如下:

github.com/HouzuoGuo/tiedot/db> shasum *.go
79b42b7af9784255b39b4307950709880df4a86f  col.go
b5f5a127c990229e8ac085eb8e7c72d0e6617e1c  col_test.go
be45a7eae65803df2dc31e23db7eb27bcffa17cc  db.go
290c32d11498aacb0456117f2bffa8e7ab74ccd8  db_test.go
3d0e0dc06fbd8191b5d68b32b4ac4200444e98f2  doc.go
f15745867ccfcb8609194b617cc6e8911174dad9  doc_test.go
40fcd698a680b39bd8405b9bc62d0f4b99411cbf  idx_test.go
d1c481d7d75140b229440819bb21eb64095a7b35  query.go
c83114227dc59100de953ffceb4398e4d8a6075b  query_test.go

提交完毕后,可以使用类似的方法将其添加到go.mod文件中 go get github.com/HouzuoGuo/tiedot@<hash>

根据下面@torek的建议,我从github检出了代码,并编写了一个示例脚本来读取所有提交并检查其中一个文件的哈希是否匹配。但是,这不起作用。我想念什么?

COMMITS=$(git rev-list --all)

for COMMIT_HASH in $COMMITS
do
    TREE_HASH=$(git cat-file -p $COMMIT_HASH | grep tree | cut -d' ' -f2)
    if [[ -z "$TREE_HASH" ]]; then
        echo "Tree hash is empty"
        continue
    fi

    DB_DIR_HASH=$(git cat-file -p $TREE_HASH | grep '[[:space:]]db$' | awk '{print $3}')
    if [[ -z "$DB_DIR_HASH" ]]; then
        echo "db dir hash is empty"
        continue
    fi

    DBGO_HASH=$(git cat-file -p $DB_DIR_HASH | grep db.go | awk '{print $3}')
    if [[ -z "$DBGO_HASH" ]]; then
        echo "db.go hash is empty"
        continue
    fi

    if [[ "$DBGO_HASH" == "be45a7eae65803df2dc31e23db7eb27bcffa17cc" ]]; then
        echo "db.go hash matched!!!   Commit $COMMIT_HASH"
    fi
done
星期二

有什么办法可以从单个文件的哈希中找到提交哈希?

坏消息:不,因为提交哈希不仅取决于文件本身,而且还取决于提交的元数据。

好消息:您不需要这样做,因为您可以简单地从提交哈希到文件再往另一个方向发展也就是说,使用存储库的克隆,遍历提交图。对于过程中找到的每个提交,将保存的源快照与您关心的文件集进行比较。

编辑2:确保您使用的校验和是Git会使用的校验和,而不是运行shasum或任何类似命令生成的校验和也就是说,使用git hash-object命令来计算,你将搜索对象的哈希标识。(默认值是计算Blob哈希ID,因此您可以直接运行它git hash-object db/db.go。)

您可能会发现多个匹配项(这就是为什么它不可逆的原因):例如,也许v2.4.2v2.4.4两个匹配项都因为v2.4.3已损坏而错误已还原为make v2.4.4但这并不重要,只要结果对您有用即可。

要比较您关心的源的哈希值,请git ls-tree -r在有问题的提交上使用使用git rev-list枚举提交哈希标识。如果您有一棵完整的树,则可以通过计算树的哈希值并比较git rev-parse $commit^{tree}每个$commit的结果来加快处理速度,而不是比较文件的某些已知子集的所有文件哈希,但是这两种方法都应该非常快。

编辑:我不确定您的脚本出了什么问题,但这是一个更简单的变体:

git rev-list --branches |
while read commit; do
    h=$(git rev-parse --quiet --verify $commit:db/db.go) || continue
    if [ $h == be45a7eae65803df2dc31e23db7eb27bcffa17cc ]; then
        echo "db/db.go hash matched in commit $commit"
    fi
done

请注意,该文件可能需要多次提交!当我跑的这个变体的Git仓库GIT中,寻找哈希IDd2632690d5107b53ee8a7ac4832cd85eb8c7bfc1levenshtein.c,我得到了匹配18132个提交(这花了大约十几分钟,刚刚超过60000提交通过扫描)。但是,哈希ID可能没有提交:检查的一种快速方法是使用jthill的comment:中的选项(带有或其他)。如果至少出现了一次匹配,则至少有一次提交具有对象;该脚本将查找具有该对象的所有提交。git log --find-object=hash--all--branches

git rev-list --tags --no-walk在大约8秒钟内使用找到的181次提交:

$ time git rev-list --tags --no-walk | while read commit; do h=$(git rev-parse --quiet --verify $commit:levenshtein.c) || continue; test $h = d2632690d5107b53ee8a7ac4832cd85eb8c7bfc1 && echo "found in $commit"; done | wc -l
     181

real    0m7.810s
user    0m2.449s
sys     0m3.434s

没有脚本的同一件事在0.046s内找到772个带标记的提交,因此此脚本片段在我的旧Mac笔记本电脑上每秒处理约100次提交。(我用它来估算10分钟:我知道那很慢!)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从同一分支的未来提交中检出单个文件?

来自分类Dev

在Git中检出单个文件夹

来自分类Dev

您可以从git的将来提交中检出文件吗?

来自分类Dev

在svn中查找锁定文件而无需检出

来自分类Dev

在特定提交中获取文件的SHA哈希

来自分类Dev

使用特定文件名检出上一次提交中的所有文件

来自分类Dev

回购工具清单检出单个文件

来自分类Dev

Git:检出vs恢复单个文件

来自分类Dev

如何从正在运行的Docker映像中查找提交哈希

来自分类Dev

我需要从Bitbucket Git存储库中检出单个文件夹

来自分类Dev

SVN:如何检出存储库并清除本地存储库中的现有文件/目录

来自分类Dev

SVN:如何检出存储库并清除本地存储库中的现有文件/目录

来自分类Dev

从较早的提交中删除已在本地删除的提交文件

来自分类Dev

从较早的提交中删除已在本地删除的提交文件

来自分类Dev

GIT:在特定提交中查找文件

来自分类Dev

在 git 中查找提交文件的特定组合

来自分类Dev

如何通过文件哈希从git存储库查找文件修订或提交?

来自分类Dev

生成 CSV 文件的单个哈希

来自分类Dev

Git-从仓库中检出单个目录-错误:pathspec [目录路径]与git已知的任何文件都不匹配

来自分类Dev

git在单个提交文件中的单行上还原

来自分类Dev

如何从单个文件中的旧提交还原更改

来自分类Dev

git在单个提交文件中的单行上还原

来自分类Dev

Azure Pipelines查找传入合并的提交哈希

来自分类Dev

git stash pop:放弃单个文件中的本地更改

来自分类Dev

在RAD中检出vs劫持文件

来自分类Dev

git如何知道在哪个提交中检出子模块?

来自分类Dev

`git submodule update` 不会检出子模块中的提交

来自分类Dev

Git检出多个提交

来自分类Dev

检出与分支对应的提交

Related 相关文章

  1. 1

    如何从同一分支的未来提交中检出单个文件?

  2. 2

    在Git中检出单个文件夹

  3. 3

    您可以从git的将来提交中检出文件吗?

  4. 4

    在svn中查找锁定文件而无需检出

  5. 5

    在特定提交中获取文件的SHA哈希

  6. 6

    使用特定文件名检出上一次提交中的所有文件

  7. 7

    回购工具清单检出单个文件

  8. 8

    Git:检出vs恢复单个文件

  9. 9

    如何从正在运行的Docker映像中查找提交哈希

  10. 10

    我需要从Bitbucket Git存储库中检出单个文件夹

  11. 11

    SVN:如何检出存储库并清除本地存储库中的现有文件/目录

  12. 12

    SVN:如何检出存储库并清除本地存储库中的现有文件/目录

  13. 13

    从较早的提交中删除已在本地删除的提交文件

  14. 14

    从较早的提交中删除已在本地删除的提交文件

  15. 15

    GIT:在特定提交中查找文件

  16. 16

    在 git 中查找提交文件的特定组合

  17. 17

    如何通过文件哈希从git存储库查找文件修订或提交?

  18. 18

    生成 CSV 文件的单个哈希

  19. 19

    Git-从仓库中检出单个目录-错误:pathspec [目录路径]与git已知的任何文件都不匹配

  20. 20

    git在单个提交文件中的单行上还原

  21. 21

    如何从单个文件中的旧提交还原更改

  22. 22

    git在单个提交文件中的单行上还原

  23. 23

    Azure Pipelines查找传入合并的提交哈希

  24. 24

    git stash pop:放弃单个文件中的本地更改

  25. 25

    在RAD中检出vs劫持文件

  26. 26

    git如何知道在哪个提交中检出子模块?

  27. 27

    `git submodule update` 不会检出子模块中的提交

  28. 28

    Git检出多个提交

  29. 29

    检出与分支对应的提交

热门标签

归档