團(tuán)隊(duì)準(zhǔn)備從 SVN 切換到自建的 Git 開(kāi)發(fā)模型,選擇了 Gitlab CE 版本作為源碼管理平臺(tái)。本文描述的開(kāi)發(fā)模型適用于嵌入式開(kāi)發(fā)領(lǐng)域,這與 Web 相關(guān)產(chǎn)品開(kāi)發(fā)模型有較大差別。
Gitlab CE 是一個(gè)開(kāi)源的基于 Git 的源代碼管理軟件,本文介紹基于 Gitlab 的源代碼管理規(guī)范及典型工作流程。關(guān)于 Gitlab 的安裝,可參閱官方文檔。Gitlab 是一個(gè)非常強(qiáng)大的系統(tǒng),基本上可以搭建一個(gè)類似 Github 這樣的私有網(wǎng)站了。本文描述的,只是針對(duì)嵌入式開(kāi)發(fā)領(lǐng)域,進(jìn)行項(xiàng)目管理,權(quán)限管理,代碼評(píng)審,產(chǎn)品分支管理等有限領(lǐng)域的一些實(shí)踐規(guī)則。
1 用戶管理
Gitlab 安裝完成后,會(huì)自動(dòng)創(chuàng)建一個(gè) root 帳戶,這個(gè)帳戶是系統(tǒng)管理員。系統(tǒng)管理員有最高的系統(tǒng)權(quán)限,可以查看所有的項(xiàng)目,并給適當(dāng)?shù)捻?xiàng)目分配權(quán)限。當(dāng)系統(tǒng)管理員第一次登錄時(shí),系統(tǒng)會(huì)強(qiáng)制要求修改密碼。
用戶可以自己注冊(cè),也可以由系統(tǒng)管理員創(chuàng)建用戶。這里推薦由系統(tǒng)管理員創(chuàng)建用戶,并設(shè)置初始密碼,然后告訴用戶。用戶第一次登錄時(shí),系統(tǒng)要求修改密碼。推薦用戶登錄后,修改個(gè)人頭像,并使用真實(shí)頭像,這樣后續(xù)查看修改記錄時(shí)可以一眼看出哪個(gè)人修改了什么內(nèi)容。

操作演練(建議實(shí)際安裝完成后,演練一遍下面的任務(wù)):
- 在 Gitlab 系統(tǒng)上創(chuàng)建四個(gè)用戶,分別是 user1, user2, user3, user4
- 使用 user1 登錄系統(tǒng)
2 項(xiàng)目管理
對(duì)正式的項(xiàng)目,推薦由系統(tǒng)管理員來(lái)進(jìn)行項(xiàng)目管理工作,并分配權(quán)限。系統(tǒng)管理員賬戶一般由軟件開(kāi)發(fā)經(jīng)理持有,這樣確保不會(huì)有人能隨意修改系統(tǒng),也不會(huì)有人能看到全部的項(xiàng)目相關(guān)資料。
2.1 創(chuàng)建項(xiàng)目
創(chuàng)建項(xiàng)目推薦在 Gitlab 網(wǎng)頁(yè)上操作,簡(jiǎn)單易懂。需要注意,創(chuàng)建項(xiàng)目時(shí),一定要選擇 “Private” 的項(xiàng)目。Public 的項(xiàng)目注冊(cè)用戶都可以看得到。而 Private 的項(xiàng)目只有經(jīng)過(guò)明確邀請(qǐng)的用戶才能看得到這個(gè)項(xiàng)目。這對(duì)項(xiàng)目的權(quán)限管理有極大的幫助。

操作演練:由系統(tǒng)管理員創(chuàng)建一個(gè)示例項(xiàng)目 demo
2.2 設(shè)置項(xiàng)目成員
不同的帳戶具有不同的項(xiàng)目權(quán)限。Gitlab 有多種角色的帳戶,還可以基于 Group 來(lái)進(jìn)行權(quán)限管理。在需求不是特別復(fù)雜的情況下,我們推薦采用最簡(jiǎn)單的權(quán)限模型來(lái)管理項(xiàng)目權(quán)限。
- Master 賬戶是這個(gè)項(xiàng)目的主要負(fù)責(zé)人,他可以直接修改代碼并提交,不需要經(jīng)過(guò)審核。除此之外,Master 用戶還可以對(duì) Developer 提交的代碼進(jìn)行評(píng)審,并最終決定是合并進(jìn)主干還是退回重新修改。
- Developer 賬戶是這個(gè)項(xiàng)目的貢獻(xiàn)者,它可以查看代碼并下載代碼,但不能直接提交代碼,提交的代碼需要經(jīng)過(guò) Master 審核后才能合并進(jìn)主干。
- 其他的角色可根據(jù)實(shí)際情況酌情使用,比如可以給 SQA 開(kāi)通 Reporter 角色的賬戶,用來(lái) report issue 。
Gitlab 默認(rèn)的角色列表項(xiàng)目權(quán)限可參閱官方文檔項(xiàng)目角色與權(quán)限。需要注意,這里的 Master 指的是用戶在項(xiàng)目上的角色,而不是指代碼的主干。

