分支合并的方法有两种:merge 和 rebase
本篇先讲解使用 merge
来合并分支的观念。
情境|想要使用 A 分支来合并 B 分支
步骤|
先切换到 A 分支(显示当前位於 A 分支上)
使用 git merge
指令
$ git merge B分支 # 合并 B 分支
🛠 实际操作
建立新的分支,并 Commit 两次。
$ git branch one # 新增一个 one 分支
$ git checkout one # 切换到 one 分支
// 重复动作提交第二次
$ touch hello.html # 新增一个档案
$ git add . # 加至暂存区
$ git commit -m"讯息记录" # 提交到储存库
任务:想要使用 master
分支来合并 one
分支
因目前在 one 分支上,因此先切回到 master 分支上。
$ git checkout master # 切换到 master 分支
执行合并分支 git merge
指令( master
合并 one
分支)
$ git merge one # 合并 one 分支
查看档案列表,确认先前新增的档案内容是否有在内
$ ls -al # 查看档案列表
master 分支上有 hello.html 与 hello2.html 档案了~
因为 master 将 one 分支合并,所以 one 分支上的 commit 内容在 master 分支上也有一份了。
什麽是快转模式呢?这是 git 在合并分支时的预设模式。
假设今天的 master 分支与 one 分支关系长这样:
one 分支与 master 分支为同个版本,也就是说他们有相同的档案与内容。
但是现在 one 分支新增 2 个版本,也就是领先 master 分支 2 个 Commit 版本。
当 master 要合并 one 分支时,master 分支与 one 分支的差异仅仅在於 one 分支多了 2 个 Commit 版本,其余档案内容都相同。
因为 master 分支与 one 分支都是同个 commit 分支出去的,所以当 master 分支合并 one 分支後,可以说是 master 合并自己以後的版本。这时 git 就会使用预设的 fast-forward 模式 来将 master 分支往後 2 个版本到 one 分支最新的 Commit 版本。
这时候两个分支的关系图会如以下图表示:
假使今天的情况是 master 分支出去 one 分支与 two 分支:
又切回 master
分支,并新增 two
分支後提交两个新版本。
现在三个分支的关系如下图:
one
分支与two
分支是从master
分支出去的,并且都比master
分支多了新的两个版本。one
分支与two
分支类似兄弟的概念。
master 分支想将两个分支都合并,因为 one 分支与 two 分支都是从 master 分支出去的,所以 master 有的档案内容 one 跟 two 都有,因此 master 要将与其中一只分支合并时,也是直接使用 fast-forward 模式 进行合并,简单来说可以想像是 master 分支可以将两个分支都直接收割了。
假设是 master 分支合并 two 分支:
紧接上面的状况,如果是要使用 one
合并 two
分支,或是 two
分支来合并 one
分支呢?
虽然 one
跟 two
都是从同一个 Commit 出来的,有相同来源,但是两个分支有自己新增的版本,各自出家。此时如果要合并的话,Git 的方法是:
再额外产生一个 Commit 来指向两个分支的最後 Commit,而执行合并的分支往前到最新的 Commit 中。
🛠 实际操作
假设如果是要用 two 分支来合并 one 分支的话, Commit 指向跟分支的关系会变成如下:
//当前在 two 分支上
$ git merge one # two 分支合并 one 分支
⚠️ 这时候可能会出现 Vim 编辑器,会提示说要请你输入文字纪录 Commit 的文字讯息
👉 因此要确定在「Insert」模式下,可以按下 i
、a
、o
其中一按键进入 Insert 模式,之後便可输入文字讯息。
👉 过後需要在 「Nomal」 模式下才能存挡、离开。
Insert 模式与 Nomal 模式切换方式:按下
ESC
按键或是Ctrl+[
⚠️ 在 「Nomal」 模式下,按下 :w
可进行存挡;按下 :q
会关闭档案,而 :wq
则是存挡完成後关闭档案。
合并後的分支与 Commit 之间的状况会是:使用 git log
指令查看
会新增额外的 Commit 来合并两个分支
使用
one
分支来合并two
分支一样会产生新的 Commit ,但这个 Commit 值会因为计算结果而不同。
💬 我们可以思考【 A 合并 B 】与 【 B 合并 A 】有什麽不同呢?
其实就结果来看,谁合并谁是没有什麽差异的,但是过程中会有些差别。
不管是谁合并谁,每个分支上的 Commit 都是平等的,只是哪一个分支往前移动而已,而 Commit 本身的档案或内容并不会受影响。因此这里可以再次复习分支的观念:分支只是一个指标,即使删除或改名都不会影响已经存在的 Commit。
--no-ff
参数预设的 fast-forward 模式 ,从 SourceTree 上来原来的新增的分支并不会特别表示,也可以称作是无线图,如果想要特别表示这里也有个其他分支(有线图),可以加上 --no-ff
参数即可。
$ git merge one --no-ff
如此一来就很像铁轨上又多出一条铁路出来,但都会抵达相同地点。
--no-ff
参数 - 不要使用快转模式合并。此时也会产生额外的 Commit 来指向前两个 Commit 喔!
有时候在我们还没合并分支前,可能会因为指令错误或是手残而不小心将新增的分支给砍掉了。如果想要把它救回来我们可以怎麽做呢?
方法|只要再制作分支将 Commit 内容接回来即可。
$ git branch 【新分支名称】 【Commit 的 SHA-1 值】
也许你会疑惑,为什麽我们明明已经砍掉分支,却还是可以找得到 Commit 的 SHA-1 值?这是因为一直强调的观念:分支只是一个指标。因此删掉分支,对 Git 来说只是一个指标没有了,但是 Commit 的内容依然存在,所以我们可以透过 Commit 的 SHA-1 值接回分支。
补充|如果忘记欲接回的 Commit 的 SHA-1 值,可以使用
git reflog
指令翻找。
Relog 预设会保留 30 天,如果是在时间范围内删除的都有机会查询到。
虽然我们说明上都是讲「合并分支」,实际上合并的应该是「分支指向的 Commit」。
👉 分支只是一个指向某个 Commit 的指标。
<<: 【Day 21】 实作 - 启用 AWS CloudFront 日志
>>: ASP.NET MVC 从入门到放弃(Day30)-总结
早起运动30分钟Day1 今天一边运动,一边听《转行》这本书。里面提到几个我喜欢的观点。 “我们都以...
有时候想要刻一些小物件,或是需要分享程序码给人以便请教问题 我都会使用codepen (真的是初学者...
forEach 来看看forEach在MDN的定义 Array.prototype.forEach(...
Socket.io 注意server side需要使用3.0.3版本 否则flutter clien...
需求 在早前几篇文章,我们介绍了 Recoil 这个 library 来在整个 App 分享全域变数...