收藏 分销(赏)

代码管理实践10讲.pdf

上传人:Stan****Shan 文档编号:1240124 上传时间:2024-04-19 格式:PDF 页数:92 大小:4.28MB
下载 相关 举报
代码管理实践10讲.pdf_第1页
第1页 / 共92页
代码管理实践10讲.pdf_第2页
第2页 / 共92页
代码管理实践10讲.pdf_第3页
第3页 / 共92页
代码管理实践10讲.pdf_第4页
第4页 / 共92页
代码管理实践10讲.pdf_第5页
第5页 / 共92页
点击查看更多>>
资源描述

1、目录页一、量体裁衣,寻找适合你团队的代码协同模式.4二、新一代高效 Git 协同模型 AGit-Flow 详解.28三、评审协同如何提效,我们团队的 4 点思考.40四、打破代码评审“小步快跑难落地”的魔咒.45五、重评审还是轻评审,企业该如何选择代码评审模式?.58六、代码评审到持续交付的最后一公里.61七、3 类代码安全风险如何避免?.63八、揭秘!业界创新的代码仓库加密技术.71九、打通源码!高效定位代码问题.79十、这样才是代码管理和 Commit 的正确姿势!.84一、量体裁衣,寻找适合你团队的代码协同模式4一、量体裁衣,寻找适合你团队的代码协同模式三类代码协同模式,Git 大神告诉

2、你到底如何选1.Git 代码协同模式基础为团队规划研发协同模式之前,有必要了解 Git 的几种协同模型。其中多种协同模型中使用了代码评审。代码评审在不同的代码平台有不同的称谓。GitHub 应该是受到了 git 命令 git request-pull 的启发,将代码评审称为拉取请求(pull request,PR)。GitLab 因为代码评审最终被合并(也支持变基 rebase)到目的分支,因而称其为合并请求(merge request,MR)。阿里云云效的代码平台,代码评审不但用于分支提交变更的评审,也将支持分支创建、分支删除、强制推送行为的评审,因此云效代码平台将代码评审称为变更请求(ch

3、ange request),简记为 CR。1)GitHub-Flow:开源社区标配的协同模型GitHub 在 2008 年一经推出,就凭借其创造性的“仓库派生+pull request”的工作流征服了开源社区。这是因为这一协同模式解决了开源社区最大的痛点:仅对少数人开放代码仓库写权限和人人皆可贡献开源的矛盾。a)GitHub 工作流的使用对于开源项目的参与者,可以划分为两类角色:维护者和贡献者。维护者:具有代码仓库最高权限,可以创建分支、删除分支、更新分支,以及向分支强制推送。一、量体裁衣,寻找适合你团队的代码协同模式5贡献者:没有仓库的写权限,只拥有读权限,不能向代码仓库直接推送。GitHu

4、b 创造了“仓库派生”这一机制,解决了代码仓库的只读用户向代码仓库贡献的途径。我们以 k8s 社区为例,介绍 GitHub 工作流。(图示摘自 https:/www.kubernetes.dev/docs/guide/github-workflow/)GitHub 工作流说明:创建派生仓库。说明:作为 k8s 项目的贡献者,没有 k8s 仓库的写权限,但可以通过 GitHub 的 fork 功能将 k8s 项目(kubernetes/kubernetes)派生到自己名下,如仓库$user/kubernetes。用户对于自己的派生仓库拥有写权限。将自己的派生仓库克隆到本地。执行命令:git cl

5、one https:/ master 分支)同步。说明:派生仓库并不能和上游仓库自动同步,为避免本地提交和上游仓库出现过大的偏离导致合并冲突,在每一个功能开发前,以本地仓库为中介,将远程上游仓库的新提交同步到远程的派生仓一、量体裁衣,寻找适合你团队的代码协同模式6库中。git remote add upstream https:/ fetch upstreamgit switch mastergit rebase upstream/mastergit push origin master创建一个本地分支(如 mybranch 分支)。说明:为每一个开发任务创建一个单独的本地分支是一个好习惯,这

6、样可以在一个本地仓库中,用不同的本地分支关联不同的 pull request。git switch-c mybranch master在本地分支中开发。git add git commit-s将本地分支推送到远程派生仓库。git push-u-f upstream HEAD创建代码评审(pull request)。即:通过 GitHub 的 Web 界面,从远程派生仓库向远程上游仓库创建 pull request。本地仓库中新的改动(提交)再次推送到远程的派生仓库,会自动刷新代码评审中的提交。一、量体裁衣,寻找适合你团队的代码协同模式7b)优势和缺点GitHub-Flow 的优势:满足了开源项

