在一个存储库上运行带有--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
1条答案
按热度按时间juzqafwq1#
git filter-repo
为旧的id添加替换引用。比如git replace --list
,这就是日志中的“(HEAD,replaced”标记所告诉你的。这允许重写提交消息中的文本引用解析为重写历史中的相应提交。您可以使用以下命令关闭替换查找: