1. 程式人生 > >Git初學札記(四)————Git Push的常規操作與Pull衝突解決

Git初學札記(四)————Git Push的常規操作與Pull衝突解決

目錄

引言

同步

圖示

重點

引言

在團隊開發當中,Git Push是多人協作環節中的最重要的一環可能沒有之一。同SVN一樣,push操作可以看做是對遠端程式的提交。

在多人協作中,push往往是最容易出現問題的一個環節,因為其他開發者有可能修改了你正準備提交的檔案,並且已經先你一步提交到了遠端倉庫中。由此,才會引出後面一系列的pull、merge等操作。

由於在之前的部落格《實現個人的Git遠端程式碼版本控制————EGIT完成Eclipse到GitHub一條龍》中已經詳細介紹了通過EGit Push新專案的操作,因此本篇部落格主要介紹一下Git命令列的操作,以及在Push中可能會遇到的種種問題及解決辦法。

Git命令列的遠端Push

不論以哪種方式push到遠端倉庫,都需要先在遠端建立一個可以與之關聯的空的倉庫。為了簡化演示過程,我們採用GitHub作為遠端倉庫的建立伺服器。

首先,我們已經在遠端建立了一個空倉庫:

複製倉庫地址,執行git命令:

如上圖所示,首先我們為本地倉庫add(關聯)一個遠端倉庫,並預設命名為origin,然後通過push命令推送到遠端倉庫,輸入git push -help,可以檢視一下push命令的引數,其中-u代表設定上游(遠端庫)

第一次通過-u引數push專案的同時設定好遠端庫之後,後面就可以直接git push origin master了。

EGit Push操作中的衝突問題

正如引言中所述的情況,我們將分支push到遠端倉庫的時候恰巧遠端倉庫中已經有了改動而與我們正準備提交的程式碼有衝突。這種情況在過去的開發中屢見不鮮,在svn中也存在同樣的問題,常常是一個工具類,大家都添加了自己的工具方法,如果不希望merge混亂,就需要有一個專門的merge人員,每天定點去伺服器上對大家的修改進行merge操作。雖然近些年微服務的口號喊得響徹,但是對於不適合微服務的專案,就仍然存在多人同時修改了共有檔案的情況發生。雖然我們不希望這樣的情況發生,也會盡量避免這種情況的發生,但仍然要學習如何使用Git去處理衝突的情況。

最有用的建議是:

push之前請先同步對比!

EGit的全部功能都封裝自git命令,應該說git命令包含了全部的EGit外掛操作。但是對於某些比對性的操作,命令列的體驗往往是差強人意的,尤其是在專案檔案繁多的情況下,幾十個檔案進行比對,絕對會讓你看的眼花繚亂。

假設此時,我們已經對自己修改的程式碼充滿了信心,並且提交到了本地倉庫,正準備push到遠端庫上去,這個時候我們應該怎麼做?是直接push還是先pull?我覺得先檢視一下同步比對資料的情況,然後對我們接下來的操作結果做到心中有數才是上策!接下來就來講解一下對比的操作。

同步

工作區與本地庫同步

選擇Team>Synchronize Workspace

Synchronize Workspace”翻譯過來是“同步工作區”,這聽起來有些“嚇人”,但是實際上,它僅僅是將本地庫與工作區內容進行比對。

工作區與遠端庫同步

同步之前,需要先將 Remote Tracking 的遠端庫進行Fetch...操作。

Fetch步驟如下:

切換到Git Repository檢視,右鍵專案名 > Remote > Fetch...

Fetch 完成!

這樣我們就可以任意選擇遠端分支與本地工作區進行比對:

注意這裡EGit為了區分工作區與本地庫的比對和工作區與遠端庫的比對,特意加了一個with,因此這裡的“Synchronize with Workspace”代表的是工作區與遠端庫的一個分支進行比對。

比對圖示

這裡的一些圖示資訊和svn的用法是類似的,灰色箭頭代表本地有修改,藍色箭頭代表遠端有修改,紅色雙箭頭代表此檔案有衝突。