7、目人人皆可贡献的目标。在 2008 年,仓库派生是基于原生 Git 实现开源协同的最易用的方案。易于管理。将代码管理工作化整为零,每个派生仓库由派生者自行管理,开源项目的负责人无需进行复杂的授权管理和分支管理。派生仓库是一个独立的拷贝,不会受到上游变更(许可证变更、开放性变更、授权变更等)的影响。GitHub-Flow 的缺点:仓库同步操作复杂。同步操作涉及到远程上游仓库、远程派生仓库、本地克隆仓库的三方数据同步,开发者要熟悉 git remote、git rebase 等命令。派生熔断导致仓库授权失去管控。在仓库的开放性发生变更(例如从公开项目转换为私有项目),主项目和派生项目之间的派生关系

8、被切断,成为没有派生关系的不同的项目,派生项目的管理权也从主项目自动交接给派生项目的用户。不适合于多仓库类型的项目(如 Android 项目)。由于多仓库的存在,放大了派生仓库和上游仓库同步的复杂度。派生仓库导致服务端存储出现冗余。上述缺点,尤其是派生熔断导致仓库授权失去管控,无法被企业管理者所接受。因此,GitHub 工作流只适合于外部开源或者企业内部开源项目,而不适合企业私有项目。一、量体裁衣,寻找适合你团队的代码协同模式82)分支评审:仅适用于私有仓库的协同模型GitHub 的派生工作流会因为仓库可见性从公开变为私有导致派生熔断,造成仓库授权失去管控,因此派生仓库协同模式通常不被企业所接

9、受。进而,被所有代码平台所支持的分支评审模式自然成为企业私有仓库协同的最直观的选择。a)分支评审模式的使用企业私有代码仓库的协同者通常包含三类角色:管理员、开发者、贡献者。管理员:即仓库的维护者,具有代码仓库最高权限,可以创建分支、删除分支、更新分支,以及向分支强制推送。开发者:具有仓库的读写权限,除了不具备删除仓库等危险操作的权限之外,和管理员一样,具有创建分支、删除分支、更新分支,以及向分支强制推送的权限。贡献者:没有仓库的写权限,只拥有读权限。上述三个角色中,只有开发者和管理者拥有写权限,因此只有这两种角色才能够使用分支评审模式参与代码仓库的协同。采用分支评审模式协同,开发者在服务端仓库

10、中创建临时分支,将本地提交推送到相应的临时分支上,再从该临时分支创建到目标分支的代码评审。临时分支通常在代码合入后清除。用户在服务端创建的临时分支,根据目标分支的不同,有着不同的名称。如:特性分支(topic branch):为完成某一功能开发而创建的临时分支,通常基于主干分支创建。不同的项目对于特性分支可能有不同的命名规范,例如:topic/、feature/。热修复分支(hotfix branch):为修复已发布的历史版本的缺陷,基于历史发布版本(如 v1.0 版本)创建的分支。不同的项目对于热修复分支可能有不同的命名规范,例如:hotfix/。一、量体裁衣,寻找适合你团队的代码协同模式9

