如何使用Git提高研發團隊工作效率?

wow_worktile發表於2019-02-13

為什麼使用Git

隨著網際網路時代的來臨與發展,尤其分散式開發的大力引入,對於開發工程師來說,程式碼管理變成了頭等難題。10多個人或者更多的成員的研發團隊如何管理同一份程式碼,異地辦公如何跟同事有效的維護同一份程式碼?下面直接介紹Git,就不對Git和其他的版本管理工具進行比較了。

Git屬於分散式的版本控制系統,它具有以下特點:

  • Git中每個克隆(clone)的版本庫都是平等的。你可以從任何一個版本庫的克隆來建立屬於你自己的版本庫,同時你的版本庫也可以作為源提供給他人,只要你願意。
  • Git的每一次提取操作,實際上都是一次對程式碼倉庫的完整備份。
  • 提交完全在本地完成,無須別人給你授權,你的版本庫你作主,並且提交總是會成功。
  • 甚至基於舊版本的改動也可以成功提交,提交會基於舊的版本建立一個新的分支。
  • Git的提交不會被打斷,直到你的工作完全滿意了,PUSH給他人或者他人PULL你的版本庫,合併會發生在PULL和PUSH過程中,不能自動解決的衝突會提示您手工完成。
  • 衝突解決:在需要的時候才進行合併和衝突解決。
  • Git版本庫統一放在伺服器中
  • 可以為 Git 版本庫進行授權:誰能建立版本庫,誰能向版本庫PUSH,誰能夠讀取(克隆)版本庫,即許可權配置
  • 團隊的成員先將伺服器的版本庫克隆到本地;並經常的從伺服器的版本庫拉(PULL)最新的更新;
  • 團隊的成員將自己的改動推(PUSH)到伺服器的版本庫中,當其他人和版本庫同步(PULL)時,會自動獲取改變
  • 你完全可以在脫離Git伺服器所在網路的情況下,如移動辦公/出差時,照常使用程式碼庫
  • 你只需要在能夠接入Git伺服器所在網路時,PULL和PUSH即可完成和伺服器同步以及提交

選擇適合團隊的工作流

分散式工作流程:

同傳統的集中式版本控制系統(CVCS)不同,Git 的分散式特性使得開發者間的協作變得更加靈活多樣。在集中式系統中,每個開發者就像是連線在集線器上的節點,彼此的工作方式大體相像。而在 Git 中,每個開發者同時扮演著節點和集線器的角色——也就是說,每個開發者既可以將自己的程式碼貢獻到其他的倉庫中,同時也能維護自己的公開倉庫,讓其他人可以在其基礎上工作並貢獻程式碼。由此,Git 的分散式協作可以為你的專案和團隊衍生出種種不同的工作流程,接下來的章節會介紹幾種利用了 Git 的這種靈活性的常見應用方式。我們將討論每種方式的優點以及可能的缺點;你可以選擇使用其中的某一種,或者將它們的特性混合搭配使用。複製程式碼

Git 提供的有以下三種工作流程

  1. 集中式工作流
  2. 整合管理者工作流
  3. 司令官與副官工作流

目前我們團隊使用的是最簡單的方式,集中式工作流程,隨著研發團隊的壯大可能會選擇使用第二種,下面我們分別介紹下三種工作流

1.集中式工作流

集中式系統中通常使用的是單點協作模型——集中式工作流。一箇中心集線器,或者說倉庫,可以接受程式碼,所有人將自己的工作與之同步。若干個開發者則作為節點——也就是中心倉庫的消費者——並且與其進行同步。

git-集中式工作流.png

這意味著如果兩個開發者從中心倉庫克隆程式碼下來,同時作了一些修改,那麼只有第一個開發者可以順利地把資料推送回共享伺服器。第二個開發者在推送修改之前,必須先將第一個人的工作合併進來,這樣才不會覆蓋第一個人的修改。這和 Subversion (或任何 CVCS)中的概念一樣,而且這個模式也可以很好地運用到 Git 中。如果在公司或者團隊中,你已經習慣了使用這種集中式工作流程,完全可以繼續採用這種簡單的模式。只需要搭建好一箇中心倉庫,並給開發團隊中的每個人推送資料的許可權,就可以開展工作了。Git 不會讓使用者覆蓋彼此的修改。例如 John 和 Jessica 同時開始工作。 John完成了他的修改並推送到伺服器。接著 Jessica 嘗試提交她自己的修改,卻遭到伺服器拒絕。她被告知她的修改正通過非快進式(non-fast-forward)的方式推送,只有將資料抓取下來並且合併後方能推送。這種模式的工作流程的使用非常廣泛,因為大多數人對其很熟悉也很習慣。當然這並不侷限於小團隊。利用 Git 的分支模型,通過同時在多個分支上工作的方式,即使是上百人的開發團隊也可以很好地在單個專案上協作。