操作演練:
- 添加一個(gè)用戶作為 Master 賬戶
- 添加一個(gè)用戶作為 Developer 帳戶
3 Git Flow
Git Flow 是一種基于 Git 的開(kāi)發(fā)流程。其主要思想是,以 Master 為主線,所有的新功能開(kāi)發(fā)在 Branch 上完成,等開(kāi)發(fā)完成后,合并到 Master 里。
原則:Master 里包含的永遠(yuǎn)是穩(wěn)定(至少經(jīng)過(guò)初步測(cè)試和代碼評(píng)審)的源代碼??梢灾苯釉?Master 上把代碼進(jìn)行部署(編譯并發(fā)布給測(cè)試部的版本)。

主要分成幾個(gè)步驟:
- 創(chuàng)建分支
- 在分支上提交代碼
- 創(chuàng)建 Merge Request
- 代碼評(píng)審
- 合并到主干
接下來(lái),我們來(lái)討論幾個(gè)典型的場(chǎng)景下的 Git FLow 開(kāi)發(fā)模型。熟悉 Github 的同學(xué)可能對(duì) Merge Request 這個(gè)稱呼感到奇怪,實(shí)際上它就是 Pull Request,不同的叫法而已。
3.1 Master 用戶直接在主干上開(kāi)發(fā)
這種開(kāi)發(fā)模式一般用在一些不需要團(tuán)隊(duì)協(xié)作的小功能的開(kāi)發(fā)上。這種開(kāi)發(fā)模式和 SVN 開(kāi)發(fā)模式基本相同。
1. 下載代碼
git clone http://user1@192.168.56.101/user1/demo.git
2. 編寫代碼,驗(yàn)證后提交
git commit -am "My feature is ready"
3. 推送到主干
git push
便捷與安全有時(shí)是相互矛盾的。這種開(kāi)發(fā)模式雖然簡(jiǎn)潔,但沒(méi)有強(qiáng)制的代碼評(píng)審,是否采用需要根據(jù)實(shí)際情況考量。
操作演練:由 Master 用戶直接提交代碼修改到主干
3.2 新功能分支開(kāi)發(fā)流程
這種工作一般在一個(gè)較大的新功能開(kāi)發(fā)時(shí)使用,一般需要進(jìn)行團(tuán)隊(duì)協(xié)作,即由幾個(gè)人共同來(lái)開(kāi)發(fā)。這是最經(jīng)典的 Git Flow 開(kāi)發(fā)流程,在 Bug Fix 時(shí)也可以使用這個(gè)開(kāi)發(fā)模式。典型步驟如下:
1. 創(chuàng)建功能開(kāi)發(fā)分支
創(chuàng)建新功能分支,并把分支推送到遠(yuǎn)程代碼倉(cāng)庫(kù)。這個(gè)動(dòng)作也可以在 Gitlab 網(wǎng)頁(yè)上操作。
git clone http://user1@192.168.56.101/user1/demo.git
cd demo
git checkout -b feature2
git push origin feature2
2. 其他開(kāi)發(fā)人員下載代碼,并在分支上開(kāi)發(fā)新功能
git clone http://user2@192.168.56.101/user1/demo.git
git checkout feature2
git config user.name "user2"
git config user.email "user2@example.com"
3. 測(cè)試新功能并提交
git commit -am "Developer user2 for Feature 2"
git push
4. 創(chuàng)建 Merge Request
步驟 2 和 3 可以無(wú)限制次數(shù)地進(jìn)行,直到新功能開(kāi)發(fā)完成,并完成單元測(cè)試為止。當(dāng)新功能開(kāi)發(fā)完成后,需要在 Gitlab 網(wǎng)頁(yè)上創(chuàng)建合并請(qǐng)求。提交 Merge Request 的目的是為了發(fā)起代碼評(píng)審流程。

