the*_*ine 9 git git-rebase squash
让我们说我的本地git log节目:
739b36d3a314483a2d4a14268612cd955c6af9fb a
...
c42fff47a257b72ab3fabaa0bcc2be9cd50d5c89 x
c4149ba120b30955a9285ed721b795cd2b82dd65 y
dce99bcc4b79622d2658208d2371ee490dff7d28 z
Run Code Online (Sandbox Code Playgroud)
我的遥控器git log显示:
c4149ba120b30955a9285ed721b795cd2b82dd65 y
dce99bcc4b79622d2658208d2371ee490dff7d28 z
Run Code Online (Sandbox Code Playgroud)
什么是最简单的方法(假设任意大量的本地提交):
527b5810cfd8f45f18ae807af1fe1e54a0312bce a ... x
c4149ba120b30955a9285ed721b795cd2b82dd65 y
dce99bcc4b79622d2658208d2371ee490dff7d28 z
Run Code Online (Sandbox Code Playgroud)
小智 17
如果A到X之间的中间提交数量相对较少,那么通过使用交互式变基可以很好地完成:
git rebase -i origin/master
Run Code Online (Sandbox Code Playgroud)
但是,根据我的个人经验,在大量提交中使用交互式变基很慢.我一次在大约一百次提交上运行交互式rebase(在使用Git Bash的Windows机器上),并且msysgit花了很长时间生成交互式rebase提交编辑器,允许您选择要运行的操作在哪个提交上,因为,列表最终变得非常大.
在这种情况下,您有几个解决方法.
git reset混合和软复位可用于修改工作树或临时区域(分别)以聚合/收集两个提交A和Y之间的所有更改,之后您可以一次提交所有修改作为单个提交.
我只举一个软复位的例子,因为它已经为你留下了所有的东西,而如果你使用混合复位,你将不得不进行修改:
# You don't need to create the temp branch A if you
# copy the commit sha A down somewhere so that you can remember it.
git branch temp A
git reset --soft Y
git commit -m "Squash commits A through X"
# Verify that this new commit is equivalent to the final state at A
git diff A
Run Code Online (Sandbox Code Playgroud)
另一种选择是简单地使用补丁.只需生成A到Y之间差异的差异补丁,然后将补丁应用为Y之上的新提交:
git diff y a > squash.patch
git checkout -b squash-branch y
git apply squash.patch
git commit -m "Squash commits A through X"
# Verify that this new commit is equivalent to the final state at A
git diff A
Run Code Online (Sandbox Code Playgroud)
正如@ABB在评论中指出的那样,如果涉及二进制文件,这将无法正常工作.git diff --binary除了文本文件之外,还可以用于为二进制文件输出diff,但我不确定那些diff是否也可以用作补丁.
一种选择是git rebase -i @{u}.我经常使用它,以至于我把它别名为git freebase(因为它适用于你可以自由变换的提交).
如果你不熟悉,@{u}是一个快捷方式@{upstream},或"当前分支的上游".