我正在努力恢复代码库的历史记录。我已经恢复了我的git repo commits lost at the root,现在发现了一个新的并发症。
大量代码被分成单独的代码库一段时间......然后合并回来。
Main repo: A -- B -- C -- D -- E
| ^
Code moved: | |
V |
Other repo: X -- Y -- Z
当发生拆分(和合并)时,文件只是被复制到目标仓库中,历史记录丢失了。
为了进一步复杂化,在提交之前对每个副本稍微修改了文件,因此我可能需要额外提交这些更改。
这引出了两个问题:
是否可以使用较低的分支(D
)替换commit X-Y-Z
(将文件复制回来)? (这是我的首要任务。)
如果可能的话,是否可以恢复在提交X
创建的文件的历史记录?
“其他”仓库中有大约300个提交,而D
以后的“主要”仓库大约有5000个提交。
我怀疑git-rebase
可能是必需的,但理想情况下,我想使用git-filter-branch
,以便我不必手动解决历史合并冲突。
答案 0 :(得分:1)
您可能需要设置一些git replace
- 来手动更改/拼接历史记录,而不更改任何现有提交的内容。然后按照我们在别处讨论的那样进行过滤器分支,使这些替换移植物成为永久性的。
因为git replace
允许您在一个替换对象中替换Git通常会“看到”原始对象,并且因为提交具有父提交ID,所以您可以使用多个提交链替换单个提交。例如,如果提交X
以某种明确定义的方式“坏”:
...--o--P--X--Q--o--...
然后我们构造一个新的“好”提交序列G 1 ... G n :
...--o--P--X--Q--o--...
\
G1--G2--...--Gn
(其中G 1 的父提交ID为P
,这是我们的错误X
提交的父级;如果X
需要或值得,则为多个父母,我们可以设置所有那些好的提交G 1 )。然后我们指示Git用G n “替换”X
,以便遍历看起来像这样:
...--o--P--X- [replaced] -Q--o--...
\ /
G1--G2--...--Gn
一旦过滤,X
完全消失,提交Q,然后以通常的过滤器分支方式复制到新副本。
要构建“好”提交,你可以逐字git checkout -b tempbranch <P>
然后开始提交,但是如果你需要设置多个父项,这有点棘手(你可以使用git commit-tree
代替普通git commit
,或通过创建.git/MERGE_HEAD
并使用其余的额外哈希来作弊。你可能想要回溯新的“好”提交,和/或设置任意作者(git commit
有这些命令行开关,git commit-tree
使你使用魔法env变量。)