Git使用入門,使用原理解讀及如何在GitLab、GitHub或者Stash上管理項目(三)

來源:互聯網
上載者:User

標籤:git   專案管理   merge   merge request   branch   

上一篇講了remote相關,讓大家基本瞭解了一下遠端庫與本地庫之間的聯絡。目前我認為還剩下的容易造成理解混亂的是merge命令以及merge動作的應用情境,下面詳述。

首先先給大家解釋merge本身的一些內容,再結合一些情境幫大家從混亂的理解中找到思路,進而完全理解Merge Request的意思並掌握這項技能。

merge譯成中文是合并,顧名思義,git merge命令時用來合并的,而合并的對象就是branch(分支)。下面我舉個簡單的應用情境(只在本地Repository中)來說明:本地庫中有兩個分支testBranch1和testBranch2。目前兩個分支中的檔案內容相同,都只有一個fileA.txt檔案,而且fileA.txt的內容只有一行文字:HelloWorld!

如果你目前處於testBranch1,並且修改了fileA.txt檔案在第二行增加了一句:Hello! 

此時你的fileA.txt形如:

HelloWorld!

Hello!

不僅如此,你還建立了另一個空檔案fileB.txt,並且把所有的修改commit進來。


然後checkout到testBranch2上,此時testBranch2上應該只有一個fileA.txt檔案而且內容只有一行HelloWorld! 此時你又修改了fileA.txt在第二行增加了一句HaHa! ,並且把所有的修改都commit進來。

此時你的fileA.txt形如:

HelloWorld!

HaHa!


現在可以想象,testBranch1和testBranch2兩個分支分別管理著兩套不同版本的內容了。前者有兩個檔案,後者只有一個檔案,而且名字相同的檔案內容也有所差別。好了git merge命令馬上要出場了,下面請特別注意小編介紹的兩個情境:

情境1:

git checkout testBranch1 (即切換到testBranch1分支上),執行git merge testBranch2命令。這樣代表:站在testBranch1分支上,把testBranch2分支上的內容融合到testBranch1分支上來。

這樣git會嘗試把testBranch2中的內容與testBranch1融合,而這樣是不會改變testBranch2分支上的內容的,只會改變testBranch1上的內容。所以此後testBranch1上有兩個檔案(fileA.txt和fileB.txt),而testBranch2上依然只有1個檔案(filtA.txt)


情境2:

git checkout testBranch2 (即切換到testBranch2分支上),執行git merge testBranch1 命令。這樣代表站在testBranch2分支上,把testBranch1分支上的內容融合到testBranch2分支上來。

這樣git會嘗試把testBranch1中的內容與testBranch2融合,而這樣是不會改變testBranch1分支上的內容的,只會改變testBranch2上的內容。所以此後testBranch1上有兩個檔案(fileA.txt和fileB.txt),而testBranch2上也有了2個檔案(fileA.txt和fileB.txt)


情境1和情境2在整體上的變化大家明白以後應該就能理解merge命令的含義了吧?下面說一下另一個細節

相信大家注意到,如果第一個分支的fileA.txt和第二個分支的fileA.txt進行融合的話,是有可能產生歧義的。前者的第二行希望是Hello!,後者的第二行希望是HaHa!  那麼最終結果到底聽誰的呢?這種情況下Git就“有可能產生衝突”。那麼在merge 過程中產生衝突是怎樣的效果呢?此時你的fileA.txt可能會呈現類似以下的中間狀態(此時以情境1的情況為例):

HelloWorld!

>>>>>>>>>

Hello!

=========

Haha!

<<<<<<<<<

類似這樣的狀態代表Git說:我糊塗了。就需要我們人工來解決這樣的衝突。此時我們可以開啟fileA.txt檔案,發現內容可能如上所示。解決時我們會想:Hello!是我在操作testBranch1時想加的話,HaHa!是我在操作testBranch2是想加的話。兩個我都想儲存下來,那稍微編輯一下就想搞成如下形式:

HelloWorld!

Hello!

HaHa!

這樣解決衝突(即人為編輯)完成後我們儲存並關閉檔案。

注意!此時我們仍然處於merge的“過程中”,要想完成merge必須告訴Git:剛才衝突的檔案就按照我剛才儲存的這樣解決!  怎麼告訴Git呢?就是git add fileA.txt然後git commit -m "解決fileA檔案的衝突問題" 兩個命令。說白了就是再把最新的fileA.txt檔案加入Git的管理。

這些都做完之後,我們就已經渡過了merge過程回家包餃子了。

這裡需要理解一個Git的底層原理,這裡稱其為原理111:在將testBranch2分支merge到testBranch1分支中時,我們像上面那樣解決fileA.txt檔案的衝突。這樣Git就“知道了”上面這個衝突的解決辦法,即用形如:

HelloWorld!

Hello!

HaHa!

的內容來替換衝突檔案中的內容(因為這是剛才主人決定的)。那麼如果此後再將testBranch1分支merge到testBranch2分支中時,我們就不必要再手動解決衝突了,因為Git已經知道該怎麼做了。