11、下面的示意图演示了一个开发者如何通过分支模式将特性分支(如 topic/1)合入到主干分支(如 master)。说明如下:git clon 开发者将远程仓库克隆到本地:e https:/ topic/1 分支:git switch-c topic/1在本地分支中开发。git add git commit-s将本地 topic/1 分支推送到远程服务器上。git push-u origin HEAD开发者访问 Web 界面,选择从 topic/1 分支向 master 分支创建代码评审(如编号 123 的代码评审 CR#123)。本地仓库继续修改,创建或更新提交。git add git comm

12、it-s执行推送命令,自动刷新远程仓库中的代码评审(CR#123)。git push代码评审通过,从 Web 界面访问 CR#123,点击合入完成分支 topic/1 到分支master 的合入。分支 topic/1 合入后,可以手工删除该分支。一、量体裁衣,寻找适合你团队的代码协同模式11b)GitLab 的保护分支功能保护分支功能最早由 GitLab 实现,目的是确保分支能够严格采用分支评审模式进行协同。通过输入名称通配符,确保与之匹配的分支被加以保护。可以设置被保护的分支必须使用代码评审才能够合入,不能直接推送。可以设置被保护的分支不能够被强制推送,管理员也不例外。保护分支由管理员进行设

13、置,通常仅对代码仓库的主干分支、维护分支进行保护,而不对特性分支进行保护。c)优势和缺点分支评审模式的优点:如果某个特性的开发周期比较长,创建一个长期存在的特性分支,便于开发者能够随时执行推送命令将本地提交推送到服务端,避免本地误操作而丢失数据。如果某个特性由多人协同开发,设置一个特性分支,便于多个用户进行工作协同。分支评审模式的缺点:如果开发者无论是否必须、无论特性的大小,都采用分支评审模式,且不能及时删除过时的特性分支,就会在服务端遗留大量过时的分支。仓库中过多的特性分支和仓库的核心分支(主干、维护分支)混杂,会给开发者带来困惑,也会导致用户操作过程的性能下降。缺乏有效的分支授权管控,无法

14、限制对于非保护分支的推送、创建、删除权限的管控,可能导致特性分支被误删,或者特性分支因多人协同时强制推送被覆盖,造成代码丢失、协同效率的下降。一、量体裁衣,寻找适合你团队的代码协同模式12d)分支评审模式的改进采用 AGit-Flow 协同模式,直接通过命令行创建代码评审,而不在仓库中创建临时分支,可以解决了分支评审模式中特性分支过多、混乱的问题。至于分支评审模式缺乏对特性分支创建、删除、强制更新的授权,阿里云云效代码平台提供推送评审模式,实现自助式分支管理,以解决代码仓库中分支管理无序的难题。3)AGit-Flow:兼顾开源和私有项目的集中式协同模型阿里巴巴内部的代码平台在 2019 年实现

15、了一种集中式工作流不需要仓库派生,就可以让只读用户贡献代码。这种集中式工作流既适合于开源项目,又适合于私有项目。因其核心实现基于阿里云代码团队定制版的 Git(AGit),因此将此工作流命名为 AGitFlow。AGit Flow 在设计上参考了 Gerrit,使用体验和 Gerrit 类似。在 2020 年,阿里巴巴将这一成果核心代码贡献到 Git 社区,对 Git 服务端和 Git 客户端能力进行了扩展。参见:Git2.29 让 Git 成功“牵手”Gerrit。在 2023 年 6 月,由阿里云代码团队参与建设的 AtomGit 开源平台上线,标志着首次将AGit 工作流带入到了开源社区

16、()。a)AGit 工作流的使用AGit 工作流在设计上参考了 Gerrit。Gerrit 是谷歌开发的代码平台,被 Android、OpenStack 等项目拿来管理各自的研发协同。Gerrit 的仓库格式也是 Git,但是服务端实现采用了 Java 开发的 Git 兼容工具jGit 而非原生 Git,除了带有谷歌风格的逐提交代码评审之外,还实现了无需派生仓库、所有贡献者基于同一个上游仓库进行协同的集中式工作流。一、量体裁衣,寻找适合你团队的代码协同模式13Gerrit 这一集中式工作流既适合开源项目,也适合私有项目。但是因为 jGit 在性能和功能上落后于原生 Git,且 Gerrit 的

17、使用体验、可扩展性存在的问题,导致 Gerrit 协同模式没有 GitHub 工作流那样的被人熟知和使用广泛。在 2020 年,阿里巴巴向 Git 社区贡献两个功能扩展,一个成为 Git 服务端的功能扩展(proc-receive 挂钩),一个成为 Git 客户端功能扩展(report-status-v2 能力)。这样代码平台的设计者可以在服务端针对用户的 git 推送行为进行相应的扩展,体验上类似 Gerrit,但是能力更加强大。即:用户向仓库的特殊引用(如 refs/for/master)推送,生成代码评审。其中特殊引用 refs/for/master 在服务端并不存在,也不会因为用户的推