5. 代碼評(píng)審
合并請(qǐng)求可以指定具有 Master 角色的用戶進(jìn)行 Review。如果 Review 通過(guò),則直接會(huì)把新功能合并進(jìn)代碼主干。如果 Review 不通過(guò),則評(píng)審人員可以直接關(guān)閉這個(gè) Merge Request。等待開(kāi)發(fā)者重新修改代碼,并重新提交 Merge Request。

評(píng)審過(guò)程中,可以直接在 Gitlab 網(wǎng)頁(yè)上,對(duì)著代碼寫上評(píng)審意見(jiàn)。這些評(píng)審意見(jiàn)對(duì)應(yīng)的開(kāi)發(fā)者都會(huì)看到。

6. 更新本地代碼副本
當(dāng)新功能合并到代碼主干后,其他開(kāi)發(fā)人員可以更新服務(wù)器上的最新代碼到自己本地的工作副本中。
git pull
操作演練:
- Master 用戶創(chuàng)建一個(gè)遠(yuǎn)程分支
- Developer user2 下載代碼,切換到開(kāi)發(fā)分支,并提交代碼到開(kāi)發(fā)分支
- Developer user3 下載代碼,切換到開(kāi)發(fā)分支,并提交代碼到開(kāi)發(fā)分支
- Master user1 下載代碼,切換到開(kāi)發(fā)分支,并提交代碼到開(kāi)發(fā)分支
- 創(chuàng)建合并請(qǐng)求
- 代碼評(píng)審
- 評(píng)審不過(guò),發(fā)回重新修改
- Developer user2 重新修改代碼,并提交到開(kāi)發(fā)分支
- 重新發(fā)起合并請(qǐng)求
- 代碼評(píng)審
- 評(píng)審?fù)ㄟ^(guò),合并到代碼主干
- 刪除開(kāi)發(fā)分支
- 開(kāi)發(fā)者更新本地代碼
3.3 Developer 用戶直接在主干上開(kāi)發(fā)
這種開(kāi)發(fā)模式一般用在一些不需要協(xié)作的小功能開(kāi)發(fā)或 Bug 修復(fù)上。由于 Developer 用戶沒(méi)有權(quán)限把修改的代碼直接提交到主干上。所以,需要先 Fork 一個(gè)本地分支,然后本地修改后,發(fā)起一個(gè) Merge Request ,由 Master 用戶進(jìn)行代碼評(píng)審,合格后由 Master 用戶把代碼合并到主干。
1. 開(kāi)發(fā)者 Fork 一份基線
這一步驟必須在 Gitlab 網(wǎng)頁(yè)端進(jìn)行。比如,我們使用 user2 Fork 一個(gè)由 user1 創(chuàng)建的 demo 項(xiàng)目,則其 Git 地址為:
http://user2@192.168.56.101/user2/demo.git
注意和原來(lái)直接從 user1 的 demo 項(xiàng)目的 Git 地址比較 http://user2@192.168.56.101/user1/demo.git 。
2. 開(kāi)發(fā)者下載 Fork 的基線代碼
git clone http://user2@192.168.56.101/user2/demo.git
3. 開(kāi)發(fā)者修改代碼,測(cè)試,并提交
git push origin master
4. 提交 Merge Request
這一步驟必須在 Gitlab 網(wǎng)頁(yè)上進(jìn)行。點(diǎn)擊 Merge Requests -> New Merge Request 來(lái)創(chuàng)建一個(gè)合并請(qǐng)求。需要指定合并請(qǐng)求的源分支和目的分支。

