git最常用方法之一帐要,合并代碼把敞,大部分時(shí)候我們都是使用merge命令。其實(shí)還有rebase命令榨惠,既然都是合并代碼奋早,兩者有什么差異和共同點(diǎn)盛霎?
那就來深入了解一下
1.相同點(diǎn)
雖然git合并代碼有merge和rebase兩種方式,但是兩種合并方式的最終結(jié)果是一樣的耽装,沒有任何區(qū)別愤炸。
既然整合結(jié)果沒有區(qū)別,那么區(qū)別在哪了掉奄?那就是合并過程规个。
2.不同點(diǎn)
以兩個(gè)分支為例,主分支master姓建,新分支develop诞仓,將develop分支合并到master主分支
2.1. merge合并
//當(dāng)前處于master分支
daideMacBook-Pro:UIFinalTest dai$ git status
On branch master
Your branch is ahead of 'github/master' by 5 commits.
(use "git push" to publish your local commits)
//創(chuàng)建并切換到develop分支
nothing to commit, working tree clean
daideMacBook-Pro:UIFinalTest dai$ git checkout -b develop
Switched to a new branch 'develop'
//創(chuàng)建一個(gè)類,添加到develop倉庫
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Develop1'
[develop 905f008] Develop1
Committer: dai <dai@daideMacBook-Pro.local>
//切換到master分支,并添加一個(gè)類到master倉庫
daideMacBook-Pro:UIFinalTest dai$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'github/master' by 5 commits.
(use "git push" to publish your local commits)
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Master1'
[master 4d82b67] Master1
Committer: dai <dai@daideMacBook-Pro.local>
//再次添加一個(gè)類到master倉庫
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Master2'
[master 3a2c545] Master2
Committer: dai <dai@daideMacBook-Pro.local>
//最后速兔,再回到develop分支墅拭,添加一個(gè)類到develop倉庫
daideMacBook-Pro:UIFinalTest dai$ git checkout develop
Switched to branch 'develop'
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Develop2'
[develop 78d53bf] Develop2
Committer: dai <dai@daideMacBook-Pro.local>
因?yàn)閙aster和develop的父分支是一樣的,都是base涣狗,所以具體流程如下:
master: base <--- Master1 <--- Master2
develop: base <--- Develop1 <--- Develop2
合并代碼:
//先切換到master分支谍婉,使用git merge develop命令
daideMacBook-Pro:UIFinalTest dai$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'github/master' by 7 commits.
(use "git push" to publish your local commits)
daideMacBook-Pro:UIFinalTest dai$ git merge develop
因?yàn)槭褂胢erge命令是按照時(shí)間戳先后順序的,所以镀钓,得到的提交歷史為:
base <--- Develop1 <--- Master1 <--- Master2 <---Develop1 <--- Merge(做了三方合并發(fā)現(xiàn)沖突穗熬,手工處理沖突后git add/commit增加了提交節(jié)點(diǎn)Merge)
2.2 rebase合并
分支創(chuàng)建同上,但是在合并代碼時(shí)掸宛,不需要切換到master分支
合并代碼:
daideMacBook-Pro:UIFinalTest dai$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Develop1
Applying: Develop2
1:回到兩個(gè)分支(master死陆、develop)的共同祖先(base),
2:提取你所在分支(develop)每次提交時(shí)產(chǎn)生的差異唧瘾,
3:把這些差異分別保存到臨時(shí)文件里措译,
4:然后從當(dāng)前分支(develop)轉(zhuǎn)換到你需要衍合的分支(master),
5:依照順序把分支master的差異commit放到分支feature-1中饰序。
合并后的 Develop2(即現(xiàn)在的 Develop2`)所指的快照领虹,同上面Merge三方合并例子中的 Merge所指的快照內(nèi)容一模一樣了。最后整合得到的結(jié)果沒有任何區(qū)別求豫,但衍合能產(chǎn)生一個(gè)更為整潔的提交歷史塌衰。如果視察一個(gè)衍合過的分支的歷史記錄,看起來更清楚: 仿佛所有修改都是先后進(jìn)行的蝠嘉,盡管實(shí)際上它們原來是同時(shí)發(fā)生的最疆。
總結(jié)
git rebase過程相比較git merge合并整合得到的結(jié)果沒有任何區(qū)別,但是通過git rebase衍合能產(chǎn)生一個(gè)更為整潔的提交歷史蚤告。
如果觀察一個(gè)衍合過的分支的歷史提交記錄努酸,看起來會更清楚:仿佛所有修改都是在一根線上先后完成的,盡管實(shí)際上它們原來是同時(shí)并行發(fā)生的杜恰。
一般我們使用衍合的目的获诈,是想要得到一個(gè)能在遠(yuǎn)程分支上干凈應(yīng)用的補(bǔ)丁仍源,比如某個(gè)項(xiàng)目你不是維護(hù)者,但是想幫點(diǎn)忙舔涎,最好使用衍合處理笼踩。
先在自己的一個(gè)分支進(jìn)行開發(fā),當(dāng)準(zhǔn)備向主項(xiàng)目提交補(bǔ)丁的時(shí)候亡嫌,根據(jù)最新的orgin/master進(jìn)行一次衍合操作然后再提交嚎于,這樣維護(hù)者就不需要任何整合工作。
實(shí)際為:把解決分支補(bǔ)丁同最新主干代碼之間的沖突的責(zé)任昼伴,劃轉(zhuǎn)給由提交補(bǔ)丁的人來解決匾旭。
作為維護(hù)項(xiàng)目的人只需要根據(jù)你提供的倉庫地址做一次快進(jìn)合并,或者直接采納你提交的補(bǔ)丁圃郊。
衍合的風(fēng)險(xiǎn)价涝,請務(wù)必遵循如下準(zhǔn)則:
一旦分支中的提交對象發(fā)布到公共倉庫,就千萬不要對該分支進(jìn)行衍合操作持舆。