18、送操作而被创建,用户的推送操作被服务端扩展程序接管,创建代码评审。客户端收到服务端操作的真实结果,并向用户报告。例如:Git 客户端通过report-status-v2 协议接收到服务端真实的操作行为,在服务端创建了代码评审(如:refs/changes/123/head)。在如下的示例中,有两个角色参与到协同中。开发者向服务端仓库推送,创建了编号为123 的代码评审(CR#123),评审者亦能下载、修改和上传代码评审中的提交。一、量体裁衣,寻找适合你团队的代码协同模式14上图中的开发者,执行如下操作:开发者将远程上游仓库克隆到本地,并在本地创建开发分支。git clone https:/ s

19、witch-c topic master在本地分支中开发。git add git commit-s执行特别的推送命令。如下所示,将本地提交推送到远端不存在也不会被创建的一个虚拟分支(引用)中,该虚拟分支的格式为 refs/for/。服务端识别这个特殊的推送操作,在服务端创建代码评审。git push origin HEAD:refs/for/master/topic上述推送命令的特殊目标分支被服务端识别,自动创建代码评审(如编号 123 的代码评审:CR#123)。本地仓库继续修改,创建或更新提交。git add git commit-s执行同样的推送命令,刷新远程仓库中的代码评审(CR#12

20、3)。一、量体裁衣,寻找适合你团队的代码协同模式15上图中的代码评审者参与代码评审过程中,可以下载代码评审(CR#123)到本地进行线下评审,亦可参与代码协同,更新 CR#123 上的提交。说明如下:评审者可以下载编号 123 的代码评审相关提交到本地,进行线下评审。git fetch origin refs/changes/123/head评审者创建本地分支(如 rev-branch)。git switch-c rev-branch FETCH_HEAD评审者在本地分支创建新提交。git add git commit-s-fixup HEAD评审者执行特殊推送命令,更新代码评审中的提交,供原

21、作者参考。该命令中使用了特别的推送参数-o review=123 用于更新指定代码评审。示例如下:git push-o review=123 origin HEAD:refs/for/masterb)优势和缺点AGit-Flow 的优势:人人皆可贡献,只读用户也可以参与代码开发,适合于开源场景。同时也适合于企业私有仓库的开发场景。因为不存在仓库派生,不像 GitHub 工作流那样因派生熔断导致仓库授权失去管控,因此既适合于开源代码开发场景,又适合于企业私有项目的开发场景。开发者工作在同一个仓库中,服务端仓库无需同步操作。即不需要 GitHub 工作流那样要进行上游仓库、派生仓库、本地仓库的三方

22、同步操作。操作步骤简化,命令行推送操作直接创建代码评审,无需通过 web 界面创建代码一、量体裁衣,寻找适合你团队的代码协同模式16评审。适合于多仓库项目的场景。可以参考 Android 项目管理多仓库的方案。AGit-Flow的 缺 点:Git推 送 命 令 行 比 较 长,使 用 特 殊 的 目 标 引 用(refs/for/)或特殊的推送参数,需要学习和适应。4)推送评审模式基于阿里云贡献给 Git 社区的两大核心功能(服务端 proc-receive 挂钩和客户端report-status-v2 扩展),阿里云云效代码平台创造了推送评审模式,实现对仓库分支、标签的全生命周期管理。推送评

23、审模式内部测试中,将于 2023 年底正式商用。推送评审的使用方法:向已有分支推送:不更新分支,而是创建一个新的代码评审,或更新已有的相关代码评审。推送操作欲创建分支/标签:不直接创建分支/标签,而是创建一个审核单,审核通过后执行分支/标签的创建操作。推送操作欲删除分支/标签:不直接删除分支/标签,而是创建一个审核单,审核通过后执行分支/标签的删除操作。向分支强制推送:不更新分支,而是创建一个审核单,审核通过后执行分支的强制更新操作。管理员可以在推送命令中加入参数绕过推送评审,使得推送操作直接生效。如:git push-o review=no origin :一、量体裁衣,寻找适合你团队的代码

24、协同模式17git push-o review=no-force-with-lease2.设计团队的代码协同工作流基于前面介绍的代码协同模式,企业/团队根据项目的实际情况可以灵活定制自己的代码协同工作流。通过对以下问题的回答,可以找出最适合的代码协同工作流。1)团队能力和项目类型评估是否开源?开源包括针对外部的代码开源,还包括企业内部开源(内源)。如果代码仓库选择了开源(无论是外部开源,还是内源),为管理方便可以在仓库中仅定义两种用户角色:维护者。维护者可以是一个人或者一个团队承担项目维护者的职责,维护者具有仓库读写和管理权限。管理权限包括:批准代码评审通过,合并代码评审等。贡献者。贡献者具有

25、只读权限,需要通过 GitHub-Flow 或者 AGit-Flow 方式向仓库贡献代码。对于复杂的需要多人协同开发的特性,可以采用 GitHub-Flow 模式。通过创建的派生仓库进行多人协同开发,开发完毕创建向上游仓库的代码评审。代码评审通过,将提交合入到上游代码仓库。对于简单的特性开发,建议采用 AGit-Flow 模式,用户执行 git 推送命令,直接在服务端创建代码评审。一、量体裁衣,寻找适合你团队的代码协同模式18对处于开发中尚不具备合入质量的提交,为了避免本地数据丢失,或者希望在服务端触发持续构建(CI)检查代码质量,可以通过如下推送命令在服务端创建草稿模式的代码评审:git p

