恢复发散的历史,然后收敛回购

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 让你使用神奇的环境变量)。