图解 Git 基本命令 merge 和 rebase

图解 Git 基本命令 merge 和 rebase,第1张

图解 Git 基本命令 merge 和 rebase

Git 基本命令 merge 和 rebase,你真的了解吗? 前言

Git 中的分支合并是一个常见的使用场景。


  • 仓库的 bugfix 分支修复完 bug 之后,要回合到主干分支,这时候两个分支需要合并;
  • 远端仓库的分支 A 有其他小伙伴合入了代码,这时候,你需要和远端仓库的分支 A 进行合并;

以上只是列举了分支合并的一些常见场景,关于 mergerebase 命令你足够了解吗?

HEAD 的理解

在介绍本文的主要内容之前,我们先理解一下 HEAD


HEAD 指向当前所在的分支,类似一个活动的指针,表示一个「引用」。


例如当前在 develop 分支,HEAD 内容就是 ref: refs/heads/develop


HEAD 既可以指向「当前分支」的最新 commit,也可以指向历史中的某一次 commit (「分离头指针」的情况)。


归根结底,HEAD 指向的就是某个提交点。


当我们做分支切换时,HEAD 会跟着切换到对应分支。


fast-forward 与 --no-ff 的区别

假如有一个场景:有两个分支,master 分支和 feature 分支。


现在,feautre 分支需要合并回 master 分支。


fast-forward 合并方式是条件允许的情况,通过将 master 分支的 HEAD 位置移动到 feature 分支的最新提交点上,这样就实现了快速合并。


这种情况,是不会新生成 commit 的。


--no-ff 的方式进行合并,master 分支就会新生成一次提交记录。


如果条件满足时,merge 默认采用的 fast-forward 方式进行合并,除非你显示的加上 --no-ff 选项;而条件不满足时,merge 也是无法使用 fast-forward 合并成功的!

merge *** 作

上面用图解的方式介绍了 fast-forward--no-ff 的区别。


下面,结合实际的代码仓进行合并 *** 作,举几个栗子理解一下。


git merge *** 作是区分上下文的。


当前分支始终是目标分支,其他一个或多个分支始终合并到当前分支。


这个注意点记住了,方便记忆!所以,当需要将某个分支合并到目标分支时,需要先切到目标分支上。


fast-forward 合并

刚刚一直在强调条件允许的时候,fast-forward 才能合并成功。


条件指的是什么呢?

其实指的是源分支和目标分支之间没有分叉(单词 diverge),这种情况才可以进行快速合并。


如果是下图中的场景,无法通过 HEAD 的快速移动实现分支的合并!

下面进行一个不分叉的场景的示例:

现在需要将 feature 分支合入到 master 分支,默认使用 fast-forward 方式:

# 切到目标分支
git checkout master
git merge feature

命令行里显示了 Fast-forward 的提示:

看一眼 master 分支合入的前后对比(注意 HEAD 的位置):

no-ff 合并

不分叉的场景是否可以强制采用 --no-ff 方式合并呢?可以!

# master 回到合入前的状态
git reset --hard d2fa1ae
git merge feature --no-ff

这次命令行没有 Fast-forward 的提示了。


看一眼 master 分支图:

这个图和上面讲解 no-ff 命令时的示意图一致,果然会有新 commit 生成。


分叉场景的合并

上面的图展示了我们经常遇到的一个场景,特性分支创建之后,源分支也会有新的提交。


这就是形成分叉了。


这时候如果我们进行合并呢?

git merge feautre

可以看到,虽然默认会尝试 fast-forward 的方式进行合并,但是因为分叉了,所以此时会采用 no-ff 的方式进行合并!有新的 commit 生成了!

fast-forward 方式对应的合并参数是 --ff

我们试试这个参数 --ff-only,顾名思义,就是强制只使用 ff 方式进行合并:

# 回到合并前
git reset --hard 3793081
git merge feature --ff-only

经过测试,当分叉时,因为无法使用 ff 方式合并,即使你强制指定使用该方式合并也不行,会提示终止!

附上 Git 官方文档中的解释,方便理解:

With --ff, when possible resolve the merge as a fast-forward (only update the branch pointer to match the merged branch; do not create a merge commit). When not possible (when the merged-in history is not a descendant of the current history), create a merge commit.
rebase *** 作

rebase 命令是一个经常听到,但是大多数人掌握又不太好的一个命令。


rebase 合并往往又被称为 「变基」,我称为 「基化」

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/588374.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存