5. 代碼評(píng)審
指定的代碼評(píng)審者可以查看這個(gè)合并請(qǐng)求,并選擇直接關(guān)閉或者合并到主干。如果關(guān)閉,則一般會(huì)寫上評(píng)審不通過(guò)的理由,然后由開(kāi)發(fā)者重新修改,并重新提交合并請(qǐng)求。如果通過(guò)評(píng)審,則代碼會(huì)合并到主干上。
6. 開(kāi)發(fā)者更新本地代碼
當(dāng) Developer 角色的開(kāi)發(fā)者 Fork 了一份代碼后,本地 Git 倉(cāng)庫(kù)里實(shí)際是“追蹤”開(kāi)發(fā)者 Fork 出來(lái)的這份代碼,而不是原始的代碼倉(cāng)庫(kù)里的代碼。如下所示:
$ git remote -v
origin http://user2@192.168.56.101/user2/demo.git (fetch)
origin http://user2@192.168.56.101/user2/demo.git (push)
此時(shí)要怎么樣把原始的代碼倉(cāng)庫(kù)里的代碼更新到本地呢?比如,另外一個(gè)開(kāi)發(fā)者合并了一個(gè)新的功能到原始代碼的主干上,怎么樣把這個(gè)代碼更新到本地呢?進(jìn)而更新到 Fork 出來(lái)的代碼倉(cāng)庫(kù)里呢?可以使用以下的方法:
首先,把原始的 Git 代碼倉(cāng)庫(kù)地址添加到本地:
$ git remote add upstream http://user2@192.168.56.101/user1/demo.git
查看添加后的情況:
$ git remote -v
origin http://user2@192.168.56.101/user2/demo.git (fetch)
origin http://user2@192.168.56.101/user2/demo.git (push)
upstream http://user2@192.168.56.101/user1/demo.git (fetch)
upstream http://user2@192.168.56.101/user1/demo.git (push)
接著,把原始 Git 代碼倉(cāng)庫(kù)里的代碼下載下來(lái),只是把數(shù)據(jù)庫(kù)下載下來(lái)而已,并沒(méi)有合并到本地分支:
git fetch upstream
下一步,把下載下來(lái)的代碼合并到本地分支:
git merge upstream/master
執(zhí)行這一步時(shí)需要注意,需要確保本地沒(méi)有未提交的修改,否則到時(shí)處理代碼沖突會(huì)比較麻煩。上面的兩條指令也可以由一條完成,即 git pull upstream master 。
最后,把從原始 Git 代碼倉(cāng)庫(kù)合并下來(lái)的代碼,提交到 Fork 出來(lái)的遠(yuǎn)程代碼倉(cāng)庫(kù)里。
git commit -am "Merge from upstream"
git push origin master
操作演練:
- 開(kāi)發(fā)者 Fork 一份基線
- 開(kāi)發(fā)者下載 Fork 出來(lái)的基線代碼到本地
- 開(kāi)發(fā)者修改代碼并提交
- 開(kāi)發(fā)者再次修改代碼,并再次提交
- 開(kāi)發(fā)者推送本地提交到 Fork 出來(lái)的遠(yuǎn)程代碼倉(cāng)庫(kù)上
- 開(kāi)發(fā)者發(fā)起 Merge Request
- 代碼評(píng)審,不通過(guò),關(guān)閉 Merge Request
- 開(kāi)發(fā)者根據(jù)評(píng)審意見(jiàn)重新修改代碼,并提交,然后推送到遠(yuǎn)程代碼倉(cāng)庫(kù)
- 開(kāi)發(fā)者發(fā)起 Merge Request
- 代碼評(píng)審,通過(guò),合并到主干
- 其他開(kāi)發(fā)者提交代碼到主干
- 開(kāi)發(fā)者更新本地代碼到原始主干,并且使 Fork 出來(lái)的遠(yuǎn)程代碼倉(cāng)庫(kù)與原始主干保持同步
4 分支及標(biāo)簽管理
分支的目的是為了做代碼隔離。典型的代碼隔離如前面介紹的新功能開(kāi)發(fā)分支,另外一個(gè)典型的目的是為己發(fā)布的產(chǎn)品拉獨(dú)立的分支來(lái)維護(hù),或者雖然產(chǎn)品還沒(méi)發(fā)布,但由于并行開(kāi)發(fā)多個(gè)產(chǎn)品線,在產(chǎn)品測(cè)試后期,就拉出獨(dú)立分支,隔離主干的頻繁變動(dòng)。這背后的原因是由于不同的分支代碼的質(zhì)量和穩(wěn)定性是不一樣的。一般來(lái)講,新功能開(kāi)發(fā)分支穩(wěn)定性最差,因?yàn)橹挥虚_(kāi)發(fā)者做了單元測(cè)試而已。其次是主干,做了代碼評(píng)審,如果有自動(dòng)化測(cè)試系統(tǒng),那么還會(huì)做設(shè)備自動(dòng)測(cè)試和系統(tǒng)自動(dòng)測(cè)試。一般情況下,產(chǎn)品的集成測(cè)試版本以及前面幾個(gè)系統(tǒng)測(cè)試版本會(huì)在主干上直接編譯。最穩(wěn)定的是產(chǎn)品分支,己發(fā)布或即將發(fā)布的產(chǎn)品的測(cè)試力度和強(qiáng)度是最大的,其穩(wěn)定性也是最好的。綜上,我們開(kāi)發(fā)流程里采用的分支類型包含:
- 開(kāi)發(fā)分支:為了開(kāi)發(fā)新功能而臨時(shí)創(chuàng)建的,當(dāng)合并進(jìn)主干后,這種分支可以刪除
- 代碼主干:一直存在,且在 Gitlab 里具有保護(hù)屬性,即普通的 Developer 要修改這個(gè)分支上的代碼時(shí)需要經(jīng)過(guò)評(píng)審
- 產(chǎn)品分支:產(chǎn)品即將發(fā)布或發(fā)布后創(chuàng)建,然后一直存在,且在 Gitlab 里具有保護(hù)屬性
4.1 產(chǎn)品分支管理
假設(shè),我們有一個(gè)產(chǎn)品已經(jīng)經(jīng)過(guò)了 8 輪的系統(tǒng)測(cè)試,目前軟件整體上比較穩(wěn)定,按計(jì)劃再測(cè)試 2 輪即會(huì)正式發(fā)布。而當(dāng)前,主干上頻繁地有新功能合并進(jìn)來(lái),這些新功能又是這個(gè)產(chǎn)品不需要的。產(chǎn)品軟件負(fù)責(zé)人經(jīng)過(guò)討論,決定拉出獨(dú)立的產(chǎn)品分支來(lái)管理,以避免新合并進(jìn)來(lái)的新功能由于穩(wěn)定性較差,測(cè)試不全面,影響即將發(fā)布的產(chǎn)品的質(zhì)量。
在創(chuàng)建功能開(kāi)發(fā)分支時(shí),我們介紹了命令行創(chuàng)建遠(yuǎn)程分支的方法,實(shí)際上在 Gitlab 網(wǎng)頁(yè)上操作更簡(jiǎn)單。

