Git rebase 合并多次提交
在一般研发管理流程中,我们一般都是这么使用Git版本的:
- 0、先拿到一个需求(不细谈需求前面的采集、归纳整理、确认及评审等环节)
- 1、从主分支checkout一个新分支
- 2、在完成阶段性的目标后,提交代码
- 3、完成整体需求后自测,并提测,提测内容包含当前分支代码
- 4、通过测试后,代码合并到主分支
- 5、新建tag,按照tag发布代码,系统上线
整个流程没有什么问题,只是在git管理时,会在git的提交记录中看到每一次的提交,使得主分支的版本比较多,在特殊情况下,进行代码回溯及比较时,弄得头晕眼花。
Git提供reabse命令,可以将多次commit合并成一个提交,这样提交记录看起来比较简洁些。
没有rebase的示例
开发改需求时,先checkout出了一个新分支feature_connectLimit_20201119
,使用git log或者IDEA查看某需求的提交记录,如下图
从上到下对应的revision number如下表
9e1a88efb9cad48a46a1103a6920d752afca3513
9a32e0bc33c8d31bb6d9f2150af247aa784df14d
9fa7517460aac5c8d3e617be0e8c92d3e0570926
d1fcf3db8a49207a065624295121b903d06bec64
d0096d69986a70ea7911dd521fcfafcd7dad13e0
2fe0e3f1ac36d6299bb2618394d0d73ab79e17c7
37a19607401bbe929884ae36d34f0df450754692
合并到主分支(main)时,如果不进行处理,就会在主分支看到6条commit,如下图
以上还是比较乐观的情况,主分支只需要fast-forward到最新commit即可。如果发生冲突,再进行merge后,版本图表就不是一条简简单单的直线了。
rebase示例
git 提供了reabase命令,可以将(连续的、关联性的)多次commit合并成一个新的commit,再重新合并到主分支。
我们将2fe0e3f1~9e1a88ef这6个commit合并成一个新的commit。
具体看以下命令:
git checkout feature_connectLimit_20201119
git rebase -i 37a19607
其中,-i 的参数是不需要合并的 commit 的 hash 值。
进入到vi的编辑模式,
pick 2fe0e3f1a --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
pick d0096d699 呼叫记录:插入时检查重复
pick d1fcf3db8 呼叫记录:根据redis插入时检查重复
pick 9fa751746 --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
pick 9a32e0bc3 代码还原
pick 9e1a88efb 调整缓存key
# Rebase 37a196074..9e1a88efb onto 9fa751746 (6 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
可以看到其中分为两个部分,上方未注释的部分是填写要执行的指令,而下方注释的部分则是指令的提示说明。指令部分中由前方的命令名称、commit hash 和 commit message 组成。
根据命令注释,我们很容易知道 pick 和 squash 这两个命令的大概意义。
pick 的意思是要会执行这个 commit
squash 的意思是这个 commit 会被合并到前一个commit
我们将 d0096d699~9e1a88efb 这5个 commit 前方的命令改成 squash 或 s,然后输入:wq以保存并退出,如下
pick 2fe0e3f1a --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
s d0096d699 呼叫记录:插入时检查重复
s d1fcf3db8 呼叫记录:根据redis插入时检查重复
s 9fa751746 --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
s 9a32e0bc3 代码还原
s 9e1a88efb 调整缓存key
这时我们会看到新的commit message 的编辑界面,大概列举了要合并的commit的log信息。
# This is a combination of 6 commits.
# This is the 1st commit message:
--story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
# This is the commit message #2:
呼叫记录:插入时检查重复
# This is the commit message #3:
呼叫记录:根据redis插入时检查重复
# This is the commit message #4:
--story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
# This is the commit message #5:
代码还原
# This is the commit message #6:
调整缓存key
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Fri Nov 20 19:08:02 2020 +0800
#
# interactive rebase in progress; onto 37a196074
# Last commands done (6 commands done):
# squash 9a32e0bc3 代码还原
# squash 9e1a88efb 调整缓存key
# No commands remaining.
# You are currently rebasing branch 'feature_connectLimit_20201119' on '37a196074'.
#
# Changes to be committed:
...file lists
输入新的提交信息,this is a rebase test for many times commit;
,并:wq保存退出。再次查看 commit 历史信息,你会发现这些commit已经合并了。
这是合并的commit的提交信息:
合并到主分支后,也只有一条commit,这些清爽多了。