2.整合管理者工作流

Git 允許多個遠端倉庫存在,使得這樣一種工作流成為可能:每個開發者擁有自己倉庫的寫許可權和其他所有人倉庫的讀許可權。這種情形下通常會有個代表``官方''專案的權威的倉庫。要為這個專案做貢獻,你需要從該專案克隆出一個自己的公開倉庫,然後將自己的修改推送上去。接著你可以請求官方倉庫的維護者拉取更新合併到主專案。維護者可以將你的倉庫作為遠端倉庫新增進來,在本地測試你的變更,將其合併入他們的分支並推送回官方倉庫。這一流程的工作方式如下所示:

  • 專案維護者推送到主倉庫。
  • 貢獻者克隆此倉庫,做出修改。
  • 貢獻者將資料推送到自己的公開倉庫。
  • 貢獻者給維護者傳送郵件,請求拉取自己的更新。
  • 維護者在自己本地的倉庫中,將貢獻者的倉庫加為遠端倉庫併合並修改。
  • 維護者將合併後的修改推送到主倉庫。

git-整合管理者工作流.png

這是 GitHub 和 GitLab 等集線器式(hub-based)工具最常用的工作流程。人們可以容易地將某個專案派生成為自己的公開倉庫,向這個倉庫推送自己的修改,併為每個人所見。這麼做最主要的優點之一是你可以持續地工作,而主倉庫的維護者可以隨時拉取你的修改。貢獻者不必等待維護者處理完提交的更新——每一方都可以按照自己節奏工作。

3.司令官與副官工作流

這其實是多倉庫工作流程的變種。一般擁有數百位協作開發者的超大型專案才會用到這樣的工作方式,例如著名的 Linux 核心專案。被稱為副官(lieutenant)的各個整合管理者分別負責整合專案中的特定部分。所有這些副官頭上還有一位稱為司令官(dictator)的總整合管理者負責統籌。司令官維護的倉庫作為參考倉庫,為所有協作者提供他們需要拉取的專案程式碼。整個流程看起來是這樣的

  • 普通開發者在自己的特性分支上工作,並根據master分支進行變基。這裡是司令官的master分支。
  • 副官將普通開發者的特性分支合併到自己的master分支中。
  • 司令官將所有副官的master分支併入自己的master分支中。
  • 司令官將整合後的master分支推送到參考倉庫中,以便所有其他開發者以此為基礎進行變基。

git-司令官與副官工作流.png

這種工作流程並不常用,只有當專案極為龐雜,或者需要多級別管理時,才會體現出優勢。利用這種方式,專案總負責人(即司令官)可以把大量分散的整合工作委託給不同的小組負責人分別處理,然後在不同時刻將大塊的程式碼子集統籌起來,用於之後的整合。

介紹了上面三種工作流,想必你一定有想法使用哪一種了,選擇一個適合自己團隊的工作流,只要是嚴格按照這種規則執行的話,相信你的研發團隊對於程式碼的管理一定不會再混亂了,這也會大大提升團隊的工作效率。

管理 Git 分支

幾乎所有的版本控制系統都以某種形式支援分支。使用分支意味著你可以把你的工作從開發主線上分離開來,以免影響開發主線。在很多版本控制系統中,這是一個略微低效的過程——常常需要完全建立一個原始碼目錄的副本。對於大專案來說,這樣的過程會耗費很多時間。
有人把 Git 的分支模型稱為它的``必殺技特性'',也正因為這一特性,使得 Git 從眾多版本控制系統中脫穎而出。為何 Git 的分支模型如此出眾呢? Git 處理分支的方式可謂是難以置信的輕量,建立新分支這一操作幾乎能在瞬間完成,並且在不同分支之間的切換操作也是一樣便捷。與許多其它版本控制系統不同,Git 鼓勵在工作流程中頻繁地使用分支與合併,哪怕一天之內進行許多次。理解和精通這一特性,你便會意識到 Git 是如此的強大而又獨特,並且從此真正改變你的開發方式。複製程式碼

