恢复发散的历史,然后收敛回购
Restore history of divergent, then convergent repo
我正在努力恢复代码库的历史。我已经恢复了我的 git 存储库的 ,现在发现了一个新的并发症。
一大块代码被拆分到一个单独的代码库中一段时间...然后合并回来。
Main repo: A -- B -- C -- D -- E
| ^
Code moved: | |
V |
Other repo: X -- Y -- Z
发生拆分(和合并)时,文件被简单地复制到目标存储库中,历史记录丢失了。
更复杂的是,文件在提交之前对每个副本都进行了轻微修改,因此我可能需要额外提交这些更改。
这引出了两个问题:
是否可以用较低的分支 (X-Y-Z
) 替换提交 D
(将文件复制回来)? (这是我的首要任务。)
如果可能的话,是否也可以恢复在提交 X
时创建的文件的历史记录?
"other" 回购中有大约 300 次提交,从 D
开始,"main" 回购中有大约 5000 次提交。
我怀疑可能需要 git-rebase
,但理想情况下,我想利用 git-filter-branch
这样我就不必手动解决历史合并冲突。
您可能想要设置一些 git replace
-ments 来手术式地改变/拼接历史,而不更改任何现有提交的 内容。然后按照我们在其他地方讨论过的方法进行 filter-branch,使这些替代移植物成为永久性的。
因为 git replace
允许您用 object 替换 Git 通常 "see" 原始的地方,并且因为提交具有 parent 提交 ID,您可以用多个提交链替换单个提交。例如,如果提交 X
在某些 well-defined 方面是 "bad":
...--o--P--X--Q--o--...
然后我们构造一个新的 "good" 提交序列 G1 ... Gn:
...--o--P--X--Q--o--...
\
G1--G2--...--Gn
(其中 G1 的 parent 提交 ID 是 P
,这是我们错误的 X
提交的 parent ; 如果 X
需要,或值得,多个 parents,我们可以将所有这些设置为良好的提交 G1)。然后我们用Gn指示Git到"replace"X
,这样遍历是这样的:
...--o--P--X- [replaced] -Q--o--...
\ /
G1--G2--...--Gn
过滤后,X
完全消失,提交 Q 并随后以通常的 filter-branch 方式复制到它们的新副本。
要构建 "good" 提交,您可以从字面上 git checkout -b tempbranch <P>
然后开始提交,但如果您需要设置多个 parent,这会有点棘手(你可以使用 git commit-tree
而不是普通的 git commit
,或者通过创建 .git/MERGE_HEAD
来作弊)。你可能想要回溯新的 "good" 提交,and/or 设置任意作者(git commit
有这些的命令行开关,git commit-tree
让你使用神奇的环境变量)。
我正在努力恢复代码库的历史。我已经恢复了我的 git 存储库的
一大块代码被拆分到一个单独的代码库中一段时间...然后合并回来。
Main repo: A -- B -- C -- D -- E
| ^
Code moved: | |
V |
Other repo: X -- Y -- Z
发生拆分(和合并)时,文件被简单地复制到目标存储库中,历史记录丢失了。
更复杂的是,文件在提交之前对每个副本都进行了轻微修改,因此我可能需要额外提交这些更改。
这引出了两个问题:
是否可以用较低的分支 (X-Y-Z
) 替换提交 D
(将文件复制回来)? (这是我的首要任务。)
如果可能的话,是否也可以恢复在提交 X
时创建的文件的历史记录?
"other" 回购中有大约 300 次提交,从 D
开始,"main" 回购中有大约 5000 次提交。
我怀疑可能需要 git-rebase
,但理想情况下,我想利用 git-filter-branch
这样我就不必手动解决历史合并冲突。
您可能想要设置一些 git replace
-ments 来手术式地改变/拼接历史,而不更改任何现有提交的 内容。然后按照我们在其他地方讨论过的方法进行 filter-branch,使这些替代移植物成为永久性的。
因为 git replace
允许您用 object 替换 Git 通常 "see" 原始的地方,并且因为提交具有 parent 提交 ID,您可以用多个提交链替换单个提交。例如,如果提交 X
在某些 well-defined 方面是 "bad":
...--o--P--X--Q--o--...
然后我们构造一个新的 "good" 提交序列 G1 ... Gn:
...--o--P--X--Q--o--...
\
G1--G2--...--Gn
(其中 G1 的 parent 提交 ID 是 P
,这是我们错误的 X
提交的 parent ; 如果 X
需要,或值得,多个 parents,我们可以将所有这些设置为良好的提交 G1)。然后我们用Gn指示Git到"replace"X
,这样遍历是这样的:
...--o--P--X- [replaced] -Q--o--...
\ /
G1--G2--...--Gn
过滤后,X
完全消失,提交 Q 并随后以通常的 filter-branch 方式复制到它们的新副本。
要构建 "good" 提交,您可以从字面上 git checkout -b tempbranch <P>
然后开始提交,但如果您需要设置多个 parent,这会有点棘手(你可以使用 git commit-tree
而不是普通的 git commit
,或者通过创建 .git/MERGE_HEAD
来作弊)。你可能想要回溯新的 "good" 提交,and/or 设置任意作者(git commit
有这些的命令行开关,git commit-tree
让你使用神奇的环境变量)。