目錄
- 實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)
- git merge 合并代碼
- 創(chuàng)建分支和提交記錄
- 進(jìn)行合并
- 解決沖突
- 回滾代碼
- 補(bǔ)充操作
- 再來(lái)看看使用 git rebase 合并分支
- 創(chuàng)建分支和提交記錄
- 進(jìn)行合并
- 處理沖突
- 版本回滾
- git rebase 還有什么優(yōu)化的空間嗎?
- 為什么要對(duì)版本進(jìn)行合并?
- 如何對(duì)代碼進(jìn)行合并呢?
- git merge 合并代碼
- git merge VS. git rebase 總結(jié)
- 相同的地方
- 不同的地方
- 為什么要推薦使用 git rebase 呢?
- 這里還有幾點(diǎn)重要的說(shuō)明
我們現(xiàn)在分支合并想到最多的就是git merge
肴敛,還有一個(gè)合并代碼的命令git rebase
挑童,而這個(gè)命令在工作中優(yōu)先被推薦使用,下面先通過(guò)兩個(gè)例子體會(huì)一下兩個(gè)命令合并代碼的差別:
實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)
git merge 合并分支
創(chuàng)建分支和提交記錄
- 從
master
分支創(chuàng)建一個(gè)merge1
分支品腹,進(jìn)行第一次提交
git checkout master
git checkout -b merge1
git add .
git commit -m 'merge1'
- 從
master
分支創(chuàng)建一個(gè)merge2
分支冷溶,修改代碼,進(jìn)行第一次提交
git checkout master
git checkout -b merge2
git add .
git commit -m 'merge2'
- 切換到
merge1
分支,修改代碼彪置,進(jìn)行第二次提交
git checkout merge1
git add .
git commit -m 'merge1-2'
- 切換到
merge2
分支,修改代碼蝇恶,進(jìn)行第二次提交
git checkout merge2
git add .
git commit -m 'merge2-2'
進(jìn)行合并
5.將merge2
分支merge
到merge1
分支中拳魁,解決沖突之后會(huì)有一個(gè)新的 merge
的 commit
分支。
git checkout merge1
git merge merge2
- 如果想取消合并撮弧,直接使用
git merge --abort
git merge --abort
解決沖突
- 解決沖突之后(這里選擇保留雙方更改)潘懊,這里選擇直接提交代碼
git add .
git commit -m 'merge1 merge merge2'
回滾代碼
- 如果想要回到
merge1-2
,執(zhí)行操作git reset
補(bǔ)充操作
- 在第7步的時(shí)候贿衍,如果直接使用
git merge --continue
會(huì)進(jìn)入面板授舟,可以修改提交分支的信息
git merge --continue
這個(gè)時(shí)候i
插入,修改merge1 merge merge2 continue
之后按ESC
鍵贸辈,然后按:wq
保存释树,可以看出,這邊還是會(huì)新保留一個(gè)commit
- 9步之后想要回到
merge1-2
擎淤,操作git reset
git reset <commitID>
再來(lái)看看使用 git rebase 合并分支
創(chuàng)建分支和提交記錄
- 從
master
分支創(chuàng)建一個(gè)merge1
分支奢啥,進(jìn)行第一次提交
git checkout master
git checkout -b merge1
git add .
git commit -m 'merge1'
- 從
master
分支創(chuàng)建一個(gè)merge2
分支,修改代碼嘴拢,進(jìn)行第一次提交
git checkout master
git checkout -b merge2
git add .
git commit -m 'merge2'
- 切換到
merge1
分支桩盲,修改代碼,進(jìn)行第二次提交
git checkout merge1
git add .
git commit -m 'merge1-2'
- 切換到
merge2
分支席吴,修改代碼赌结,進(jìn)行第二次提交
git checkout merge2
git add .
git commit -m 'merge2-2'
進(jìn)行合并
- 切換到
merge1
分支,進(jìn)行rebase
操作git rebse merge2
git checkout merge1
git rebase merge2
首先這里可以看到要和兩個(gè)提交進(jìn)行rebase
抢腐,
- 此時(shí)想要退出合并姑曙,寫(xiě)
git rebase --abort
git rebase --abort
處理沖突
- 我們要手動(dòng)修改第一個(gè)提交,因?yàn)檫@個(gè)提交不是最后一個(gè)提交迈倍,所以?xún)?nèi)容可以不保留伤靠,選擇采用當(dāng)前更改
- 然后提交修改,這里先使用
git add .
啼染,然后使用git rebase --continue
時(shí)說(shuō)沒(méi)有修改宴合,是否強(qiáng)制使用git rebase --skip
跳過(guò)
git add .
git rebase --skip
- 這個(gè)成功之后進(jìn)入下一個(gè)提交,這里可以看到迹鹅,這里與
merge
的當(dāng)前更改和傳入更改的位置是有改變的卦洽,傳入的更改反而是merge1
,這個(gè)時(shí)候選擇保留雙方更改斜棚。
- 然后提交修改
git add .
git rebase --continue
- 此時(shí)查看
git log
阀蒂,發(fā)現(xiàn)合并后的log
展示
- 并沒(méi)有再生成新的提交記錄
- 這里的
log
順序和merge
不同 - 因?yàn)閯偛盼覀兪褂?code>skip跳過(guò)了一個(gè)
commit
该窗,所以這里并沒(méi)有merge1
。
版本回滾
- 此時(shí)要回滾到
merge1-2
的時(shí)候蚤霞,即沒(méi)有rebase
之前酗失,是無(wú)法回退的,因?yàn)槲覀兊陌姹緲?shù)里面昧绣,已經(jīng)找不到合并之前的兩次提交了规肴,這個(gè)時(shí)候需要使用git reflog
操作日志進(jìn)行回滾,這里使用第幾步可以回滾的更好夜畴。
git rebase 還有什么優(yōu)化的空間嗎?
一般使用git rebase
的時(shí)候拖刃,都會(huì)將當(dāng)前的版本進(jìn)行commit
合并。
為什么要對(duì)版本進(jìn)行合并?
剛才實(shí)驗(yàn)的時(shí)候贪绘,其實(shí)我們已經(jīng)看到了兑牡,git rebase的流程是,將merge2的代碼拉到merge1中兔簇,然后和merge1中提交的代碼一次一次進(jìn)行diff发绢,但是一般情況下,我們一般會(huì)將merge1中最后一次提交的代碼視為最終代碼垄琐,并不需要再和之前的代碼進(jìn)行diff边酒,這個(gè)時(shí)候就需要先將之前的版本合并,然后再與merge2進(jìn)行diff狸窘,此時(shí)只需要diff一次即可墩朦。
如何對(duì)代碼進(jìn)行合并呢?
請(qǐng)看這篇博客:方法二:合并需要的commit
git merge VS. git rebase 總結(jié)
相同的地方
對(duì)git版本進(jìn)行管理,功能是合并代碼翻擒,都需要手動(dòng)解決沖突氓涣。
不同的地方
比較 | git merge | git rebase |
---|---|---|
原理 |
git merge 是兩個(gè)分支最新commit 進(jìn)行diff 比較,解決沖突之后生成一個(gè)新的commit 記錄 |
git rebase 是將目標(biāo)分支拉取陋气,并與當(dāng)前分支的每一個(gè)提交逐一進(jìn)行diff 劳吠,將當(dāng)前分支合并到目標(biāo)分支代碼的后面,解決沖突之后更新commitID 巩趁,當(dāng)前分支原來(lái)的commitID 不保留在log 記錄中 |
查看log
|
commit記錄按照版本提交時(shí)間進(jìn)行排列痒玩,并不是版本的真實(shí)順序。 |
按照合并順序進(jìn)行排列议慰,實(shí)際版本的真實(shí)順序 |
原理圖 | 這個(gè)是分支存在的真實(shí)結(jié)構(gòu)圖 |
這個(gè)圖描述了蠢古,merge1的rebase操作,是將merge2代碼拉過(guò)來(lái)之后將自己合并到其后面 |
為什么要推薦使用 git rebase 呢?
- 避免在總分支上手動(dòng)處理沖突的危險(xiǎn)操作
我們實(shí)際開(kāi)發(fā)的時(shí)候别凹,都會(huì)有一個(gè)總的dev
分支草讶,和一個(gè)自己的分支work
,正確的操作是我們應(yīng)該先將dev
的分支拉過(guò)來(lái)炉菲,然后將我們的代碼合并上去堕战,首先在我們自己的work
代碼中坤溃,有一個(gè)處理完沖突的最新代碼,其次再去dev
分支merge
我們的work
分支践啄,這樣浇雹,就不會(huì)出現(xiàn)在dev
分支上手動(dòng)處理沖突的危險(xiǎn)操作。
# 在work分支
git rebase dev
# 處理完分支屿讽,切換到dev分支
git checkout dev
# 合并work分支的代碼
git merge work
- 得到一個(gè)干凈整潔的版本樹(shù)
通過(guò)上面的原理圖我們可以看到,在分支存儲(chǔ)的時(shí)候吠裆,兩個(gè)分支的內(nèi)容還是實(shí)際還是分開(kāi)的伐谈,而rebase
之后的版本樹(shù),是一條真實(shí)干凈的版本樹(shù)试疙。這個(gè)對(duì)以后正式版本的維護(hù)是很可的一件事诵棵,也是推薦大家用的。
這里還有幾點(diǎn)重要的說(shuō)明
千萬(wàn)不要用
dev
分支去rebase
我們自己的分支祝旷。rebase dev
的時(shí)候履澳,盡量先將自己所有的commit
合并成1個(gè),然后再進(jìn)行rebase
操作怀跛。對(duì)于
dev
分支來(lái)說(shuō)距贷,使用rebase
更好一些。如果進(jìn)行回滾操作了吻谋,那么當(dāng)前分支修改之后還需要再次與dev
進(jìn)行一次merge
操作忠蝗。如果是rebase
,直接可以在最新的代碼中進(jìn)行修改漓拾。重重重要的說(shuō)明! 重重重要的說(shuō)明! 重重重要的說(shuō)明!有些人會(huì)說(shuō)
rebase
的操作復(fù)雜阁最,而且回滾操作很不方便,我們都知道合并是一件很慎重的事情骇两,所以我們?cè)谶M(jìn)行合并操作的時(shí)候速种,也要進(jìn)行慎重思考。之前也有遇到過(guò)低千,有同時(shí)濫用merge
將別人代碼沖掉的情況配阵,所以對(duì)于開(kāi)發(fā)來(lái)說(shuō),上線(xiàn)的東西質(zhì)量保證是很重要的栋操。