需要注意,默認(rèn)情況下創(chuàng)建出來(lái)的分支是不處于保護(hù)狀態(tài)的。即任何的 Developer 角色的人都可以推送代碼到這個(gè)分支,這是我們不希望看到的。越到項(xiàng)目后期,代碼的修改越需要謹(jǐn)慎地進(jìn)行評(píng)審。所以,創(chuàng)建完分支,需要把分支設(shè)置為 Proteced 屬性,這樣可以對(duì)產(chǎn)品分支的代碼修改進(jìn)行嚴(yán)格地控制。

大家可以看到,這里設(shè)置的保護(hù)級(jí)別比主干更高,即沒(méi)有人能直接推送代碼到這個(gè)分支上。任何人,包括 Master 角色的開(kāi)發(fā)者提交代碼時(shí),也只能通過(guò)創(chuàng)建 Bug Fix 分支,然后在分支上修改代碼,驗(yàn)證,最后通過(guò)創(chuàng)建 Merge Request 來(lái)強(qiáng)制進(jìn)行代碼評(píng)審。當(dāng)然,Master 角色的開(kāi)發(fā)者可以自己評(píng)審自己的代碼,但起碼強(qiáng)制進(jìn)行了二次確認(rèn)。相應(yīng)地,為了安全,也可以把主干的保護(hù)級(jí)別設(shè)置成和產(chǎn)品分支的保護(hù)級(jí)別一樣,這樣就沒(méi)有人能直接向主干推送代碼,都必須通過(guò) Merge Request 進(jìn)行代碼評(píng)審后才可以合并代碼到主干上。
創(chuàng)建完分支后,后續(xù)這個(gè)產(chǎn)品的版本就直接從這個(gè)分支上編譯,而不再?gòu)闹鞲缮暇幾g。假設(shè),這個(gè)時(shí)候這個(gè)產(chǎn)品上修改了一個(gè) Bug,并提交到了這個(gè)分支上。那么這個(gè)提交要不要也合并到主干上呢?答案是原則上需要合并到主干上,但也不能強(qiáng)制要求。如果這個(gè) Bug 只和這個(gè)產(chǎn)品相關(guān),而和其他產(chǎn)品無(wú)關(guān),而且提交到主干上需要考慮不同產(chǎn)品的兼容性問(wèn)題,復(fù)雜度增加很多,此時(shí)可以允許不提交到主干。如果是最終決策不提交到主干,這個(gè)提交需要在 commit log 里注明 PSBF: (Product Specific Bug Fix) 前綴,以方便以后根據(jù)前綴來(lái)查詢。但如果這個(gè) Bug 是個(gè)普遍存在的 Bug ,主干上的其他衍生產(chǎn)品也會(huì)有這樣的 Bug,則這個(gè) Bug 的修改必須合并到主干上。由于提交到產(chǎn)品分支的修改必須強(qiáng)制經(jīng)過(guò)評(píng)審,所以在評(píng)審的時(shí)候可以告訴開(kāi)發(fā)者是否需要把這個(gè)修改合并進(jìn)主干。
另外一個(gè)問(wèn)題,如果一個(gè)新功能分支合并到主干上了,這個(gè)時(shí)候一般是不需要合并到產(chǎn)品分支的。但如果主干上合并進(jìn)了一個(gè) Bug Fix 修改,此時(shí)要不要合并進(jìn)產(chǎn)品分支呢?答案是看情況,不能一概而論。如果這個(gè) Bug Fix 和具體的產(chǎn)品無(wú)關(guān),則不需要合并進(jìn)產(chǎn)品分支。如果這個(gè) Bug Fix 和具體的產(chǎn)品相關(guān),但不嚴(yán)重,屬于 normal 或 minor 級(jí)別的 Bug,則根據(jù)產(chǎn)品的生命周期判斷,可以合并也可以不合并進(jìn)產(chǎn)品分支。如果這個(gè) Bug Fix 和具體的產(chǎn)品相關(guān),且非常嚴(yán)重,則必須合并進(jìn)產(chǎn)品分支。經(jīng)過(guò)討論后,還可能需要馬上發(fā)起一個(gè) ECR/ECN 流程來(lái)下發(fā)新軟件。

