如何恢复删除历史记录的分叉的 git 历史记录?
How can I restore the git history of a fork where the history was deleted?
我有一个包含数百次提交的项目。它是另一个开源项目的分支。在创建分叉时,git 历史被擦除。现在我想重新附上历史。
原项目有数千次提交,称它们为:A <- B <- C <- D
与此同时,我们的分叉有:E <- F <- G <- H
分支不共享任何共同的祖先,但提交D
和E
具有完全相同的文件系统.创建 E
时,git 历史记录被擦除。
如何在不解决合并冲突的情况下重新附加它们?
我尝试过的解决方案:
git cherry-pick fork/initial..fork/develop
- 我尝试从 fork 中挑选更改到原始 repo,但这导致了合并冲突。该解决方案尝试线性重放提交,但是随着所有发生的分支和合并,一直存在合并冲突。
git rebase -i fork/initial fork/develop~0 --onto new-branch
- 不幸的是,Rebase 而不是 cherry-picking 存在与上述相同的问题。它会尝试按顺序重放提交,从而导致合并冲突。我也试过 --rebase-merges
无济于事。
git merge fork/develop --allow-unrelated-histories
-- 这是最接近我想要的。它仍然导致了大量的合并冲突(出于我不明白的原因?)但我用 git checkout fork/develop -- .
和 git commit
一次解决了它们。这个解决方案的问题是 fork 分支的“初始提交”仍然是接触每个文件的最旧提交,所以我没有得到合并这些分支的任何好处。
到目前为止我遇到的所有解决方案都需要我解决冲突。这不是必需的,因为我正试图在文件系统相同的地方附加历史记录。
我只想将历史重新附加到它的来源。有什么想法吗?
你可以试试这个
git rebase --onto D E H
那应该将 F、G 和 H 置于 D 之上……嗯,不完全是。当然,那些将是原始修订的复制品。也就是说,假设E..H是一条直线。
更新
我创建了一个脚本,可以在另一个修订版 之上复制分支的历史记录,而 实际上没有像 rebase 那样做任何 cherry-picking 。它使用来自原始修订的信息即时创建新修订。当然包括合并。
https://github.com/eantoranz/git/blob/replay/contrib/replay
单独使用它,因此,如果您想执行类似 git rebase --the-real-deal --onto new-base old-base tip
的操作,您可以执行:./replay new-base old-base tip
。来自问题中给出的示例:./replay D E H
。它在标准输出中打印的单行是您要求重播的 the tip
的等效修订的 ID。
我有一个包含数百次提交的项目。它是另一个开源项目的分支。在创建分叉时,git 历史被擦除。现在我想重新附上历史。
原项目有数千次提交,称它们为:A <- B <- C <- D
与此同时,我们的分叉有:E <- F <- G <- H
分支不共享任何共同的祖先,但提交D
和E
具有完全相同的文件系统.创建 E
时,git 历史记录被擦除。
如何在不解决合并冲突的情况下重新附加它们?
我尝试过的解决方案:
git cherry-pick fork/initial..fork/develop
- 我尝试从 fork 中挑选更改到原始 repo,但这导致了合并冲突。该解决方案尝试线性重放提交,但是随着所有发生的分支和合并,一直存在合并冲突。git rebase -i fork/initial fork/develop~0 --onto new-branch
- 不幸的是,Rebase 而不是 cherry-picking 存在与上述相同的问题。它会尝试按顺序重放提交,从而导致合并冲突。我也试过--rebase-merges
无济于事。git merge fork/develop --allow-unrelated-histories
-- 这是最接近我想要的。它仍然导致了大量的合并冲突(出于我不明白的原因?)但我用git checkout fork/develop -- .
和git commit
一次解决了它们。这个解决方案的问题是 fork 分支的“初始提交”仍然是接触每个文件的最旧提交,所以我没有得到合并这些分支的任何好处。
到目前为止我遇到的所有解决方案都需要我解决冲突。这不是必需的,因为我正试图在文件系统相同的地方附加历史记录。
我只想将历史重新附加到它的来源。有什么想法吗?
你可以试试这个
git rebase --onto D E H
那应该将 F、G 和 H 置于 D 之上……嗯,不完全是。当然,那些将是原始修订的复制品。也就是说,假设E..H是一条直线。
更新
我创建了一个脚本,可以在另一个修订版 之上复制分支的历史记录,而 实际上没有像 rebase 那样做任何 cherry-picking 。它使用来自原始修订的信息即时创建新修订。当然包括合并。
https://github.com/eantoranz/git/blob/replay/contrib/replay
单独使用它,因此,如果您想执行类似 git rebase --the-real-deal --onto new-base old-base tip
的操作,您可以执行:./replay new-base old-base tip
。来自问题中给出的示例:./replay D E H
。它在标准输出中打印的单行是您要求重播的 the tip
的等效修订的 ID。