在EGit官網上也給出了具體圖示的解釋:

(但願各位的英語和我一樣好 罒ω罒 !)

從上圖可以看出,我們的專案僅僅是有一個本地的修改,因此可以確定的是push之後不會出現任何衝突問題,可以放心大膽的push。也不需要每次push之前都無腦的pull。

這裡注意一下,Git的Push操作無法在Synchronize檢視中進行,因為Git的push操作都是針對於分支而言的,也就是說,我們實際上只能push當前的分支,而非檔案,就算是隻有一個檔案的修改,也必須是push分支,也就是命令列中看到的git push origin master,master就是當前的分支。而Svn可以直接在Synchronize檢視中提交單個或多個檔案,這一點應該說svn要優於git。但是瑕不掩瑜,Git強大的分支開發和版本管理體系是svn無法匹敵的。

為了push我們的分支,需要先回到基礎Java檢視中來,右鍵專案>Team>Remote>Push...或者 :右鍵專案>Team>Push to Upstream(前提是已經與遠端庫建立關聯關係)

push成功!

重點

假設,我又對程式進行了修改(添加了一行輸出語句“I wanna learn Vue.js very well!”),並且已經提交到本地庫中,正準備push到遠端倉庫。

我們如之前的建議,正確的將工作區程式碼與遠端倉庫的程式碼進行比對:

但是不幸的是,有人已經對這個檔案進行了修改,並且衝突甚是囂張!如果我們不做任何感想,直接push會有什麼情況發生?

我們心裡很清楚,push操作在衝突的情況下是不可能完成的,不過貌似返回的錯誤資訊還是很友好的。但請注意紅框內的單詞:rejected ,拒絕 ,而且還是過去時,那啥也別說了,遠端庫已經拒絕了我的push請求!所以英語不好的小夥伴一定注意了,這裡的push失敗對話方塊真的是不太鮮明,有可能誤以為push操作已經成功。這裡千萬要注意。

我們可以檢查一下遠端的倉庫,來進一步驗證我們的判斷:

果然沒有push成功。

那麼這個時候我們應該做什麼?我們應該先pull,然後解決衝突再進行push操作。

右鍵專案>Team>Pull... 或者:右鍵專案>Team>Pull (前提是已經有遠端庫關聯)

建議剛開始使用的小夥伴可以先使用“Pull...”進行拉取操作,因為會彈出一個Pull對話方塊,裡面的資訊對我們理解我們的操作會有不小的幫助,後面熟練了可以使用“Pull”直接從預設的遠端庫中去拉取。

執行完成後,我們的衝突檔案就變成了這個樣子:

可以看到,Git會將HEAD和遠端庫的修改內容全部都寫入衝突檔案中,並且使用<<<<<<< ======= >>>>>>>進行區分。

我們手動進行修改即可,修改結果如下:

再次commit的時候,Git會為我們自動生成一個Commit Message資訊,非常智慧:

提交完成後,我們再次嘗試Push操作,彈出結果對話方塊如下:

這回貌似沒有rejected了,進一步檢查一下GitHub上的檔案內容:

和我們push的結果一樣。

綜上,就是衝突發生的時候我們的處理辦法。但是這種開發者之間無溝通的衝突解決辦法只是一種方案,我們通過pull,手動刪減內容,來完成衝突的解決。但是如果這個檔案發生衝突的地方達到幾十行甚至上百行的情況又該怎麼辦?

如果一個檔案的衝突內容參差不齊,且數量很多,達到了幾十行甚至上百行的級別,那麼我們應該與發生衝突的開發者進行線下溝通,嘗試以版本回退後共同merge的方式來解決衝突,即先進行線下merge,然後由其中一人進行push操作。

總的來說,解決衝突的辦法還是比較多的,如果討厭刪刪改改的小夥伴,可以同事之間協調溝通,共同merge,這樣也可以相互學習,交流經驗。

綜上,就是push操作中常見的問題及解決辦法。如有疑問歡迎文末留言。