图解 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 ...
随机推荐
- Linux,Mac下MySQL的安装及一些知识点的整理
Linux下载安装 在服务器上下载的话,需要安装Mysql5.7相关的yum源 wget https://dev.mysql.com/get/mysql80-community-release-el7 ...
- Pycharm虚拟环境的使用
Pycharm虚拟环境的使用 pycharm创建项目的时候,一定勾选inhert global site-packages.不然系统的库就没法用了. 打开Project Interpreters页面: ...
- echarts的时间轴的提示内容写在轴下方
echarts的时间轴的提示内容写在轴下方 在echarts中横坐标的拖动轴dataZone的提示内容在两端,并且没有相关配置让其显示在轴下方或者其他位置. 解决方式: 在图标下方添加dom并且监听拖 ...
- Rocket - diplomacy - AddressAdjuster
https://mp.weixin.qq.com/s/X0s5CWN84GEiwpNR7tiRgA 基于AddressAdjuster介绍LazyModule的实现. 参考链接:https://g ...
- 从0开始探究vue-组件化-组件之间传值
理解 Vue中有个非常重要的核心思想,就是组件化,组件化是为了代码复用 什么是组件化 组件化,就像一个电脑主机里的主板,有内存条的插口,有硬盘,光驱等等的插口,我们的项目,就像一个电脑主机,通过各种组 ...
- ecilpse 纠错插件
在market里面搜索 Spot Bugs Unnecessary Code Detector
- Java实现 LeetCode 794 有效的井字游戏 (暴力分析)
794. 有效的井字游戏 用字符串数组作为井字游戏的游戏板 board.当且仅当在井字游戏过程中,玩家有可能将字符放置成游戏板所显示的状态时,才返回 true. 该游戏板是一个 3 x 3 数组,由字 ...
- Java实现 LeetCode 26 删除排序数组中的重复项
26. 删除排序数组中的重复项 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) ...
- java实现第四届蓝桥杯颠倒的价牌
颠倒的价牌 题目描述 小李的店里专卖其它店中下架的样品电视机,可称为:样品电视专卖店. 其标价都是4位数字(即千元不等). 小李为了标价清晰.方便,使用了预制的类似数码管的标价签,只要用颜色笔涂数字就 ...
- html页面引用video.js播放m3u8格式视频
//head里面的内容,我是采用cdn引用的方式,因为项目太小 <head> <meta charset="utf-8" /> <title>二 ...