乐趣区

关于程序员:Git代码合并之使用-rebase-整理提交历史

Git 代码合并之应用 rebase 整顿提交历史

Git 中整合来自不同分支的批改有两种形式:git mergegit rebase。本文次要介绍 rebase 的 3 种应用场景:

  1. 场景 1: 应用 rebase 合并分支 – 整合分叉的提交历史
  2. 应用 交互式的 rebase

    • 场景 2: 压缩提交历史
    • 场景 3: 批改多个提交信息

1 应用 rebase 合并分支

1.1 场景形容

咱们在 feature 分支开发完新的性能后,通常会通过 merge 操作将代码合并到 master 分支,这样会产生一条分叉。这时能够通过变基 使得提交历史更加整洁,看上去就像是串行的一样,提交历史是一条直线没有分叉。

1.2 操作命令

首先在本人的 feature 分支里进行开发,当开发实现时你须要先将你的代码变基到 master 上,而后再向 master 分支提交批改。这样的话,该项目标维护者就不再须要进行整合工作,只须要快进合并便可。具体操作如下:

# 1 变基到 master
git checkout feature
git rebase master

# 2 回到 master 分支,进行一次快进合并。git checkout master
git merge feature

1.3 原理图解

假如在你的我的项目上 master 分支的提交为 C0、C1、C2、C3,基于 masterC2 节点拉出了一个 feature 分支,并产生了新的提交C4,如下图:

整个变基操作的过程如下图所示,首先找到这两个分支(即以后分支 feature、变基操作的指标基底分支 master)的最近独特先人 C2,而后比照以后分支绝对于该先人的历次提交,提取相应的批改并存为临时文件,而后将以后分支(feature)指向指标基底 C3, 最初以此将之前另存为临时文件的批改依序利用,此时 feature 指向 C4',如下图:

最初回到 master 分支,进行一次快进合并,实现后 featuremaster 分支均指向 C4',如下图:

至此合并分支操作实现,master 的提交历史是一条洁净的、没有分叉的直线。

2 应用 交互式的 rebase

通过给 git rebase 减少 -i 选项来交互式地运行变基。个别被用于将 feature 分支并入 master 分支之前,清理凌乱的提交历史。

2.1 压缩提交历史

2.1.1 场景形容

感觉 commit 太小太散,将多个 commit 压缩成一个独自的提交。

2.1.2 操作命令

假如将 feature 分支以后最近的 3 个提交变为一个提交,操作如下:

# 1. 执行交互式 rebase
git rebase -i HEAD~3
# 或应用如下命令
git rebase -i dbcc8dd # dbcc8dd 为与 HEAD~3 对应的 commitid

# 2. 进入编辑器,将 16.md-2、16.md-3 的 pick 改为 squash,代表想要把它们跟上一个 commit(16.md-1)合并 
pick fe08362 feat: update 16.md-1
squash 72a7fae feat: update 16.md-2
squash f606aec feat: update 16.md-3

# 3. 第 2 步保留并退出编辑器后看到如下画面
feat: add file 16.md # 删除本来的 commit message, 改为本人想要的提交信息
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Aug 3 20:00:18 2022 +0800
#
# interactive rebase in progress; onto dbcc8dd
# Last commands done (3 commands done):
#    squash 72a7fae feat: update 16.md-2
#    squash f606aec feat: update 16.md-3
# No commands remaining.
# You are currently rebasing branch 'master' on 'dbcc8dd'.

# 4. 操作实现,验证后果
git log

留神上述第 2 步中的反序显示。交互式变基给你一个它将会运行的脚本。它将会从你在命令行中指定的提交(HEAD~3)开始,从上到下的顺次重演每一个提交引入的批改。它将最旧的而不是最新的列在下面,因为那会是第一个将要重演的。

2.2 批改多个提交信息

2.2.1 场景形容

批改在提交历史中的提交信息。

2.2.2 操作命令

例如要批改 feature 分支最近三次的提交中的任意一个提交信息。

# 1. 执行交互式 rebase
git rebase -i HEAD~3

# 2. 进入编辑器,将要被批改信息的提交由 pick 改为 reword,代表要批改 16.md- 1 的提交信息
reword fe08362 feat: update 16.md-1
pick 72a7fae feat: update 16.md-2
pick f606aec feat: update 16.md-3

# 3. 第 2 步保留并退出编辑器后看到如下画面
批改后的提交信息 feat: update 16.md-1 # 删除本来的 commit message, 改为本人想要的提交信息
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Aug 18 16:34:55 2022 +0800
#
# interactive rebase in progress; onto dbcc8dd
#...

# 4. 操作实现,验证批改后果
git log

2.3 其它的一些操作

除了 2.1、2.2 的应用场景外,交互式的 rebase 还能够 调整 commit 程序 删除 commit 等,操作过程与 2.1、2.2 大同小异,具体可参考如下指令:

# 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
# 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.

3 注意事项

应用 rebase 得恪守一条准则:

如果提交存在于你的仓库之外,而他人可能基于这些提交进行开发,那么不要执行变基。

换句话说,因为 rebase 变更历史记录,所以最好是在 push 之前就做好 rebase,不然就是确保要这个 branch 只有你本人在批改,否则你也 rebase、他也 rebase,最初只会把历史记录搞得一团糟。

4 参考资料

  1. Git 官网文档
  2. 送 PR 前,应用 Git rebase 來整顿你的 commit 吧!

GIT 宝典

网页查找不不便?想查看更多相干文章?微信扫码进入 –👉GIT 宝典 –,一键查找,解锁最及时的 Git 解决方案~!

退出移动版