充分理解 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 与流程方面的培训?
首先,在版本控制方面,怎样的流程才能够最好地满足你的需求?有许多组织都是这样想的:虽然我需要将数据迁移到一种不同的结构中,但仍然可以使用相同的流程,而不用做出任何变化。这些组织没有认识到一点,即他们的流程往往是由所选择的工具的长处(以及短处)等因素而定型的。要在一个本质上完全不同的工具,例如 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 的企业提供顾问服务,并且为他们提供这两种版本控制工具的终端用户培训教材。他已经为上百家企业提供了顾问服务,帮助他们成功地在企业中实施所选择的版本控制工具。
评论