Git 建立分支

Git 是怎麼建立新分支的呢?很簡單,它只是為你建立了一個可以移動的新的指標。比如,建立一個 testing 分支,你需要使用git branch命令:

$ git branch testing複製程式碼

這會在當前所在的提交物件上建立一個指標

git-branch-testing.png

那麼,Git 又是怎麼知道當前在哪一個分支上呢?也很簡單,它有一個名為HEAD的特殊指標。請注意它和許多其它版本控制系統(如 Subversion 或 CVS)裡的HEAD概念完全不同。在 Git 中,它是一個指標,指向當前所在的本地分支。在本例中,你仍然在master分支上。因為git branch命令僅僅建立一個新分支,並不會自動切換到新分支中去。

git-branch-head.png

你可以簡單地使用git log命令檢視各個分支當前所指的物件。提供這一功能的引數是--decorate

$ git log --oneline --decoratef30ab (HEAD, master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project複製程式碼

正上,當前mastertesting 分支均指向校驗和以f30ab開頭的提交物件。

分支切換

要切換到一個已存在的分支,你需要使用git checkout命令。我們現在切換到新建立的testing分支去:

$ git checkout testing複製程式碼

這樣HEAD就指向testing分支了。

git-branch-head-testing.png

那麼,這樣的實現方式會給我們帶來什麼好處呢?現在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'複製程式碼

git-branch-test-commit.png

如上圖所示,你的testing分支向前移動了,但是master分支卻沒有,它仍然指向執行git checkout時所指的物件。這就有意思了,現在我們切換回master分支看看:

$ git checkout master複製程式碼

git-checkout-master.png

這條命令做了兩件事。一是使 HEAD 指回master分支,二是將工作目錄恢復成master分支所指向的快照內容。也就是說,你現在做修改的話,專案將始於一個較舊的版本。本質上來講,這就是忽略testing分支所做的修改,以便於向另一個方向進行開發。
現在我們稍微再做些修改並commit:

$ vim test.rb
$ git commit -a -m 'made other changes'複製程式碼

現在,這個專案的提交歷史已經產生了分叉。因為剛才你建立了一個新分支,並切換過去進行了一些工作,隨後又切換回 master 分支進行了另外一些工作。上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,並在時機成熟時將它們合併起來。而所有這些工作,你需要的命令只有branchcheckoutcommit

git-master-commit.png

Git 合併分支

接下來我們們舉個稍微複雜點的例子,三個分支的分別處理不同的事情,最後合併到一塊
首先,我們假設你正在你的專案上工作,並且已經有一些提交, 如下圖:

git-merge-1.png

現在,你已經決定要解決你的公司使用的問題追蹤系統中的 #53 問題。想要新建一個分支並同時切換到那個分支上,你可以執行一個帶有-b引數的git checkout命令:

$ git checkout -b iss53
Switched to a new branch "iss53"複製程式碼

它是下面兩條命令的簡寫:

$ git branch iss53
$ git checkout iss53複製程式碼

git-merge-2.png

你繼續在 #53 問題上工作,並且做了一些提交。在此過程中,iss53分支在不斷的向前推進,因為你已經檢出到該分支(也就是說,你的HEAD指標指向了iss53分支)

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'複製程式碼

git-merge-3.png

當你在iss53這個分支上正在順暢的工作,這時候有個特別緊急的問題需要你來修復,那麼為了不影響iss53的正常工作,你需要做的是重新切換到master分支上來,在master分支的基礎上再建立一個新的分支 hotfix ,然後在hotfix分支解決緊急的問題。

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address 
1 file changed, 2 insertions(+)複製程式碼

git-merge-4.png

這個時候hotfix分支上的問題徹底解決了,你需要合併到master分支,並且部署上線, 那麼你只需要在master分支使用git merge命令就可以了

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward index.html | 2 ++ 
1 file changed, 2 insertions(+)複製程式碼

在合併的時候,你應該注意到了"快進(fast-forward)"這個詞。由於當前master分支所指向的提交是你當前提交(有關 hotfix 的提交)的直接上游,所以 Git 只是簡單的將指標向前移動。換句話說,當你試圖合併兩個分支時,如果順著一個分支走下去能夠到達另一個分支,那麼 Git 在合併兩者的時候,只會簡單的將指標向前推進(指標右移),因為這種情況下的合併操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。現在,最新的修改已經在master分支所指向的提交快照中了。

git-merge-5.png

關於這個緊急問題的解決方案發布之後,你準備回到被打斷之前時的工作中。然而,你應該先刪除hotfix分支,因為你已經不再需要它了, master分支已經指向了同一個位置。你可以使用帶-d選項的git branch命令來刪除分支:

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).複製程式碼