26、ush origin HEAD:refs/drafts/草稿状态的代码评审不能被合入,但是可以触发 CI 构建,可以进行代码评审。是否有旧版本需要维护?通常互联网线上应用采用持续部署(CD)、主干分支发布。这种类型的项目一旦发现线上缺陷,直接在项目的主干分支上修复缺陷,修复缺陷的提交连同新特性一同发布到线上。这种类型的项目不需要对旧版本进行维护。有的项目无法采用持续部署、持续发布,新版本有较长的开发周期,就需要对已发布的一个或多个版本进行维护。这样的项目就需要在代码仓库中存在一个或多个维护分支。例如:安卓手机的 Android 系统、苹果手机的 iOS 系统通常在每年发布一个大版本,历史发布版

27、本提供长达几年的维护期,这就需要在产品的代码仓库中创建一个或多个维护分支。不同的项目对于维护分支可能有不同的命名规范,例如:maint、maint-2.0、maint-3.0。是否使用 CI 和代码评审?使用持续构建(CI)和代码评审,可以确保贡献者提交的正确性和代码质量,是软件项目高质量交付的利器。缺乏 CI 能力,也可以使用代码评审,不过缺乏 CI 的代码评审更加消耗评审人的时间,且难以保证代码的正确性。一、量体裁衣,寻找适合你团队的代码协同模式19对于缺乏代码评审文化、缺乏单元测试、不具备 CI 条件的项目,往往跳过代码评审,这种类型的项目通常采用类似 CVS、SVN 的共享分支协同模式

28、。即使采用代码评审的项目,对于多人协同开发的复杂特性通常创建一个长期的特性分支,多人在同一个特性分支进行代码协同时,通常也采用共享分支协同模式。对于共享分支协同的建议:多个开发者向服务端仓库的同一个分支推送,先推送者成功,后推送者遇到非快进式推送被拒绝,需要采用正确的行为规范,避免强制推送造成其他人的提交被覆盖、丢失。推荐的操作方式是:推送之前先执行拉取和变基操作:git pull-rebase。再执行推送操作:git push。使用保护分支功能,设置被保护的分支不能强制推送,不能被删除。这样向保护分支推送时需要采用上面的操作建议,先和服务器同步、变基操作,再推送。当发现推送了错误的提交,希望

29、采用强制推送覆盖服务器上推送的提交时,不要使用 git push-force,而是使用 git push-force-with-lease 命令,为强制推送增加一份保险。注意:替换的服务器端提交如果已被他人获取,强制推送可能为他人带来困扰。根据 CI 和代码评审的频率来判断项目的规模当代码仓库的主干分支上有多个待合并的代码评审(CR),合并其中一个 CR 到主干,主干分支上的代码会发生变化,这会导致其他尚未合并的 CR 的构建状态变得没有意义,需要重新执行构建以确保正确性。总的构建规模和 CR 数量关系为 O(n2),庞大的 CI 构建规模造成巨大的时间成本、计算成本的浪费,此外 CR 需以排

30、队构建方式合入主干分支,导致项目协同规模受限。一、量体裁衣,寻找适合你团队的代码协同模式20我们可以采用下面的公式判断项目协同规模,决定是否采用集成分支以并行方式合入代码、降低 CI 构建数量。项目复杂度=每日新建 CR 数量/每日串行 CI 构建数量每日串行 CI 构建数量=8 小时/单次 CI 构建时间或简记为:项目复杂度=NT/8其中:N:每日新建 CR 数量。T:单次 CI 构建时间(单位:小时)。当项目复杂度大于等于 1,视为中大型项目,需要引入集成分支提升 CI 构建效率,CR先批量合并到集成分支,再合入主干。当项目复杂度小于 1,视为小型项目,仅使用主干分支即可,CR 直接合入主

31、干分支。2)示例:小型项目(无维护分支)协同规范对于小型项目(无维护分支),采用主干开发模式。存在一条主干(如 master 分支),功能开发通过特性分支模式或者 AGit-Flow 模式创建评审,代码评审触发持续集成(CI),评审通过之后,代码直接合并到主干分支。协同示意图如下所示,其中提交之间的箭头方向表示的是时间从老到新的方向。一、量体裁衣,寻找适合你团队的代码协同模式21a)项目成员管理项目成员分属三个角色:管理员、开发者和贡献者。管理员:由一位或几位核心成员担任,具有对仓库完全的读写权限。开发者:固定的项目成员,对于仓库中非保护分支具有完全的读写权限。贡献者:团队之外的成员属于贡献者

