使用git fetch和git rebase處理多人開(kāi)發(fā)同一分支的問(wèn)題

原文:https://blog.csdn.net/azureternite/article/details/76154807

情景

有的時(shí)候會(huì)遇到這種問(wèn)題,比如說(shuō)有兩個(gè)人,在同一個(gè)分支進(jìn)行開(kāi)發(fā),假設(shè)是我自己,跟我的同伴;現(xiàn)在,我寫(xiě)了一部分代碼,準(zhǔn)備push到遠(yuǎn)程了,于是我執(zhí)行g(shù)it add、git commit,一切ok,沒(méi)問(wèn)題,然后git push,這下問(wèn)題來(lái)了,git告訴我說(shuō)我的push被rejected了,原來(lái),我的同伴在我執(zhí)行push之前,已經(jīng)push了若干個(gè)commit到遠(yuǎn)程,因此我不能直接push,而是需要先把他的commits拉到我本地的repo才行。git的提示如下圖。


按照git的提示做

好,git的提示已經(jīng)很清楚了,rejected的原因通常是遠(yuǎn)程有了另外的push,詢(xún)問(wèn)了同伴,我們知道,就是ta先進(jìn)行了push。那么,根據(jù)git的提示,我們可能想要先把遠(yuǎn)程的改變進(jìn)行整合,再來(lái)push。那怎么整合呢,rejected那行告訴我們,要“fetch first”,而下面的e.g.說(shuō),我們可以用git pull來(lái)整合。也就是說(shuō),我們可以用git fetch,也可以用git pull來(lái)整合遠(yuǎn)程的改變到我們本地倉(cāng)庫(kù)中。

使用git pull

由于我本人對(duì)fetch不太了解,看著pull好像跟push是反義詞比較親切,那就用它吧。于是我執(zhí)行了git pull,然后git push。emmmm,好像沒(méi)什么問(wèn)題,但是…在source tree里面看著分支的圖譜怎么怪怪的?


圖譜里面顯示,我提交了兩個(gè)commit,但實(shí)際上我改動(dòng)的地方只進(jìn)行了一次提交。我們看看多出來(lái)的commit的描述,寫(xiě)著“Merge branch ‘master’ of github.com:ChuChencheng/test”。

嗯?意思是這個(gè)提交做的改動(dòng)是把遠(yuǎn)端的master分支進(jìn)行合并。

git pull動(dòng)的手腳

Google了一番git pull,發(fā)現(xiàn)git pull做的事情其實(shí)相當(dāng)于git fetch跟git merge,那,我之前一直沒(méi)用到的git fetch做的事情是什么呢?

git fetch這個(gè)命令會(huì)把遠(yuǎn)程的commits拉取到本地的repo中,但是,它不是直接把commits接在分支的最后面,而是從你最后一次push的那個(gè)commit節(jié)點(diǎn),再拉取一個(gè)新的分支出來(lái),類(lèi)似這樣:

????????* git fetch拉下來(lái)的節(jié)點(diǎn),建立在一個(gè)新的分支上

*? ?/? 你還沒(méi)push的節(jié)點(diǎn)

|/

* 你最后一次push的節(jié)點(diǎn)

|

*

那merge呢?git pull在拉取完之后,就會(huì)將新建的分支跟你原來(lái)的分支進(jìn)行合并,所以圖就變成了這樣:

*? 新建的分支merge進(jìn)原本的分支,這個(gè)節(jié)點(diǎn)就是merge xxx那個(gè)多出來(lái)的節(jié)點(diǎn)| \|? * git fetch拉下來(lái)的節(jié)點(diǎn),建立在一個(gè)新的分支上* /? 你還沒(méi)push的節(jié)點(diǎn)|/* 你最后一次push的節(jié)點(diǎn)|*

* 新建的分支merge進(jìn)原本的分支,這個(gè)節(jié)點(diǎn)就是merge xxx那個(gè)多出來(lái)的節(jié)點(diǎn)

| \

|? ? ?* git fetch拉下來(lái)的節(jié)點(diǎn),建立在一個(gè)新的分支上

*? ?/ 你還沒(méi)push的節(jié)點(diǎn)

|/

* 你最后一次push的節(jié)點(diǎn)

|

*

那怎么辦?

現(xiàn)在,我們知道了,這種情況下執(zhí)行g(shù)it pull,分支的圖譜就會(huì)變得很難看,但又必須把遠(yuǎn)程的commits拉取下來(lái),那有沒(méi)有辦法讓分支圖譜保持一條直線而不分叉呢?

這個(gè)時(shí)候,我們還需要一個(gè)以前也很少用(我真的很菜)的命令,git rebase。

git rebase的作用是,把一個(gè)分支的修改合并到另一個(gè)分支。聽(tīng)起來(lái)有點(diǎn)熟悉?沒(méi)錯(cuò),它跟merge的功能有點(diǎn)像。不同的是,merge的做法比較粗暴,直接把兩個(gè)分支再各自拉出一條線,連在一起就完了;而rebase則比較細(xì)心,它會(huì)把當(dāng)前分支跟你要合并的分支中不同的commits取消掉,臨時(shí)保存起來(lái),然后在要合并的分支中再把保存起來(lái)的commits patch上去,變成新的commits,當(dāng)然,commitId也是新的,這樣,最后的效果就是只剩合并后的分支,而且是一條直線,沒(méi)有分叉,沒(méi)有“Merge branch xxx of xxx”這種多余的提交。


具體做法

知道了是什么,為什么,最后就是怎么做了。

步驟如下:

git fetch

git rebase

解決沖突

git add 沖突文件

git rebase –continue

git push

其中,3、4、5點(diǎn),如果沒(méi)遇到?jīng)_突就不用進(jìn)行,直接push上去。

當(dāng)遇到?jīng)_突時(shí),git會(huì)提示patch failed,并要我們解決問(wèn)題了再執(zhí)行g(shù)it rebase --continue


此時(shí)的圖譜:


解決沖突后,通過(guò)git status可以看到rebase in progress,也就是說(shuō)現(xiàn)在還是在rebase的過(guò)程中:


然后我們把解決后的沖突文件add進(jìn)來(lái),并執(zhí)行g(shù)it rebase --continue繼續(xù)patch(也可以執(zhí)行–skip跳過(guò)這個(gè)patch,或–abort放棄rebase),可以看到分支是清晰的一條直線:


最后push,完成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容