从导出的仓库重建git哈希

时间:2013-11-15 18:07:17

标签: git

我有一个git repo(即:working目录)的内容,它被导出为tar.gz存档,我想验证存档真正对应的标记或提交。

我认为我不能一直回到提交,但我认为至少应该可以生成文件和树哈希,并尝试将其与现有提交相匹配。

我可以从概念上看到如何做到这一点,但是有没有类似的工具或脚本?

4 个答案:

答案 0 :(得分:0)

不知道有什么,但显而易见的解决方案是创建一个git目录并检查其中的内容。然后,阅读刚刚生成的提交中的tree

$ mkdir temp
$ cd temp
$ git init
$ tar xf ...
$ git add .; git commit -m 'just for hash'
$ git cat-file -p HEAD | awk '/^tree / { print $2 }' # or grep ^tree

不幸的是,这只会获得树ID(不是提交ID),但现在您只需检查“真实”仓库中的每个提交,以查看树是否匹配。如果是这样,那就是提交:

$ lookfor=$(git cat-file -p HEAD | grep ^tree)
$ cd /real/repo.git
$ for id in `git rev-list --all`; do
>     if git cat-file -p $id | grep -q "^${lookfor}$"; then
>         echo found: commit $id; break
>     fi
> done

然后使用git describe或其他任何东西将原始提交SHA-1转换为有用的名称。

答案 1 :(得分:0)

git filter-branch提供了很多机制来浏览树木清单;剩下要插入的是最佳匹配比较。您可以尝试简单地使用git status

例如,假设您在某处git识别或已正确设置GIT_DIR

$ git filter-branch --index-filter \
    'GIT_WORK_TREE=/path/to/archive git status --porcelain | wc -l'
Rewrite a2c4140ec0c94c31164ff44b6721ae2f2c83e5b3 (1/10)23
Rewrite e5fd02d47c4c1723b9c0e5ec787636c64c8e3c6b (2/10)22
Rewrite 74932cbcad41e9a001a4c841d3e16ac3376f21be (3/10)22
Rewrite 639f7944f3d9a49d995ddffd238b1e553e972898 (4/10)21
Rewrite 9784f3015d46107c900897f759a82dce9f64bf7e (5/10)16
Rewrite 30ced58105248343bd43c99f8d32790693640bc3 (6/10)12
Rewrite 07cba40558d16e24cb3cbc0fd8ab477ef2722df3 (7/10)12
Rewrite a0553b0608225c5c59f25d284ff1a57bb8040b94 (8/10)4
Rewrite 5438477bfd33a0e338fe58a126eef80e16108094 (9/10)3
Rewrite 60748e131596cf2999134e6506604f763cc3e238 (10/10)1

WARNING: Ref 'refs/heads/master' is unchanged

最低的数字将是比赛的一个很好的指标。就我而言,这是最后一次提交(HEAD)。使用当前版本的git filter-branch,它无法变为零,总会有一个./git-rewrite/内部使用文件。

注意:警告实际上是个好消息 - 我们不打算重写分支,它提醒我们在这个过程中我们没有弄乱任何东西。

答案 2 :(得分:0)

如果您的档案中有.git目录,这很简单。您已经拥有了历史记录,因为.git目录是完全运行的git存储库所需的全部内容。只需解压缩归档文件,然后按照通常的方式开始与git进行交互。

如果您没有.git目录,则无法为标记或提交重新生成任何哈希值,但您可以通过在untared目录中创建新的git存储库来重新生成文件和树的哈希值并提交所有文件。

git init
git add .
git commit

由于它们基于内容,因此文件的哈希值将在新存储库中显示相同内容。根据在原始仓库中创建目录的方式,树的哈希值可能会显示相同,但​​它们可能不会。然后,您可以使用git status之类的东西来比较原始存储库中提交的根树与新存储库中的提交的根树。

话虽这么说,如果您可以访问原始存储库,并且大致了解存档的创建时间,那么创建一个将检出提交,存档它们然后将它们与存档进行比较的脚本可能会更容易你想要匹配。这样做可能不会更快,但它会让脚本完成大部分工作而不是强迫你。

答案 3 :(得分:0)

在您导出的目录中:

git init
git add .
tree=`git write-tree`

在回购邮件中来自:

  

git log --all --format='%T %h' | grep $ tree

(或者你可以用它来完成它并做%T %h %Cgreen%d%Creset %s