以下场景:我有一个具有大量历史记录的存储库(从 2006 年以来使用的 SVN 迁移而来),并且希望将较新的历史记录推送到外部服务器。
我有一个标签,例如 mytag
,并且想要删除该标签之前发生的所有提交,但想要保留此后发生的历史记录> 这个标签。
我尝试像 Rebase many commits to one in Git. What am I doing wrong? 接受的答案中那样做,但这会导致无休止的冲突解决。
我只是想丢弃历史记录,同时能够将本地存储库(仍然保存大量历史记录) merge 到远程存储库(具有短历史记录)。
如何实现这一目标?
最佳答案
更新:请注意,在下面我假设 mytag
只有一个父提交,否则会有点复杂。
首先,我们假设您只有一个根提交,并且它是 f414f31
。 (如果您需要查找所有根提交,您可以使用 the first command in this answer 来完成。)
为了安全起见,我们为此操作创建一个新分支,这样您的分支 master
就保持原样,以防万一结果不符合您的预期。
git checkout -b new-master
将此分支重置为根提交:
git reset --hard f414f31
现在将工作树和索引更改为与 mytag
之前的提交相同:
git merge --squash mytag^
然后从索引创建一个提交 - 如果你想重写根提交,你可以使用 git commit --amend 来做到这一点,但我更愿意在你的提交之间保留一个共同的提交新旧历史,所以我会这样做:
git commit
现在您需要做的是重播自该提交以来(包括)mytag
以来的所有工作。这就是 git rebase 的目的,但默认情况下它将线性化您尝试重播的所有历史记录。如果自 mytag
以来历史记录中有许多 merge 提交,这可能是您看到许多冲突的原因。
因此,如果您不介意历史记录被线性化并且可以解决冲突(可能在 git rerere
的帮助下),您可以这样做:
git rebase --onto new-master mytag^ master
但是,如果该历史记录中有 merge ,并且您希望保留它们,则可以尝试添加 -p
(--preserve-merges
) 选项,它将尝试重新创建它们:
git rebase -p --onto new-master mytag^ master
您在下面的评论中询问了有关您有两个根提交的情况的进一步问题。在这种情况下,您可以选择其中之一,并在压缩 merge 后使用 git commit --amend 为重写的历史创建一个全新的根提交。
关于git - 压缩特定标签之前的完整历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6184014/