32、,仅有仓库的只读权限。一、量体裁衣,寻找适合你团队的代码协同模式22b)分支的命名和管理设置一条主干分支作为仓库的默认分支。主干分支通常命名为 master 或 main,由仓库管理员在仓库初始化时创建。分支管理规范:可以使用通配符“*”设置保护分支,即所有分支均被保护。管理员和开发者能够在仓库中创建新分支,或者在推送评审模式启用下,任何人均可通过创建评审单的方式创建新分支。如果所有分支均被保护,则开发者创建的特性分支也需要使用 AGit-Flow 工作流创建代码评审,将提交合并到特性分支中。向特性分支发起的代码评审,默认采用变基(rebase)方式合并,以避免在特性分支产生合并提交。向主干分

33、支发起的代码评审,默认采用非快进合并(no-ff merge)方式合并。这种方式一定会产生一个合并提交,在合并提交中记录代码评审 CR 的编号和 CR 的描述信息。特性分支合入到主干分支时,默认选择合并后删除分支,避免过时的特性分支在仓库中堆积。c)创建代码评审可以采用三种方式创建代码评审:GitHub Flow、AGit Flow、分支评审模式。代码评审创建、更新会触发持续集成。操作略。一、量体裁衣,寻找适合你团队的代码协同模式23d)持续集成(CI)针对如下场景触发持续集成:向主干分支、特性分支的代码推送,触发持续集成。创建和更新 CR,触发持续集成。CR 的目标分支被更新,触发持续集成。

34、为避免 CR 构建规模造成的资源浪费,会检查开启的 CR 数量,当仓库复杂度超过阈值(NT/8=1)则应关闭 CR 随目标分支变更而自动构建的设置。3)示例:大型私有项目(含维护分支)协同规范对于大型项目(含维护分支),存在一条主干(如 master 分支)、一条或多条维护分支(如 maint 分支)。功能开发通过特性分支模式或者 AGit-Flow 模式创建评审。创建或更新代码评审会触发持续集成,持续集成验证通过以及代码评审通过之后,首先将代码合入到集成分支(如 next 分支),触发集成分支的持续集成,验证通过后再整合入主干分支。发行版本(如 v1.0.0)的缺陷修复,需要创建一条维护分支

35、(如 maint 分支),基于该维护分支创建热修复分支或者使用 AGit-Flow 模式创建针对维护分支的代码评审。针对维护分支的代码评审验证通过后,先合入到维护分支,然后将维护分支回合到主干分支,以确保在历史版本中出现的问题在主干代码中亦得到修复,相同问题不再重现。协同示意图如下所示,其中提交之间的箭头方向表示的是时间从老到新的方向。一、量体裁衣,寻找适合你团队的代码协同模式24a)项目成员管理项目成员分属三个角色:管理员、开发者和贡献者。管理员:由一位或几位核心成员担任,具有对仓库完全的读写权限。开发者:固定的项目成员,对于仓库中非保护分支具有完全的读写权限。贡献者:团队之外的成员属于贡献

36、者,仅有仓库的只读权限。b)分支的命名在仓库中设置如下常设分支:一条主干分支:master(或 main),同时作为仓库的默认分支,由仓库管理员在仓库初始化时创建。一、量体裁衣,寻找适合你团队的代码协同模式25一条或多条维护分支:作为对一个或多个已发布版本的缺陷修复,仅合入缺陷修复提交,不合入新功能。可选的名称有:maint、maint-1.0、release/1.0、release/2.0等。Git 项目使用 maint 作为维护分支名,因为按照字母序,维护分支 maint 排在主干分支 master 之前,意味着更稳定。一条集成分支:该分支作为主干分支的集成分支,每一次集成的时候自主干分支

37、重置,批量合入已经通过评审的 CR。批量合入后触发 CI 构建。Git 项目中集成分支命名为 next,字母序排在 master 之后,视为不稳定的分支。c)分支管理规范保护分支的设置:可以使用通配符“*”设置保护分支,即所有分支均被保护。管理员和开发者能够在仓库中创建新分支,或者在推送评审模式启用下,任何人均可通过创建评审单的方式创建新分支。因为所有分支被保护,开发者创建的特性分支、hotfix 分支等也需要使用 AGit-Flow工作流创建代码评审,将提交合并到相关分支中。维护分支的管理规范:发现历史版本的缺陷后,基于存在缺陷最老的维护分支进行缺陷修复。可以采用创建 hotfix 分支的分

