图解 Git 基本命令 merge 和 rebase
Git 基本命令 merge 和 rebase,你真的了解吗?
前言
Git 中的分支合并是一个常见的使用场景。
- 仓库的 bugfix 分支修复完 bug 之后,要回合到主干分支,这时候两个分支需要合并;
- 远端仓库的分支 A 有其他小伙伴合入了代码,这时候,你需要和远端仓库的分支 A 进行合并;
以上只是列举了分支合并的一些常见场景,关于 merge
和 rebase
命令你足够了解吗?
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
合并往往又被称为 「变基」,我称为 「基化」
图解 Git 基本命令 merge 和 rebase的更多相关文章
- Git Step by Step – (8) Git的merge和rebase
前面一篇文章中提到了"git pull"等价于"git fetch"加上"git merge",然后还提到了pull命令支持rebase模式 ...
- git之merge和rebase的区别
merge合并 # merge操作 第一步: # 先创建一个目录,在主分支提交3个txt文件 [root@luchuangao]# mkdir oldboy [root@luchuangao]# gi ...
- 关于Git的merge和rebase命令解析
git rebase是对提交执行变基的操作.即可以实现将指定范围的提交"嫁接"到另外一个提交智商. 其常用的命令格式有: 用法1:git rebase --onto <new ...
- Git分支merge和rebase的区别
Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 原理 如下: 假设你现在基于远程分支&quo ...
- Merge和Rebase在Git中的区别
git命令Merge和Rebase的区别 git merge 会生成一个新得合并节点,而rebase不会 比如: D---E test / A---B---C---F master 使用merge合并 ...
- git中的merge与rebase
之前一直对git的merge与rebase很困惑,而且一般也只使用merge而不是使用rebase.今天受高人指点理清了两者的区别. 首先对于两者而言,他们的结果是一样的,差异在于合并的方式(产生的结 ...
- git merge与rebase
参考这篇文章 Git 之 merge 与 rebase 的区别 文章2 另外,使 rebase出现冲突后,先修改冲突,然后git add 某文件(我使用add .经常有问题),然后git reba ...
- git代码合并:Merge、Rebase的选择
代码合并:Merge.Rebase的选择 Zhongyi Tong edited this page on Dec 7, 2015 · 3 revisions Pages 19 Home 2.1 快速 ...
- [git]merge和rebase的区别
前言 我从用git就一直用rebase,但是新的公司需要用merge命令,我不是很明白,所以查了一些资料,总结了下面的内容,如果有什么不妥的地方,还望指正,我一定虚心学习. merge和rebase ...
随机推荐
- 「MoreThanJava」计算机系统概述
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- Rocket - debug - TLDebugModuleInner - DMI Register Control and Status
https://mp.weixin.qq.com/s/tI41wu0xaIQ5PRq6F82tNw 简单介绍TLDebugModuleInner中生成DMI控制和状态寄存器使用到的状态. 1. abs ...
- Rocket - tilelink - toBools
https://mp.weixin.qq.com/s/UGMH8EoaVcFkkQW-l4HLWg 分析toBools在Intellij中显示为红色的问题. 1. 问题 在TLA ...
- Java实现 LeetCode 773 滑动谜题(BFS)
773. 滑动谜题 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换. 最终 ...
- Java实现 LeetCode 540 有序数组中的单一元素(位运算入门)
540. 有序数组中的单一元素 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数. 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 ...
- Android中StateListDrawable的种类(状态的种类)
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="ht ...
- C++实现网络寻路
标题:网络寻路 X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少 ...
- Java实现第十届蓝桥杯人物相关性分析
试题 H: 人物相关性分析 时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分 [问题描述] 小明正在分析一本小说中的人物相关性.他想知道在小说中 Alice 和 Bob 有多少次同 ...
- Linux文件处理命令 ls 详解
Linux系统的应用场景最多的就是用作服务器的系统了,简洁,安全,高效,一般我们服务器端不会安装Linux的图形化界面,虽然现在一些Linux发行版的图形界面也很漂亮,但是,服务器最主要的是高效.所以 ...
- 全网最全测试点总结:N95 口罩应该如何测试?
引言 随着”新冠疫情“慢慢地消散,各大企业都开始恢复正常的运行,因为疫情造成很多工作人员的流失,企业也开始疯狂的招聘新鲜的人才,这对于莘莘求职者无疑是个机会,但是因为求职者众多,很多面试官也开始想方设 ...