這個原理會在後面的remote中得到應用,所以希望讀者在此能夠理解到位。

好了分割線=====================================================================================================================

下面就來講解一下什麼是Merge Request以及怎麼進行合理的Merge Request

舉一個比較簡單的情境:

你們公司的伺服器是Stash,上面有個正在開發的項目:ComRepository。這個項目有三個分支:master,worker1,worker2。那麼如果把這個項目clone下來之後,本地也會有三個分支:master, worker1, worker2。現在心裡要清楚哦,如小編第一篇文章所說,你所知道的是有6個分支的哦,伺服器上3個,你本地3個。而對於公司來說,他們不在乎每個員工本地的分支是怎樣,他們只在乎伺服器上的master分支是否運轉正常。因為伺服器上的master分支有可能就是公司發表項目時用的分支,所以這個分支上的代碼至關重要!

此時公司要求你就在worker1分支上開發吧!那麼你的開發流程是什麼呢?總之最終目的是要讓伺服器上的master分支有你開發好的代碼。

為了方便,後面依然把本地分支帶上尾碼(L),如worker1(L)。

一種思路:

在worker1(L)分支上開發,然後checkout到master(L)上,將worker1(L)分支merge到master(L)上來,然後將master(L)的新代碼push到伺服器的master上去。

這種思路是不該推薦的,如果我是老大,我是不會給你分配master分支的push許可權的。因為這樣太危險了,master分支是公司至關重要的分支,豈能讓你說push就push?這樣會讓公司的master上的代碼時刻處於危險之中。

第二種思路:

就是Merge Request的思路。我們每個開發人員都沒有master分支的push許可權,但是有pull許可權。即只能看,不能寫。但是我們有其它分支(如worker1和worker2)的pull和push許可權,反正這兩個分支也不是太重要的分支,開發人員愛怎麼糟蹋怎麼糟蹋。

那麼怎麼才能讓伺服器上的master分支得到更新呢?就是在伺服器上進行merge動作,即將伺服器上的worker1或者worker2分支上的內容merge到master分支上。這個過程就是Merge Request!所以伺服器上的merge動作不是靠你本地git merge命令來完成的,因為你只能操作你本地的分支,伺服器上的分支你八竿子打不著,怎麼可能輕易去“命令它”?所以這個merge動作基本上是在你們伺服器的網頁上進行的。比如:你在公司伺服器的網站上,發起一個Merge Request,請求把伺服器上的worker1分支merge到master分支上去,請求發起要添加一些審核人物,譬如你的老闆你的同事。當他們接收到這個Merge Request並同意後,可能會有個“同意”之類的按鈕,點擊之後就會在伺服器上把worker1分支merge到master中。這樣做就有效地保護了master分支的安全性。

伺服器上的worker1分支的更新就是靠你在本地worker1(L)上更新後push上去的。所以簡單的流程就是你早上來上班了,在worker1(L)分支上開發了一天,然後把工作內容都push到伺服器的worker1分支上去,再發起一個Merge Request請求把伺服器上的worker1分支merge到master上去,然後下班。

分割線==========================================================================================================================

以上就是結合remote和branch來講解的Merge Request。讀者瞭解之後,可以學習一下下面的非常重要的內容:

試想一下:如果你請求worker1往master上merge,我請求worker2也往master上merge。那麼久而久之,我們有可能都改了同一個檔案,就可能會產生衝突。那樣的話master分支上豈不是亂七八糟了?那麼怎麼才能讓master上的分支一直正確,不產生衝突呢?

下面我先說下流程:比如你是在worker1(L)分支上的開發人員,做完了一天的工作,先不要提Merge Request,而是先checkout到master(L)上,pull一下,把伺服器上master的代碼拉下來,是本地的master(L)是最新的master代碼,然後checkout回worker1(L)分支,將master(L)分支merge到worker1(L)上,這時候就有可能發生衝突了,因為可能在你下班之前,worker2分支的同事已經提交了代碼並且更新了master,而你們恰巧修改了同一個檔案。這時候衝突了不要緊,因為衝突是發生在你本地的,你只要在本地把衝突解決了,然後push到worker1分支上去,再提Merge Request,就不會使伺服器上的master產生代碼衝突了。

原因相信聰明的你已經明白,就是上面提到的原理111 。因為你在本地解決衝突的時候,Git就已經知道產生衝突以後該怎麼做了,而你又把這些指令碼push到了伺服器的worker1分支上,那麼伺服器的worker1分支在往master分支合并的時候自然就知道該怎麼做了。怎麼樣,Git強大吧?

順便再建議一下,當你早上來上班時,盡量也checkout到master(L),pull一下,再checkout回worker1(L),把master(L)分支的內容merge過來,完成之後再進行開發。這樣就是盡量保持在昨晚之後的最新的代碼上進行開發,以減少產生衝突的可能性嘛~


好了太晚了,今天就先講到這裡吧~這幾天還在持續忙碌中,所以更新會比較慢,見諒~







Git使用入門,使用原理解讀及如何在GitLab、GitHub或者Stash上管理項目(三)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.