38、支评审模式,或者采用 GitHub Flow 或者 AGitFlow 模式发起针对维护分支的代码评审。hotfix 分支的命名示例:hotfix/。向维护分支发起的代码评审通过之后,合入相应的维护分支。之后将修复的维护分支逐级合并到更高版本的维护分支,将缺陷修复“扩散”到所有版本中,即“merging upwards”。将修复后的最新维护分支合并到主干分支。一、量体裁衣,寻找适合你团队的代码协同模式26集成分支管理规范:将通过评审的多个 CR 自动或手工合入集成分支(如 next 分支)。更新后的集成分支触发构建。集成分支构建成功后,通过界面发起集成分支到主干分支的合并请求。主干分支管理规范:

39、中大型项目设置了集成分支,因此针对主干分支的代码评审不直接合入主干分支。在集成分支(如 next 分支)CI 构建通过之后,重新合并到主干分支(以确保合并提交的提交说明的目标分支从 next 调整为 master),更新主干分支提交,并触发构建。特性分支规范:向特性分支发起的代码评审,采用变基(rebase)方式合并,避免在特性分支产生合并提交。向主干分支发起的代码评审,采用非快进合并(no-ff merge)方式合并。这种方式一定会产生一个合并提交,在合并提交中记录代码评审 CR 的编号和 CR 的描述信息。特性分支合入到主干分支时,选择合并后删除(可以设置为默认开启),避免过时的特性分支在

40、仓库中堆积。d)创建代码评审可以采用三种方式创建代码评审:GitHub Flow、AGit Flow、分支评审模式。代码评审创建或更新会触发持续集成。操作略。一、量体裁衣,寻找适合你团队的代码协同模式27e)持续集成(CI)针对如下场景触发持续集成:向主干分支、集成分支、特性分支、维护分支的代码推送,触发持续集成。创建和更新 CR,触发持续集成。CR 的目标分支被更新,不触发 CR 的持续集成,以降低 CR 构建的复杂度。二、新一代高效 Git 协同模型 AGit-Flow 详解28二、新一代高效 Git 协同模型 AGit-Flow 详解Git 工作流概述及 AGit-Flow 的优势目前,

41、Git 已成为源代码管理的标准和基础设施。“为什么 Git 能这么成功”?Git 的创建者 Linux 在 Git 十周年的一次采访中,道出了其中的奥秘:The big thing about distributed source control is that it makes one of the mainissues with SCMs go away the politics around“who can make changes.”他认为 Git 能成功最关键的不是因为它更快、更安全,也不是因为 Git 是分布式的,而是解决了“到底谁能够贡献代码”这个问题。传统的集中式版本控制系统只

42、能针对核心用户开放写授权,长期来看这对项目做大、做强是不利的。而 Git 改变了传统版本控制系统不能够让跟多开发者贡献代码这个顽疾,让“只读用户”也可以通过“代码评审”的方式参与到项目开发中。当前业界有两种最常用 Git 工作流:GitHub 和 Gerrit。他们都具备仓库的授权模型简单,只读用户可参与代码贡献的特点。二、新一代高效 Git 协同模型 AGit-Flow 详解29如上图所示,我对这两种 GIT 工作流做了优劣势分析:*代码评审模式不同:*GitHub 的代码评审称为“pull request”,每个特性改动生成一次代码评审。Gerrit 的代码评审称为“Change”,每个提

43、交生都会生成一个“变更单”,这个变更单就是一次代码评审。工作流类型不同:GitHub 的工作流属于分布式,当开发者需要参与项目的时候,虽然没有“写”的权限,但是可以通过“Fork”的方式创建一个个人仓库(派生仓库),他就可以在这个派生仓库中去创建代码分支,创建 pull request。GitHub 底层采用的是原生的 Git(即 CGit)。Gerrit 的工作流是集中式,所有用户工作在统一管控的集中式仓库中。Gerrit 要求用户在本地克隆仓库中安装一个“commit-msg”钩子,以便在生成的提交中插入唯一的“Change-Id”,向服务器推送要使用特殊的 git push 命令。Ger

