XY 问题
请注意,原始发布者有一个XY 问题,他试图弄清楚如何压缩他的旧提交(Y 问题),而他真正的问题实际上是试图减小他的 Git 存储库的大小(X 问题),如我在评论中提到过:
有很多提交不一定会使 Git 存储库的大小膨胀。Git 在压缩基于文本的文件方面非常有效。您确定提交的数量是导致您的大型 repo 大小的实际问题吗?一个更有可能的候选者是你有太多的二进制资产版本,与纯文本文件相比,Git 没有压缩(或根本没有)。
尽管如此,为了完整起见,我还将为Matt McNabb对 Y 问题的回答添加一个替代解决方案。
压缩(数百或数千)旧提交
正如原始海报已经指出的那样,--root
当有许多提交(数量为数百或数千)时,使用带有标志的交互式 rebase 可能是不切实际的,特别是因为交互式 rebase 不会在如此大量的提交上有效运行。
正如马特麦克纳布在他的回答中指出的那样,一种解决方案是使用孤立分支作为新的(压扁的)根,然后在此基础上重新设置基础。另一种解决方案是使用几个不同的分支重置来达到相同的效果:
# Save the current state of the branch in a couple of other branches
git branch beforeReset
git branch verification
# Also mark where we want to start squashing commits
git branch oldBase <most_recent_commit_to_squash>
# Temporarily remove the most recent commits from the current branch,
# because we don't want to squash those:
git reset --hard oldBase
# Using a soft reset to the root commit will keep all of the changes
# staged in the index, so you just need to amend those changes to the
# root commit:
git reset --soft <root_commit>
git commit --amend
# Rebase onto the new amended root,
# starting from oldBase and going up to beforeReset
git rebase --onto master oldBase beforeReset
# Switch back to master and (fast-forward) merge it with beforeReset
git checkout master
git merge beforeReset
# Verify that master still contains the same state as before all of the resets
git diff verification
# Cleanup
git branch -D beforeReset oldBase verification
# As part of cleanup, since the original poster mentioned that
# he has a lot of commits that he wants to remove to reduce
# the size of his repo, garbage collect the old, dangling commits too
git gc --prune=all
--prune=all
选项将git gc
确保所有悬空提交都被垃圾收集,而不仅仅是那些超过 2 周的提交,这是git gc
.