🔥如何使用git rebase合并多次提交纪录

1,380 阅读4分钟

前言

如果遇到以下几个问题,可以考虑通过5分钟阅读,10分钟实践掌握解决方案

  1. 多人开发下,每个开发分支合并master时,携带了多个commit,导致master的提交记录杂乱无章
  2. master的提交记录信息太多,导致问题追溯不明确,团队期望保持线性的分支历史

我们可以利用git rebase来实现合并多次提交

如何合并多次提交纪录

基于上面所说问题,我们不难想到:每一次功能开发, 对多个 commit 进行合并处理。

这时候就需要用到 git rebase 。

合并多次提交

我们来合并最近的 3 次提交纪录,执行:

git rebase -i HEAD~3

编辑多次提交

这时候,会自动进入 vi 编辑模式:

pick 59f03e274 chore: 新增修改记录1
pick 89e501bb0 chore: 新增修改记录2
pick 57316860c chore: 新增修改记录3

# Rebase a63e7000f..57316860c onto a63e7000f (3 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 [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

有几个命令需要注意一下:

  • 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
  • d, drop = remove commit

按照如上命令来修改你的提交纪录:

p 59f03e274 chore: 新增修改记录1
s 89e501bb0 chore: 新增修改记录2
s 57316860c chore: 新增修改记录3

错误场景

如果保存的时候,你碰到了这个错误:

error: cannot 'squash' without a previous commit

注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。

4.如果你异常退出了 vi 窗口,不要紧张:

git rebase --edit-todo

这时候会一直处在这个编辑的模式里,我们可以回去继续编辑,修改完保存一下:

git rebase --continue

成功场景

如果保存成功,那么会跳到下一个界面,对commit进行操作

# This is a combination of 3 commits.
# This is the 1st commit message:

chore: 新增修改记录1

# This is the commit message #2:

chore: 新增修改记录2

# This is the commit message #3:

chore: 新增修改记录3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Mar 8 13:13:34 2022 +0800
#
# interactive rebase in progress; onto a63e7000f
# Last commands done (3 commands done):
#    squash 89e501bb0 chore: 新增修改记录2
#    squash 57316860c chore: 新增修改记录3
# No commands remaining.
# You are currently rebasing branch 'chore-rebase' on 'a63e7000f'.
#
# Changes to be committed:
#       modified:   README.md
#

我们需要在此处将多个commit的信息合并成一个,按如下进行:

# This is a combination of 3 commits.
# This is the 1st commit message:

- chore: 新增修改记录1
+ chore: 新增修改记录1-3

保存后即rebase成功

查看结果

git log

image.png 三次提交合并成了一次,减少了无用的提交信息

总结

  1. 自己开发的时候先从mastercheckout开发分支
  2. 正常使用git addgit commit
  3. 开发完使用git rebase -i head~N,N表示把自己的分支上相对于master新增的提交,全部rebase成一个commit,这样就是一个干净的commit
  4. 为了避免有其他同事提交了master,可以git rebase master ,处理冲突或者没有冲突后git push -f强推自己的分支,这里需要注意,一定要确保你的个人没有是只属于你个人的,没有任何开发者从你的个人分支切自己的个人分支,这也不被允许。
  5. 正常使用Merge Request合并代码,因为你开发分支已经是只有一个commit的提交,这样mastermerge你的代码后依然是一条直线的干净明确的提交记录