版本控制、Git及其在企業中的應用
充分理解Git,包括它的優點與限制,再決定它是否適合你的企業
本文旨在重點分析企業在應用Git的過程中通常所體會到的一些關鍵的優缺點,在此基礎上提出一系列需要你的企業進行深思的問題,以決定Git是否適合你,以及轉而使用Git時所需要考慮的各種因素。
Git不同于你所購買的各種商業工具,而是眾多成功的開源版本控制工具家族中的一名成員。它的出現是因為Linux內核開發社區與BitKeeper這一商業工具的分道揚鑣而誕生的。在2014年Eclipse社區調查問卷中的結果顯示,Git在代碼管理工具中處于領先地位,在這些軟件開發者中的使用比例達到了三分之一。雖然這一數據僅僅統計了開源軟件的結果,但毫無疑問,Git對于企業中的軟件開發者來說也是一顆逐漸升起的新星。
Git的優點
了解Git的迷人與獨特之處,能夠幫助你評估Git是否適用于你的團隊或企業。這門工具最顯著的不同之處在于,Git中的一切都是本地的,包括代碼 庫本身乃至各種操作。對于版本控制工具功能的任何期待都可以在Git中得到滿足。無論是查詢歷史、還是創建分支與合并操作,本地操作天然地具有快速的特 征,通過網絡與服務器之間的通信過程已在Git中降至最低。由于所有數據都已保存在本地,因此每位開發者都可以在無需與服務器進行通信的前提下開展工作, 他們可以自由地選擇任何地方進行工作,只要有一臺電腦就好。
在版本控制中,合并通常是最令人煩惱的一項任務,但Git使這一流程得到了改善,它為不同的合并用例提供了強大的、特定的合并策略。無論你打算合并 分支、對分支的origin進行rebase操作、還是需要進行選擇性的合并提交,在Git中都能夠找到相應的功能以滿足你的需求。Git的分布式模型為 開發者提供了極大的自由度,他們可以隨意選擇能夠為他們帶來最大價值的方式使用版本控制系統。開發者在本地可以盡早提交、頻繁提交,而當他們需要將變更交 付給屬于上游團隊的用戶時,則可以選擇以較大粒度的、更富于邏輯性的塊進行提交。
開發者都希望能夠按照他們所需的任何方式進行工作,與他們所使用過的其它工具相比,開發者在使用Git時能夠對于操作的類型與方式有更細粒度的控 制。Git中的大量命令通常可以分為兩類:高層命令(porcelain)與底層命令(plumbing)。有人將其比作一個水槽,意思是說:你可以通過 傳統的工具與高層命令打交道,這部分命令提供了工具的一種抽象和受控的界面。但在Git中,你也可以打開它的面盆、撥出塞子、以改變版本控制執行的方式, 包括重寫歷史等等。無論開發者是否真的需要這種能力,他們總希望能夠擁有它,可以隨時使用。
Git的缺點
但就像其它所有開發工具一樣,Git也不是一個完美的方案。Git確實是市場上發展最快的版本控制工具,但對于它的分歧也同樣很大。這種分歧不僅包 括應當在企業項目中使用還是在開源項目中使用,并且還包括是否應當由獨立的開發團隊使用還是讓整個企業擁抱Git。這種分歧的存在是源于Git這門工具的 缺點,而這些缺點與它的優點一樣,都顯得非常突出。
在2013年, CollabNet發起了一份問卷調查,以了解在企業中使用Git的最大顧慮是什么。在所有回復中排名前三的分別是安全、治理以及與工具的集成,總監以及更高級別的管理者通常會將安全性視為他們最大的顧慮。那么,為什么這三點會成為在企業中應用Git的障礙呢?
說起來,這還要追溯到這門工具本身的起源,Git最初的目的只是為了實現一個特定的開發方式的流程。雖然Git的設計者很清楚他們需要這一工具處理 哪些任務,但他們并不怎么關心其他人如何使用這一工具。當然,隨著時間的推移,Git也在不斷進化,它也在逐漸地適應其他用戶的需求與期望。但它的本質還 是以面向開源項目類型的開發為主所設計的工具,對于企業級開發來說仍存在著一些不足之處。
在開源項目開發過程中,整個工作流與企業開發相比有很大的差別。這些項目對于創建分支的需求較低,并且基本沒有人關心如何治理,在安全性方面的處理 也簡化了許多。按照一般開源項目的特性,全球開發者都可以隨意讀取代碼,而寫入的權限通常只會給予少部分可信的參與者。而企業的需求則是千變萬化的,并且 企業中每個項目團隊的需求往往也各有差別。企業項目開發通常需要進行更多的分支操作、要求進行詳細地管理、需要更細粒度的訪問控制、并且需要一些額外的安 全措施,例如與企業中的LDAP進行集成。
對于企業來說,問題并不在于每個開發者如何使用Git的功能,而在于如何支持必要的canonical庫以及上游團隊的流程。由于Git本身并沒有 canonical庫的概念,因此只能以其它方式實現保護核心信任源的任務。舉例來說,在本地進行歷史重寫操作對于開發者來說相當便利,但在嚴格的配置管 理流程中,對canonical服務器進行歷史操作會帶來一定的風險。
由于企業的需求不同,為了應對這些需求就出現了多種不同的解決方式,而這些方式仍舊能夠充分利用Git的各種益處。這些不同的解決方式并不一定是傳 統意義中的 “fork”,而更像是一種插件、一種封裝,只是以不同的手段去克服同樣的問題罷了。這也就意味著某個開發團隊在使用Git時所選擇的架構與同一企業中的 另一團隊的選擇可能是截然不同的,對于企業來說,這一點絕非他們所希望看到的結果。
確實,每個團隊使用Git的方式都是不同的。對于團隊各自具有不同的工具、流程與實踐這一現狀,企業總 是會例行公事地表示,這些工具都是以一個基礎工具為基本的。但他們很快會發現,這些不同的解決方案將限制企業自身的敏捷性與可擴展性。由于企業中的應用程 序各自散落在不同的環境與位置,因此沒有什么一目了然的方法可以充分地了解這些應用。而因為缺乏對這些應用的可見度,企業就無法維持必要的管理工作,以確 保團隊成員在各自的流程中都能夠做到遵循企業的標準。企業不得不為此投入更多資源,以支持這些不同的解決方案,而這些時間本可以用于為公司創造更多的價值 與創新工作。
此外,Git本身也存在著一些缺陷,在大型的代碼庫不斷擴展時,如何保持多個開發團隊依然能夠高效地開展工作是一項巨大的挑戰。另外,Git對于大 型二進制文件的支持也有一些局限性。為了應對這些缺陷,大型的應用不得不使用多個代碼庫以管理所有相關的代碼與文件,這又產生了其它的問題。舉例來說,企 業團隊希望能夠對完整的應用程序代碼執行某些操作(例如創建分支與設置標簽等等),無論有多少個代碼庫牽涉到這一操作。他們希望能夠同步地在所有相關的庫 中執行相同的操作,但在Git中并沒有跨多個庫的原子操作這一概念。核心Git特性無法處理這一問題,因此企業不得不考慮一些第三方的功能,例如Git Slaves或Android社區的 repo工具。
另一方面,Git的分支與合并操作所針對的是整個代碼庫,因此Git庫與應用程序之間被限制為一種1對1的關系。如果某個企業通過一個單一的庫保存 多個相關應用的所有資源,為了隔離某個特定應用程序的開發與文檔里程碑,他們就不得不為每個應用程序創建一個單獨的庫。這一結果所帶來的影響不僅在于庫的 數量大大提高了,而且還需要對構建、簽出以及安裝流程和腳本進行修改,以應對代碼庫結構的變化。
另外,由于Git本身就具有克隆的這種底層概念,因此用戶和項目團隊可能會傾向于對應用程序和模塊進行fork,而沒有考慮如何更恰當地使用分支操 作。在開發應用的新發布時,不應在上一個發布的項目上創建一個新的代碼庫,而是應當在現有的代碼庫中為新的發布創建一個全新的分支。當團隊需要修改一個共 享的組件或庫時,也應當遵循相同的策略。分支能夠將工作進行隔離,甚至對某個通用的基礎組件或類庫來說,也能夠將一些獨立的變更進行隔離,但這些分支應當 存在于一個通用的庫中,讓使用這部分代碼的用戶能夠對其進行評估及應用。
最后,對于多數企業來說,代碼的重用以及對第三方庫的利用都會被視為一種理想的方式。但對于這方面的需求,Git也無法給出完美的答復。企業可以嘗 試使用Git中的子模塊,這個功能在標準的Git包中就已經存在了,但實現這一點需要每個開發者掌握更多的實現方面的知識,以及操作的步驟。當然,他們也 可以選擇使用Git子樹功能,但他們必須確保建立起合適的關聯,以拉取這些代碼,并以適當的方式使用它。由于這兩種方案都有其弊端所在,企業可能會因此寄 希望于更好的解決方案的出現。
需要考慮的問題
從以上分析可以看出,Git的優點與缺點都是非常顯著的,這讓人有些不知所措。如果你仍然希望將現有的產品或應用從其它的版本控制工具中遷移至Git,那么你需要考慮以下幾個問題:
- 在版本控制方面,怎樣的流程才能夠最好地滿足你的需求?
- 你的組織在治理與安全方面有哪些需求?
- 有哪些工具、服務與流程需要與Git進行集成,又有哪些數據需要進行遷移?
- 如何對使用者進行Git與流程方面的培訓? </ul>
首先,在版本控制方面,怎樣的流程才能夠最好地滿足你的需求?有許多組織都是這樣想的:雖然我需要將數據遷移到一種不同的結構中,但 仍然可以使用相同的流程,而不用做出任何變化。這些組織沒有認識到一點,即他們的流程往往是由所選擇的工具的長處(以及短處)等因素而定型的。要在一個本 質上完全不同的工具,例如Git中照搬現有的流程,很可能會導致一種“格格不入”的尷尬境地。因此,你應當重新審視一下你的基本需求,并采用Git的最佳 實踐以打造一種全新的流程,讓它既能夠滿足你的需求,同時也能夠充分利用Git的強大功能。
人們總是認為,對于一種特定的工具來說,只存在著唯一一種進行分支與合并操作的最佳實踐模型。而實際上,分支操作是由于對隔離的需求而產生的,而不 是由某個工具的功能所決定的。GitFlow通常被人們錯誤地認為是一種專屬于Git的分支與合并模型,但除了它的名字與相關的腳本之外,它與Git并沒 有直接的關聯,完全可以應用于其它版本控制工具。
幾乎所有的分支模型都屬于兩種基本方式之一,選擇哪種方式要根據對并行發布式開發過程支持的需求而決定。其中,不穩定的master方式在設計時所 針對的開發方式主要專注于在任一時間只有一個新發布的情況,大多數開源項目就屬于這種情況,因為它們的工作周期較短。而穩定的master方式在設計時所 針對的開發方式專注于同時進行多個發布的情況,這正是多數企業中所采用的開發方式。
GitFlow初看上去似乎是基于穩定的master方式而設計的,因為代碼的簽入工作通常不會直接發生在master分支上。但實際 上,GitFlow的設計目標是基于不穩定master基礎的方式,支持連續的發布,只是將這種不穩定性從master分支轉移到一個通用的、連續的開發 分支而已。因此,對于企業應用來說,GitFlow這種方式作為一個最佳實踐的吸引力有所降低,也難以成為Git這門工具的一種標準用途。
其次,你需要問問你自己,你的組織在治理與安全方面有哪些需求?你是否需要一種比代碼庫更底層的訪問控制?你是否需要通過角色的方式 定義一些通用的訪問規則,并將其應用到進行應用程序開發的多個團隊之間?你是否需要選擇一種單一的帳號與密碼源?你是否已經定義好一組流程,讓團隊能夠遵 循,你也可以進行監控它們的實施情況?通過回答以上問題,能夠幫助你定義必需的訪問控制,以及回顧那些能夠滿足這些需求的流程。或者,在回答這些問題的過 程中,你可能會發現Git并不是你的企業、或是某個特定項目的最佳選擇。
在安全與治理方面的需求并不代表不能夠使用Git,但這意味著你必須找到一種合適的封裝,讓它提供這些額外的功能。你需要找到一種這樣的封裝,它能 夠滿足組織中的多個開發團隊所表現出的各種需求。在沒有治理方面的需求時,它應當能夠讓變更直接應用到canonical庫中。而一旦治理成為一種需求, 它應當能夠強制實施一些必須在變更應用到代碼庫之前所遵循的一些流程,同時又保證能夠在團隊這一層級上定義這種流程。為了支持企業在中央式治理能力與可見 性方面的需求,需要提供一種唯一的封裝能力。
Gerrit是一個開源的解決方案,它能夠滿 足這方面的需求。其實Gerrit原本是設計為一種專門支持代碼審查的工具,它的設計方式是只允許已批準的提交可以公開訪問。但它還提供了一些額外的功 能,以支持企業對于安全與治理方面的需求。它將每個代碼庫都視為一個項目,能夠應用不同的安全與治理策略。它還能夠在分支級別以及對特定的操作定義訪問控 制權限,這些操作包括標簽以及推送合并。Gerrit還提供了對LDAP的集成,以滿足有這方面需求的企業。作為企業級Git解決方案來說,Gerrit 是一個完美的示例。
再次,你需要決定有哪些工具、服務與流程需要與Git進行集成,又有哪些數據需要進行遷移?為了成功地實現這一過程,你需要擁有一個平臺與合作伙伴,以得到必要的工具。此外,你還需要充分地評估有哪些數據需要遷移至Git。對于某些環境來說,完整的歷史遷移是不必要的(或者說是不可能的)。
曾幾何時,版本控制工具被視為軟件開發這片汪洋中的一座孤島,這種觀念現在已經一去不復返了。企業需要與集成開發環境(IDE)、問題管理工具、測 試工具、構建工具與DevOps流程進行無縫的整合,而這些工具中也有相當一部分需要進行相互整合。你需要做的是找出在你的組織里使用了哪些工具、將這些 工具與現有的版本控制工具進行整合,或是與額外的版本控制工具進行整合將帶來哪些頭信息。在完成這些工作后,你就能夠通過一個支持這種整合的平臺,從你的 Git環境中獲取最大的價值。
如果你曾經轉移過你的個人資產,你就可以將它與從一個版本控制工具轉到另一個工具的挑戰進行類比。你需先要評估,在新的環境之中,哪些東西是無用 的,哪些東西是現在可能不需要,但一旦出現相關需求時就必需用到的。你是否有過幫朋友進行搬家的經歷?如果你的朋友打算把所有的一切全都打包搬走,而新的 住所還比原來的更小,那種經歷應當不會很美妙。歷史信息確實是版本控制數據的核心,但大多數歷史信息的價值只體現在一段有限的時間之內。并且,各種工具所 提供的特性不同、實現常見特性的方式不同、保存數據的方式也不同。你需要認真地評估,哪些數據可以被遷移,以及哪些數據確實需要被遷移。把剩余的部分留在 遺留的系統中別去管它。
最后,你將如何對使用者進行Git與流程方面的培訓?不要單純地因為Git是一個開源工具,就認為用戶能夠簡單地了解 它。Git是一個復雜的工具,它與你平日的工作方式有著很大的差異。你需要通過諸如午餐學習時間 、基于web的學習課程、以及引導式的培訓課程等方式讓你的團隊加快掌握Git的步伐。對于這方面的專家代表來說,你需要讓他們與真正的專家進行互動,以 及提供額外的動手實踐的機會,讓他們成為企業中能夠對Git進行第一線支持的人員。用戶在培訓中需要了解這一工具的功能,還需要通過專門的培訓以了解企業 或項目團隊如何使用Git。流程的培訓也非常重要,但需要另行安排。
Git能夠帶來各種益處,這使它成為了如今成長最快的版本控制解決方案。通過了解它的益處、它的限制、它的工作方式、它如何滿足你的業務需求、以及你需要在哪些方面補充它的不足,你才能夠決定Git是否是適合你的企業的正確工具。
關于作者
Bob Jenkins是 CollabNet版本控制服務部門的總監,在過去的19年中,他始終專注于應用程序生命周期管理工具,尤其關注版本控制工具,包括ClearCase、 Subversion以及Git。在CollabNet工作的14年間,他的主要工作是為那些計劃實施Git與Subversion的企業提供顧問服務, 并且為他們提供這兩種版本控制工具的終端用戶培訓教材。他已經為上百家企業提供了顧問服務,幫助他們成功地在企業中實施所選擇的版本控制工具。