44、rit 采用的是 JGit(Java 的 Git 实现)。各自优势:GitHub 简单易用,使用标准 Git 命令即可完成代码贡献;对派生仓拥有完全控制力,不受上游项目影响;可以创建跨项目的开源社区,全球开发者大协同,这也是 GIT 可以形成全球最大的开源社区的原因之一。Gerrit 因为采用集中式的工作流,管理员可以对项目进行严格管控,可以严格控制谁可以访问仓库,谁可以对我的仓库做贡献。Gerrit 另外一个优势是可以实现多仓库项目管理。我们知道“Android”项目具有 1000 多个仓库,就是使用 Gerrit 进行管理的,很难想象如何使用 GitHub 来管理 Android 的 10

45、00 多个仓库。二、新一代高效 Git 协同模型 AGit-Flow 详解30各自劣势:正如前面所说 GitHub 很难管理类似 Android 的多仓库项目。另外因为 GitHub 使用派生仓库的工作模式,会产生服务端数据冗余的问题。Gerrit 需要集中管控,由管理员负责创建项目,而普通用户不能创建项目,这就使得一个 Gerrit 实例通常只管理一个项目或一个组织内的项目,难以在项目之间形成代码复用,也很难汇集跨项目的开发者组成开发者社区。通过对 GitHub 和 Gerrit 等 Git 工作流的调研和学习,我们“取长补短”创建了阿里巴巴的 Git 工作流,即 AGit-Flow。在阿里

46、巴巴,我们喜欢 pull request、CGit,喜欢在命令行直接创建代码评审的集中式工作流,喜欢开放的开发者社区。我们不喜欢“commit-msg”钩子方式关联提交的代码评审,我们不喜欢一个一个分散的代码平台。我们还开发了配套的客户端工具“git-repo”,既能在单仓库下工作,又支持类似Android 的多仓库项目协同。二、新一代高效 Git 协同模型 AGit-Flow 详解31在阿里巴巴,我们如何使用 AGit-Flow下面给大家演示一下,在阿里巴巴内部,我们是如何使用 AGit-Flow 工作的。我们首先使用 Git 标准命令将仓库克隆到本地,然后在本地仓库内开发,创建提交。在工作

47、区中执行 git pr 命令,推送本地提交到服务器,服务器端会自动创建一个新的代码评审,例如:pull request#123。团队的代码评审者就可以打开编号“123”的代码评审提交评审意见。开发者根据评审意见,在本地工作区继续开发、新增或修改提交。工作区中再次执行 git pr 命令,推送本地提交到服务器。服务器发现目标分支上已经存在来自同一用户、同一本地分支的pull request,因此用户此次推送没有创建新的 pull request,而是更新已经存在的pull request。如果经过多次修改,代码依然不 OK。代码评审者也可以直接发起对评审代码的修改,帮助原开发者更新 pull r

48、equest。代码评审者可以使用 git download 123 下载编号为 123 的 pull request 到本地仓库,代码修改完毕后,执行 git pr-change 123 命令,将本地修改推送到服务端。服务端接收到代码评审者的特殊 git push 命令,更新二、新一代高效 Git 协同模型 AGit-Flow 详解32之前由开发者创建的 pull request。项目管理者通过点击 pull request 评审界面的合并按钮,将 pull request 合入 master 分支。master 分支被更新,同时关闭 pullrequest。使用 AGit-Flow 工作流无

49、需在服务器上创建新的分支,不需要给新加入的同学创建写入权限,可以对所有开发者只分配读取权限,然后通过创建代码评审再合并到主干的方式更新主干代码。这也是目前比较流行的主干研发模式。目前大家可以通过云效代码管理平台(Codeup)来实现 AGit-Flow 工作流。AGit-Flow 实现原理AGit-Flow 是如何实现的呢?首先客户端使用特殊的 git push 命令向服务端发起代码推送请求,触发 AGit-Flow 工作流。为什么说这个 git push 命令特殊呢?因为它的目标分支是一个包含特殊的前缀“refs/for/的代码分支,分支后面又跟了一个“”。这个“”用于区分本地分支名,不同开

50、发者提交的代码评审包含不同的“”,所以不会相互覆盖。我们还可以通过“-o”来传递不同的参数,比如可以指定由谁来对我的代码进行评审,我的代码评审会关联哪个“issue”。这些操作都可以通过“git push”命令完成,后来二、新一代高效 Git 协同模型 AGit-Flow 详解33我们发现这个 git push 命令比较复杂,于是我们封装了一个命令行工具 git-repo。目前 git-repo 已经对外开源,大家可以免费使用。接 下 来 这 个“Push”命 令 就 会 打 入 到 服 务 端,服 务 器 端 会 启 动 一 个 进 程“git-receive-pack”。(我们对服务器端的

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 研究报告 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服