操作演練:
- 創(chuàng)建一個(gè)產(chǎn)品分支,并設(shè)置相應(yīng)的保護(hù)級(jí)別
- Master 角色的用戶提交 Bug 修改流程,演示強(qiáng)制代碼評(píng)審的效果
- 主干上合并了一個(gè)嚴(yán)重的問(wèn)題修改,同時(shí)也需要合并到產(chǎn)品分支
4.2 標(biāo)簽管理
標(biāo)簽的目的是為了做標(biāo)記,它能唯一地標(biāo)識(shí)代碼倉(cāng)庫(kù)中某個(gè)“時(shí)刻”的代碼。典型地,所有的正式發(fā)布的軟件版本會(huì)都會(huì)打上標(biāo)簽,以方便以后追溯。再如特單版本正式發(fā)布后,也會(huì)打上標(biāo)簽。標(biāo)簽的命名和軟件命名采用相同的規(guī)則,這樣方便從己發(fā)布的軟件直接找到對(duì)應(yīng)的源碼。

5 其他
有一個(gè)非常重要的原則,需要強(qiáng)調(diào),開(kāi)發(fā)者需要盡量確保自己 Fork 出來(lái)的基線以及本地的代碼副本和原基線的主干保持同步。即需要經(jīng)常更新主干上的代碼。否則,會(huì)給后續(xù)的代碼評(píng)審以及代碼合并造成很大的無(wú)謂的工作量。其次,為了減少代碼合并時(shí)的工作量,推薦開(kāi)發(fā)者在提交 Merge Request 前,把自己的工作分支更新到主干代碼上,解決完沖突,驗(yàn)證完代碼有效性后,再提交 Merge Request。這里也提醒代碼評(píng)審者注意,如果評(píng)審一個(gè) Merge Request 時(shí),發(fā)現(xiàn)代碼有沖突,不能進(jìn)行 Fast-Forward 合并,而需要手動(dòng)合并沖突,則開(kāi)發(fā)者必定沒(méi)有在提交 Merge Request 時(shí)更新到最新的主干上。此時(shí)代碼評(píng)審者完全可以拒絕這個(gè)合并請(qǐng)求,并要求開(kāi)發(fā)者更新到最新主干上,合并完沖突,驗(yàn)證通過(guò)后重新提交 Merge Request。
推薦閱讀阮一峰的兩篇關(guān)于 Git 的博客,簡(jiǎn)潔明了,清晰易懂。分別是《Git 工作流程》和《Git遠(yuǎn)程操作詳解》。
關(guān)于 Git 的系統(tǒng)性基礎(chǔ)知識(shí),可參閱 Pro Git 這本開(kāi)源圖書。關(guān)于 Windows 平臺(tái)的 Git 客戶端,如果喜歡命令行的用戶,可使用 Git for windows。對(duì)于習(xí)慣 TortoiseSVN 客戶端的用戶,推薦使用 TortoiseGit。
(完)