在git filter-repo之后相同提交哈希的不同树哈希

ymdaylpp  于 2023-03-11  发布在  Git
关注(0)|答案(1)|浏览(190)

在一个存储库上运行带有--replace-text选项的git filter-repo之后,我注意到了这个异常,并且在一个更简单的示例中可以重现这个异常。
这似乎违反了git的一个基本原则,即如果两个提交有相同的提交哈希,它们就 * 是 * 相同的提交,因此树的内容和哈希应该是相同的。(除了一个极其不可能的冲突,无论如何,使用任意数据都不可能再现)。
重现步骤:从一个新的init艾德repo(在目录test_repo中)开始,它具有以下非常短的历史:

$ git log -p
commit 00fc46c3372592059ff63bc0dfb610d8e583fa3e (HEAD -> master)
Author: REDACTED
Date:   Thu Mar 9 10:04:38 2023 +0000

    second change

diff --git a/foo b/foo
index 8d5d568..243cf01 100644
--- a/foo
+++ b/foo
@@ -1,2 +1,4 @@
 initial
 
+zzzzz
+

commit 19f6a7da7e8d9ca30a644872167bd7f17c3b5f92
Author: REDACTED
Date:   Thu Mar 9 10:04:23 2023 +0000

    blah

diff --git a/foo b/foo
new file mode 100644
index 0000000..8d5d568
--- /dev/null
+++ b/foo
@@ -0,0 +1,2 @@
+initial
+

创建文本替换文件:复制文件:

zzz==>yyyy

克隆它并使用git filter-repo重写:

git clone . ../test_repo_mod
cd ../test_repo_mod
git filter-repo --replace-text ../test_repo/repl_file

替换没有影响初始提交,所以它保持相同的哈希值,但是第二次提交的哈希值不同。

$ git show
commit a2b5518f99f3a42d55931021e4a79c59f0971734 (HEAD -> master)
Author: REDACTED
Date:   Thu Mar 9 10:04:38 2023 +0000

    second change

diff --git a/foo b/foo
index 8d5d568..5d94489 100644
--- a/foo
+++ b/foo
@@ -1,2 +1,4 @@
 initial
 
+yyyyzz
+

然而,当我想引入旧历史时,事情变得很奇怪:

$ git remote add prefilter ../test_repo
$ git fetch prefilter
[output removed]

$ git log --graph --all  --pretty=format:'(%D) H:%H - T:%T' 
* (master) H:a2b5518f99f3a42d55931021e4a79c59f0971734 - T:0258b53a79efebb3a1a18fae2f5f2b26338bfaf8
| * (HEAD, replaced, prefilter/master) H:00fc46c3372592059ff63bc0dfb610d8e583fa3e - T:0258b53a79efebb3a1a18fae2f5f2b26338bfaf8
|/  
* () H:19f6a7da7e8d9ca30a644872167bd7f17c3b5f92 - T:6f3003a0d9bd438abda8b48741b0b0a68925dcfc

$ cd ../test_repo
$ git log --graph --all  --pretty=format:'(%D) H:%H - T:%T' 
* (HEAD -> master) H:00fc46c3372592059ff63bc0dfb610d8e583fa3e - T:179af78895dc9c453df9caa00ed83b7c5bb9a378
* () H:19f6a7da7e8d9ca30a644872167bd7f17c3b5f92 - T:6f3003a0d9bd438abda8b48741b0b0a68925dcfc

正如您所看到的,根据我在哪个存储库中查看它,带有哈希00fc46c3372592059ff63bc0dfb610d8e583fa3e的提交具有不同的树哈希(和不同的内容)。
git fsck没有显示错误,因此我认为不是git filter-repo损坏了数据。
增加:git cat-file输出:
我已经删除了我的名字+电子邮件,但每次都是一样的。

$ git cat-file -p 00fc46c3372592059ff63bc0dfb610d8e583fa3e
tree 179af78895dc9c453df9caa00ed83b7c5bb9a378
parent 19f6a7da7e8d9ca30a644872167bd7f17c3b5f92
author REDACTED 1678356278 +0000
committer REDACTED 1678356278 +0000

second change

过滤回购:

$ git cat-file -p 00fc46c3372592059ff63bc0dfb610d8e583fa3e
tree 0258b53a79efebb3a1a18fae2f5f2b26338bfaf8
parent 19f6a7da7e8d9ca30a644872167bd7f17c3b5f92
author REDACTED 1678356278 +0000
committer REDACTED 1678356278 +0000

second change
juzqafwq

juzqafwq1#

git filter-repo为旧的id添加替换引用。比如git replace --list,这就是日志中的“(HEAD,replaced”标记所告诉你的。这允许重写提交消息中的文本引用解析为重写历史中的相应提交。
您可以使用以下命令关闭替换查找:

git --no-replace-objects log --graph --all  --pretty=format:'(%D) H:%H - T:%T'

相关问题