压缩多个历史提交记录

4

我有大约20000个SVN提交记录的历史。我迁移到了Git并保留了该历史。现在我已经有26000个提交,我想将1到20000的所有提交压缩成一个。

  • 最初提交:a4f5d18
  • 迁移至Git:5a42d81
  • HEAD:933eff

我尝试检出第20000个提交,并进行变基:

git checkout 5a42d81
git rebase squash a4f5d18

但是我得到了:
fatal: Needed a single revision
invalid upstream squash
3个回答

3

如果你想保留多少次提交记录,请在下面的命令中指定该数字

git rebase -i HEAD~6000

更准确地说
git rebase -i a4f5d18

保留以下6000个提交记录(作为pick),将其余的pick更改为squash。
如果rebase成功。
 git log

您可以将所有提交压缩到一个提交中。

最好将更改推送到远程,否则当您再次拉取时,将会看到所有提交。

git push -f

OP可以直接使用a4f5d18代替HEAD~6000 - 1615903
@1615903 感谢分享,这可能会帮助其他人。 - ntshetty

3
如果我理解正确,您的主分支是这样的: master: 1 -> 2 -> 3 -> .. -> 20000 -> A (第一个未迁移的提交) -> B -> C -> .. 您想要达到的目标是: master: 1' (所有已迁移的提交) -> A' -> B' -> C' -> .. 我认为您可以采用使用git rebase HEAD~26000 (第一个提交哈希可能更容易)并将pick更改为squash的方法,但这可能有些琐碎/耗时。
一个潜在的可行方法是创建一个包含前20000个提交内容的新提交。可能值得在备份分支上进行测试。 git checkout <last migrated commit hash> -b backup-master
backup-master: 1 -> 2 -> 3 -> .. -> [20000] -> A (First non migrated commit) -> B -> C -> ..
                                       ^- you are here.

git reset --soft <first migrated commit hash>

backup-master: [1] -> 2 -> 3 -> .. -> 20000 -> A (First non migrated commit) -> B -> C -> ..
                ^- you are here         ^- the working directory tree/index reflects this commit 

修改您的初始提交内容/消息(或者如果您愿意,可以创建一个新的提交)。
`git commit --amend`
现在,`backup-master`应该包含您压缩的迁移提交,让我们移动新提交。
`git checkout master`
`git checkout -b master-rebase`(以防万一我们搞砸了)。
`git rebase backup-master` - 我相信这会起作用,因为Git知道成功重新定位所需的合并。如果这样做成功,那么`master-rebase`将包含您想要的结果。
如果失败,您可能会通过`rebase --onto`获得更好的成功率。
`git rebase --onto `
例如: `git rebase --onto backup-master ~1 master`
如果这样做成功,它将使您处于当前没有任何分支的提交上,因此您需要创建一个:
`git checkout -b rebase-success`。
有关rebase --onto的更详细解释,请参见
此处

1
谢谢,这正是我在寻找的方法,尽管实际的变基并没有更快,而且与交互变基解决方案不同,您无法看到其进度。注意:在软重置后,我不得不创建分支,因为这导致了一个脱离的头状态。 - Qeebrato
啊,这是个好点子,我忽略了reset步骤会让你的HEAD处于分离状态。更新了答案,在初始checkout步骤中添加了一个-b <branch> - Chris
@Chris 我按照你的方法操作,最后留下了两个历史记录。一个是从--root到master,另一个是从--root到rebase-success。这是否是预期的? - Candy Chiu
嘿,我好久没回答这个问题了,可能需要重新理清思路。你说的两个历史记录是什么意思?我认为本意是为了备份分支以防出现任何问题,但成功的变基应该是你想要的那个。 - Chris
@Chris,假设我们从一个分支开始,即主分支,它有26000次提交。经过一系列操作后,我成功地创建了一个名为rebase_successful的新分支,它包含6001次提交。主分支仍然存在,有26000次提交。我该如何将主分支指向这个新分支并删除原始的主分支? - Candy Chiu
哦,这个问题已经有点超出了本问题的范围,因为目前还不清楚你的设置是什么。如果只是你在独立的存储库上工作,你可以删除其他的“master”分支,并创建一个新的名为“master”的分支。或者你可以检查“master”,使用“重置”将头指向“rebase_successful”分支提示。如果你正在与其他人合作,就需要考虑更多的问题(因为你会影响共享历史记录)。 - Chris

0

我在三种情况下(交互式变基、软重置、变基到)都遇到了空格的问题。Git有嫁接分支的可能性,这发展成了替换功能:

git replace -f 5a42d81 a4f5d18
git filter-branch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接