Git初学札记(四)————Git Push的常规操作与Pull冲突解决
目錄
引言
Git命令行的遠(yuǎn)程Push
EGit Push操作中的沖突問(wèn)題
同步
工作區(qū)與本地庫(kù)同步
工作區(qū)與遠(yuǎn)程庫(kù)同步
圖標(biāo)
重點(diǎn)
引言
在團(tuán)隊(duì)開(kāi)發(fā)當(dāng)中,Git Push是多人協(xié)作環(huán)節(jié)中的最重要的一環(huán)可能沒(méi)有之一。同SVN一樣,push操作可以看做是對(duì)遠(yuǎn)端程序的提交。
在多人協(xié)作中,push往往是最容易出現(xiàn)問(wèn)題的一個(gè)環(huán)節(jié),因?yàn)槠渌_(kāi)發(fā)者有可能修改了你正準(zhǔn)備提交的文件,并且已經(jīng)先你一步提交到了遠(yuǎn)程倉(cāng)庫(kù)中。由此,才會(huì)引出后面一系列的pull、merge等操作。
由于在之前的博客《實(shí)現(xiàn)個(gè)人的Git遠(yuǎn)程代碼版本控制————EGIT完成Eclipse到GitHub一條龍》中已經(jīng)詳細(xì)介紹了通過(guò)EGit Push新項(xiàng)目的操作,因此本篇博客主要介紹一下Git命令行的操作,以及在Push中可能會(huì)遇到的種種問(wèn)題及解決辦法。
Git命令行的遠(yuǎn)程Push
不論以哪種方式push到遠(yuǎn)程倉(cāng)庫(kù),都需要先在遠(yuǎn)程建立一個(gè)可以與之關(guān)聯(lián)的空的倉(cāng)庫(kù)。為了簡(jiǎn)化演示過(guò)程,我們采用GitHub作為遠(yuǎn)程倉(cāng)庫(kù)的創(chuàng)建服務(wù)器。
首先,我們已經(jīng)在遠(yuǎn)程建立了一個(gè)空倉(cāng)庫(kù):
復(fù)制倉(cāng)庫(kù)地址,執(zhí)行g(shù)it命令:
如上圖所示,首先我們?yōu)楸镜貍}(cāng)庫(kù)add(關(guān)聯(lián))一個(gè)遠(yuǎn)程倉(cāng)庫(kù),并默認(rèn)命名為origin,然后通過(guò)push命令推送到遠(yuǎn)程倉(cāng)庫(kù),輸入git push -help,可以查看一下push命令的參數(shù),其中-u代表設(shè)置上游(遠(yuǎn)程庫(kù))
第一次通過(guò)-u參數(shù)push項(xiàng)目的同時(shí)設(shè)置好遠(yuǎn)程庫(kù)之后,后面就可以直接git push origin master了。
EGit Push操作中的沖突問(wèn)題
正如引言中所述的情況,我們將分支push到遠(yuǎn)程倉(cāng)庫(kù)的時(shí)候恰巧遠(yuǎn)程倉(cāng)庫(kù)中已經(jīng)有了改動(dòng)而與我們正準(zhǔn)備提交的代碼有沖突。這種情況在過(guò)去的開(kāi)發(fā)中屢見(jiàn)不鮮,在svn中也存在同樣的問(wèn)題,常常是一個(gè)工具類(lèi),大家都添加了自己的工具方法,如果不希望merge混亂,就需要有一個(gè)專(zhuān)門(mén)的merge人員,每天定點(diǎn)去服務(wù)器上對(duì)大家的修改進(jìn)行merge操作。雖然近些年微服務(wù)的口號(hào)喊得響徹,但是對(duì)于不適合微服務(wù)的項(xiàng)目,就仍然存在多人同時(shí)修改了共有文件的情況發(fā)生。雖然我們不希望這樣的情況發(fā)生,也會(huì)盡量避免這種情況的發(fā)生,但仍然要學(xué)習(xí)如何使用Git去處理沖突的情況。
最有用的建議是:
push之前請(qǐng)先同步對(duì)比!
EGit的全部功能都封裝自git命令,應(yīng)該說(shuō)git命令包含了全部的EGit插件操作。但是對(duì)于某些比對(duì)性的操作,命令行的體驗(yàn)往往是差強(qiáng)人意的,尤其是在項(xiàng)目文件繁多的情況下,幾十個(gè)文件進(jìn)行比對(duì),絕對(duì)會(huì)讓你看的眼花繚亂。
假設(shè)此時(shí),我們已經(jīng)對(duì)自己修改的代碼充滿了信心,并且提交到了本地倉(cāng)庫(kù),正準(zhǔn)備push到遠(yuǎn)程庫(kù)上去,這個(gè)時(shí)候我們應(yīng)該怎么做?是直接push還是先pull?我覺(jué)得先查看一下同步比對(duì)數(shù)據(jù)的情況,然后對(duì)我們接下來(lái)的操作結(jié)果做到心中有數(shù)才是上策!接下來(lái)就來(lái)講解一下對(duì)比的操作。
同步
工作區(qū)與本地庫(kù)同步
選擇Team>Synchronize Workspace
“Synchronize Workspace”翻譯過(guò)來(lái)是“同步工作區(qū)”,這聽(tīng)起來(lái)有些“嚇人”,但是實(shí)際上,它僅僅是將本地庫(kù)與工作區(qū)內(nèi)容進(jìn)行比對(duì)。
工作區(qū)與遠(yuǎn)程庫(kù)同步
同步之前,需要先將 Remote Tracking 的遠(yuǎn)程庫(kù)進(jìn)行Fetch...操作。
Fetch步驟如下:
切換到Git Repository視圖,右鍵項(xiàng)目名 > Remote > Fetch...
Fetch 完成!
這樣我們就可以任意選擇遠(yuǎn)程分支與本地工作區(qū)進(jìn)行比對(duì):
注意這里EGit為了區(qū)分工作區(qū)與本地庫(kù)的比對(duì)和工作區(qū)與遠(yuǎn)程庫(kù)的比對(duì),特意加了一個(gè)with,因此這里的“Synchronize with Workspace”代表的是工作區(qū)與遠(yuǎn)程庫(kù)的一個(gè)分支進(jìn)行比對(duì)。
比對(duì)圖標(biāo)
這里的一些圖標(biāo)信息和svn的用法是類(lèi)似的,灰色箭頭代表本地有修改,藍(lán)色箭頭代表遠(yuǎn)程有修改,紅色雙箭頭代表此文件有沖突。
在EGit官網(wǎng)上也給出了具體圖標(biāo)的解釋:
(但愿各位的英語(yǔ)和我一樣好 罒ω罒 !)
從上圖可以看出,我們的項(xiàng)目?jī)H僅是有一個(gè)本地的修改,因此可以確定的是push之后不會(huì)出現(xiàn)任何沖突問(wèn)題,可以放心大膽的push。也不需要每次push之前都無(wú)腦的pull。
這里注意一下,Git的Push操作無(wú)法在Synchronize視圖中進(jìn)行,因?yàn)镚it的push操作都是針對(duì)于分支而言的,也就是說(shuō),我們實(shí)際上只能push當(dāng)前的分支,而非文件,就算是只有一個(gè)文件的修改,也必須是push分支,也就是命令行中看到的git push origin master,master就是當(dāng)前的分支。而Svn可以直接在Synchronize視圖中提交單個(gè)或多個(gè)文件,這一點(diǎn)應(yīng)該說(shuō)svn要優(yōu)于git。但是瑕不掩瑜,Git強(qiáng)大的分支開(kāi)發(fā)和版本管理體系是svn無(wú)法匹敵的。
為了push我們的分支,需要先回到基礎(chǔ)Java視圖中來(lái),右鍵項(xiàng)目>Team>Remote>Push...或者 :右鍵項(xiàng)目>Team>Push to Upstream(前提是已經(jīng)與遠(yuǎn)程庫(kù)建立關(guān)聯(lián)關(guān)系)
push成功!
重點(diǎn)
假設(shè),我又對(duì)程序進(jìn)行了修改(添加了一行輸出語(yǔ)句“I wanna learn Vue.js very well!”),并且已經(jīng)提交到本地庫(kù)中,正準(zhǔn)備push到遠(yuǎn)程倉(cāng)庫(kù)。
我們?nèi)缰暗慕ㄗh,正確的將工作區(qū)代碼與遠(yuǎn)程倉(cāng)庫(kù)的代碼進(jìn)行比對(duì):
但是不幸的是,有人已經(jīng)對(duì)這個(gè)文件進(jìn)行了修改,并且沖突甚是囂張!如果我們不做任何感想,直接push會(huì)有什么情況發(fā)生?
我們心里很清楚,push操作在沖突的情況下是不可能完成的,不過(guò)貌似返回的錯(cuò)誤信息還是很友好的。但請(qǐng)注意紅框內(nèi)的單詞:rejected ,拒絕 ,而且還是過(guò)去時(shí),那啥也別說(shuō)了,遠(yuǎn)程庫(kù)已經(jīng)拒絕了我的push請(qǐng)求!所以英語(yǔ)不好的小伙伴一定注意了,這里的push失敗對(duì)話框真的是不太鮮明,有可能誤以為push操作已經(jīng)成功。這里千萬(wàn)要注意。
我們可以檢查一下遠(yuǎn)程的倉(cāng)庫(kù),來(lái)進(jìn)一步驗(yàn)證我們的判斷:
果然沒(méi)有push成功。
那么這個(gè)時(shí)候我們應(yīng)該做什么?我們應(yīng)該先pull,然后解決沖突再進(jìn)行push操作。
右鍵項(xiàng)目>Team>Pull... 或者:右鍵項(xiàng)目>Team>Pull (前提是已經(jīng)有遠(yuǎn)程庫(kù)關(guān)聯(lián))
建議剛開(kāi)始使用的小伙伴可以先使用“Pull...”進(jìn)行拉取操作,因?yàn)闀?huì)彈出一個(gè)Pull對(duì)話框,里面的信息對(duì)我們理解我們的操作會(huì)有不小的幫助,后面熟練了可以使用“Pull”直接從默認(rèn)的遠(yuǎn)程庫(kù)中去拉取。
執(zhí)行完成后,我們的沖突文件就變成了這個(gè)樣子:
可以看到,Git會(huì)將HEAD和遠(yuǎn)程庫(kù)的修改內(nèi)容全部都寫(xiě)入沖突文件中,并且使用<<<<<<< ======= >>>>>>>進(jìn)行區(qū)分。
我們手動(dòng)進(jìn)行修改即可,修改結(jié)果如下:
再次commit的時(shí)候,Git會(huì)為我們自動(dòng)生成一個(gè)Commit Message信息,非常智能:
提交完成后,我們?cè)俅螄L試Push操作,彈出結(jié)果對(duì)話框如下:
這回貌似沒(méi)有rejected了,進(jìn)一步檢查一下GitHub上的文件內(nèi)容:
和我們push的結(jié)果一樣。
綜上,就是沖突發(fā)生的時(shí)候我們的處理辦法。但是這種開(kāi)發(fā)者之間無(wú)溝通的沖突解決辦法只是一種方案,我們通過(guò)pull,手動(dòng)刪減內(nèi)容,來(lái)完成沖突的解決。但是如果這個(gè)文件發(fā)生沖突的地方達(dá)到幾十行甚至上百行的情況又該怎么辦?
如果一個(gè)文件的沖突內(nèi)容參差不齊,且數(shù)量很多,達(dá)到了幾十行甚至上百行的級(jí)別,那么我們應(yīng)該與發(fā)生沖突的開(kāi)發(fā)者進(jìn)行線下溝通,嘗試以版本回退后共同merge的方式來(lái)解決沖突,即先進(jìn)行線下merge,然后由其中一人進(jìn)行push操作。
總的來(lái)說(shuō),解決沖突的辦法還是比較多的,如果討厭刪刪改改的小伙伴,可以同事之間協(xié)調(diào)溝通,共同merge,這樣也可以相互學(xué)習(xí),交流經(jīng)驗(yàn)。
?
綜上,就是push操作中常見(jiàn)的問(wèn)題及解決辦法。如有疑問(wèn)歡迎文末留言。
?
總結(jié)
以上是生活随笔為你收集整理的Git初学札记(四)————Git Push的常规操作与Pull冲突解决的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Apache工具包方法——Hex.enc
- 下一篇: HTMLCSS————CSS常用选择器及