如何对一系列提交使用git rebase -i命令?

28

我能否使用rebase压缩一个本地的feature/topic分支的一系列提交,而不包括最近的提交?这是为了准备在合并和推送到公共仓库之前的提交。

我快速地进行了工作,并进行了许多标题和描述不好的小更改,我想将它们压缩成两到三个逻辑提交并添加良好的注释。我可以选择一个范围的提交,从329aed9到af39283,这些提交可能在此功能分支的短历史中的任何位置。

git rebase -i RANGE_START_COMMIT_ID RANGE_LAST_COMMIT_ID
谢谢!

如果你正在使用vim(默认情况下Git使用vim),你可以使用可视块模式(ctrl-v)一次性将任意数量的picks更改为squashes。 - Cascabel
4
谢谢Jefromi。我最终弄清楚了如何使用vim选择和压缩。对于其他初学者,运行“git rebase -i mybranch~5”,其中5是要处理的最近提交的数量。如果你想让一个提交保持原样,那么将其前缀保留为“pick”。否则,请将其行前缀从“pick”更改为“squash”,然后rebase将把每个“squash”提交压缩到它上面标记为“pick”的第一个提交中。如果你有10个提交,并将3个保留为“pick”,其余的保留为“squash”,那么在rebase后,你将得到总共三个提交的结果。我会发布一张截图展示这个过程。 - Dylan Valade
下面的提交列表中的帮助不几乎就是这个意思吗? - Cascabel
1
是的,但从帮助中并不容易看出您可以在单个变基中使用 pick 来保留某些提交的原样,同时修改其他提交。至少对我来说,这是一个不连贯的地方,希望这能帮助其他人。 - Dylan Valade
2个回答

12

您可以使用git checkout -b new_branch af39283创建新分支,然后进行变基。但是,如果您想在将来的某个时间点包括稍后的提交,则无法避免将它们重新变基。提交的SHA1取决于所有祖先提交。


卡尔,谢谢你的建议。我没意识到可以根据SHA生成一个新分支,但我尝试了一下,很喜欢这个方法。如果我们要创建四个不同的Squash,则使用这种方法似乎会为最后三个Squash创建一个新分支。原始功能分支将被重新设置为第一个Squash。最后,其他三个“git checkout -b new_branch SHA#”将合并到原始功能分支中,从而创建一个完美无缺的分支。 - Dylan Valade
你是说你想要的最终结果是一个包含3个压缩提交和原始提交的分支?如果是这样,在执行rebase -i时弹出的提交列表中,你只需要将前几个压缩提交的pick更改为reword,选择其他所有内容的squash,并将未更改的提交保留为pick - Karl Bielefeldt
2
@Karl:你不需要重新编辑合并提交的第一次提交;Git会自动让你进行编辑,并提供所有合并提交的消息作为起点。 - Cascabel

2
因此,你所说的“不包括”最近的提交并不是完全清楚的,但是当你执行rebase -i时,你可以在不必对最后一个提交做任何事情的情况下压缩/重新排序/重新命名/修复/删除之前的提交。当然,你正在重写它下面的历史记录,因此它的差异将被重新应用,并且在重新基础之后,它将成为一个不同的提交对象,但是由于你还没有公开推送这个提交(而且你正在重写其余部分),这应该不会有太大影响。

感谢您的帮助。"not including" 的意思是我想要制作单独的压缩包,但保留最近的提交记录不变。最后一次提交很好,我希望它保持独立(不与其他提交记录合并)。然后有大约20个非常小的提交记录可以压缩成几个压缩的提交记录。最终,将大约60个小提交记录合并为4个合理的提交记录,以便合并到公共存储库中。 - Dylan Valade

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