(二)连续多个提交合并成一个提交
在工作当中很可能会遇到一种场景,在编码的过程中,创建了很多的commit,当功能开发完成之后,发现之前有几个commit似乎可以合并在一起,这几个commit就是一个完成的功能,没有必要拆分成几个commit提交。
也就是整理历史提交的场景,把历史提交中的多个连续的commit,合并成一个commit。
注意:这个场景适用于本地,自己开发的过程中,还没提交打团队集成分支的时候。(不能用到团队的共享分支上,
git rebase
黄金法则。)
1、查看当前分支的日志情况
我们可以看到下面历史提交情况,发现最新生成的几个commit都是修改hello.html
文件的内容,那我们可以把这几个commit,合并成一个commit。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
dbdeba5 (HEAD -> master) 第6次提交,新增hello.html文件 v5
9a1342a 第5次提交,新增hello.html文件 v4
c90d574 第4次提交,新增hello.html文件 v3
d5fa1d1 第3次提交,新增hello.html文件 v2
5a5352d 第2次提交,新增hello.html文件 v1
69edafd 第1次提交,新增readme.txt文件 v1
2、执行commit合并(重点)
需求:把最近提交4个的commit合并成为一个commit。
说明:
- 我们用到的命令,还是
git rebase
命令。 - 我们要合并最新提交的4个commit,所以这个变基的基要选择第五个commit。
(1)执行$ git rebase -i 5a5352d
命令
进入到交互页面中,看看里边的内容。
pick d5fa1d1 第3次提交,新增hello.html文件 v2
pick c90d574 第4次提交,新增hello.html文件 v3
pick 9a1342a 第5次提交,新增hello.html文件 v4
pick dbdeba5 第6次提交,新增hello.html文件 v5
# Rebase 5a5352d..dbdeba5 onto dbdeba5 (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop = remove commit
# l, label
说明:在合并的提交中,必须有一个策略为pick
,意思是基于哪个提交合并,或者说这几个提交合到哪个commit上。
注意:上图中的四个commit,从上到下,越上commit的提交时间越早。
我们一般选择第一提交d5fa1d1
为pick,其他的提交都合在这个commit上。
(2)选择策略
其他被合并的commit,我们要选择一下他们的策略。用到的策略如下:
s, squash
这个策略就是我们要处理的场景。
-
use commit
:表示这些提交都要保留。 -
but meld into previous commit
:但是要把他合并到前面的commit里。
(3)编辑rebase
交互页面中的策略
编辑完成,意思是说把策略为s
的提交内容,合并到策略为pick
的提交当中去。
pick d5fa1d1 第3次提交,新增hello.html文件 v2
s c90d574 第4次提交,新增hello.html文件 v3
s 9a1342a 第5次提交,新增hello.html文件 v4
s dbdeba5 第6次提交,新增hello.html文件 v5
保存退出(:wq!
)。
(4)编辑rebase第二个交互页面
上边保存退出之后,会直接跳转到这个交互页面上。
如下:
# This is a combination of 4 commits.
# This is the 1st commit message:
第3次提交,新增hello.html文件 v2
# This is the commit message #2:
第4次提交,新增hello.html文件 v3
# This is the commit message #3:
第5次提交,新增hello.html文件 v4
# This is the commit message #4:
第6次提交,新增hello.html文件 v5
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sat May 1 17:50:22 2021 +0800
#
# interactive rebase in progress; onto 5a5352d
# Last commands done (4 commands done):
# s 9a1342a 第5次提交,新增hello.html文件 v4
# s dbdeba5 第6次提交,新增hello.html文件 v5
# No commands remaining.
# You are currently rebasing branch 'master' on '5a5352d'.
#
# Changes to be committed:
# modified: hello.html
#
这个交互窗口的意思是,把4个commit进行合并,让我们填写为什么要做这次变更,为什么要把这几个commit合并成一个提交。
该页面编辑如下:
# This is a combination of 4 commits.
修改hello.html文件内容
第3次提交,新增hello.html文件 v2
第4次提交,新增hello.html文件 v3
第5次提交,新增hello.html文件 v4
第6次提交,新增hello.html文件 v5
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sat May 1 17:50:22 2021 +0800
#
# interactive rebase in progress; onto 5a5352d
# Last commands done (4 commands done):
# s 9a1342a 第5次提交,新增hello.html文件 v4
# s dbdeba5 第6次提交,新增hello.html文件 v5
# No commands remaining.
# You are currently rebasing branch 'master' on '5a5352d'.
#
# Changes to be committed:
# modified: hello.html
提示:with '#' will be ignored, and an empty message aborts the commit.
的意思是:带#
号的表示备注,在提交的message中是不会出现的。
保存退出(:wq!
)。
如果Git执行完rebase
操作没有问题,就会显示如下信息:
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git rebase -i 5a5352d
[detached HEAD 840f01d] 修改hello.html文件内容
Date: Sat May 1 17:50:22 2021 +0800
1 file changed, 4 insertions(+)
Successfully rebased and updated refs/heads/master.
说明:rebase
操作已经成功,并且分支头指针,也指向了最新的commit。
(原理同上面应用,这里就不重复了)
(5)查看版本库历史提交记录
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
840f01d (HEAD -> master) 修改hello.html文件内容
5a5352d 第2次提交,新增hello.html文件 v1
69edafd 第1次提交,新增readme.txt文件 v1
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log
commit 840f01db9f204aff4543345d65b22cb68aee574c (HEAD -> master)
Author: sun_wk
Date: Sat May 1 17:50:22 2021 +0800
修改hello.html文件内容
第3次提交,新增hello.html文件 v2
第4次提交,新增hello.html文件 v3
第5次提交,新增hello.html文件 v4
第6次提交,新增hello.html文件 v5
commit 5a5352de6d0f1704133dbb2e667153f72dca9ba7
Author: sun_wk
Date: Sat May 1 17:49:57 2021 +0800
第2次提交,新增hello.html文件 v1
commit 69edafd3e11e4f3b8fea55eb0ff226824d4867fc
Author: sun_wk
Date: Sat May 1 17:46:43 2021 +0800
我们可以看到,最后四次提交合并为一个提交了。
3、补充:合并多个不连续的提交
假如我们需要合并的多个提交,并不是连续的。
同样的你也是要取得这几个提交中,最早一次提交的父commit-id,作为变基的基。
执行git rebase -i 父commit-id
命令,然后进入交互界面中,然后把你需要合并的目标提交放在最顶部(格式:pick commit-id XXX
,XXX就表示注释,可有可无),然后把其他几个要合并的提交编辑成s commit-id XXXX
,最后保存退出即可。(之后其他的步骤和上面同理,这里就不演示了。)