現在你可以切換回你正在工作的分支繼續你的工作,也就是針對iss53分支

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)複製程式碼

git-merge-6.png

這個時候 #53 問題解決後你就可以把程式碼合併到master了,操作跟剛才的htofix分支處理方式一樣

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.index.html | 1 +
1 file changed, 1 insertion(+)複製程式碼

但是這和你之前合併hotfix分支的時候看起來有一點不一樣。在這種情況下,你的開發歷史從一個更早的地方開始分叉開來(diverged)。因為,master分支所在提交併不是iss53分支所在提交的直接祖先,Git 不得不做一些額外的工作。出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(C4和C5)以及這兩個分支的工作祖先(C2),做一個簡單的三方合併。

git-merge-7.png

和之間將分支指標向前推進所不同的是,Git 將此次三方合併的結果做了一個新的快照並且自動建立一個新的提交指向它。這個被稱作一次合併提交,它的特別之處在於他有不止一個父提交。

git-merge-8.png

這個時候如何不需要iss53分支的話,你也可以刪除iss53分支了

遠端分支

github為例,目前很多開源專案以及公司的研發專案程式碼一般都託管在github,那麼就出現了遠端倉庫,遠端分支等這些概念。
下面我們從github遠端倉庫clone下來一份程式碼

git-remote-1.png

如果你在本地的master分支做了一些工作,然而在同一時間,其他人推送提交到git@github.com:glj1102/git_test.git 並更新了它的master分支,那麼你的提交歷史將向不同的方向前進。也許,只要你不與 origin 伺服器連線,你的origin/master指標就不會移動。

git-remote-branch-1.png

如果要同步你的工作,執行git pull命令。這個命令是抓取遠端分支資料到本地分支,並且更新本地資料庫,移動origin/master指標指向新的、更新後的位置。同時你也可以執行 git push命令把你本地修改的資料提交到遠端分支。

實時跟蹤和監控團隊程式碼操作記錄

我們使用的是 Worktile + github 來管理團隊的,平時團隊溝通,任務分配都是通過Worktile來做的,那麼 Worktile 與github如何關聯的呢?

Worktile繫結github程式碼倉儲

在Worktile的後臺管理 > 服務管理中找到github,點選新增

worktile-git-1.png

下一步會讓你選擇Worktile的一個聊天群組,之後github的提交記錄就會傳送到這個群組中:

worktile-git-2.png

新增服務之後需要進行一些配置,配置方式有兩種,一種是授權模式,選擇倉儲,選擇事件, 另一種是普通模式,這種模式Worktile會生成一個Webhook連結,拿到這個連結可以直接在github倉儲中進行Webhook配置:

worktile-git-3.png

worktile-git-4.png

具體的配置Worktile後臺github服務設定中有教程。

Worktile接收github傳送的操作記錄

根據不配置時選擇的事件不同,github會傳送不同的記錄訊息

worktile-git-5.png

想了解更多關於Worktile,可以點選Worktile檢視更多哦~

總結

通過上面對Git的介紹,對於團隊管理者來說,如何使用Git來有效的管理團隊程式碼應該會有最基本的概念,那接下來就需要你真正的花時間來實踐了。那麼對於Git的命令集網上有很多例子的,下面我這裡介紹兩本Git的基本入門教程:

Git 簡易指南 www.bootcss.com/p/git-...
Git 圖解 marklodato.github.io/v...


文章來源:Worktile技術部落格

歡迎訪問交流更多關於技術及協作的問題。 

文章轉載請註明出處。 

相關文章