资讯专栏INFORMATION COLUMN

Git workflow 详谈

funnyZhang / 2552人阅读

摘要:在合并完成后,可以执行将自己开发的功能发布至中心仓库。特性分支工作流基于特性的分支工作流,可以为每个特性做隔离,避免对中心仓库主干代码造成影响。修复分支,用于对线上主分支代码的及时修复,待修复完成后,合并进入主分支,再并入开发分支。

作为一名工程师, Git 在日常开发中是不可或缺的工具。
这里详细介绍几种比较常用的基于 Git 的工作流模型, 以便于团队协作的规范化和效率提升。

中心化工作流

使用过SVN的应该都知道, SVN使用的是集中式管理流程, 如果你刚从SVN 切换到 Git , 你可以尝试使用中心化工作流的方式。这样,你几乎不需要变更之前的工作方式, 就可以完成平滑的过渡了。 而且在使用过程中还可以看到 Git 优于 SVN 的地方:
第一,每个成员都可以在本地拥有一份完整的项目代码仓库,而不只是一个工作区的副本,任何人都可以在本地执行 addcommit ,而不需要考虑远端仓库是否有变更,直到需要的时候再去提交即可。
第二,Git 的工作区、暂存区、引用更新等设计,可以给开发者更多自由来切换当前工作,且不会造成代码丢失。

工作细节

中心化工作流的方式是:在远端(远端可以是服务器端,也可以是本地的任意目录)新建一个仓库,默认是 master 分支,作为唯一的中心仓库。 所有人都 clone 这个仓库作为本地仓库,并在本地仓库进行开发。本地的提交是和远端仓库无关的,等需要的时候再 push 进主仓库的 master 分支即可。

在这种方式下, 远端是唯一确定的中心仓库, 所有人都要以这个仓库为准。 所以,在提交之前要先 fetch 最新提交,在这些提交之上作出自己的更改(一般我们使用 rebase来完成)。

如果本地的修改和远端仓库中的变更发生了冲突,那么 Git 会暂停 rebase ,并让你来解决这些冲突。我们可以很简单的使用 git statusgit add 等命令完成冲突的合并。 另外, 如果我们解决不了冲突, 我们也可以使用 git rebase --abort 很容易的退出 rebase 的过程。

这样每天的工作方式就变成了,从中心仓库拉取最新代码, 然后开始一天的工作, 开发完成后,拉取中心仓库的更新, 合并代码后, 再提交至中心仓库, 结束一天的工作。 这样的好处就是不需要变更原先(使用SVN)的工作方式。当然弊端也很明显,你并不知道中心仓库的代码是否是稳定的,或者说并不能确定当你的代码和中心仓库代码合并后,是否是稳定的,带来的问题就是开发进度和回滚不那么方便控制。

示例

我们有两位程序员, A 和 B, 两人同时在对一个项目做开发, 并且使用 Git 的中心化工作流方式。

1.创建远端中心仓库

这里我们有两种方式:

借助于已经搭建好的平台 GitHub/GitLab 之类的,点击 create repo 即可。

在远端(这里只是为了区别本地仓库,事实上,使用任何一个其他人可以连通的机器都可以,包括自己本地其他目录) 创建一个 裸仓库 ,创建裸仓库和我们平时创建本地仓库的区别,可以参考我另一篇文章 Git 本地仓库和裸仓库 。

这里以第二种方式为例:

# --bare 参数必须有
git init --bare /the/repo/path.git

2.所有人都 clone 中心仓库到本地作为本地仓库

git clone /the/repo/path.git

注意仓库地址必须是正确的, 且有权限访问才能 clone 成功。

3.程序员 A 在他的本地仓库进行功能开发并进行发布

一般情况下,我们通过 git status 看看当前状态,并通过 git add git commit 等命令完成本地仓库的提交。 当然这个提交影响的也只是本地仓库而已,并没有对中心仓库产生任何影响,所以我们既不需要关心别人有什么提交,也不用担心我们当前的提交是否对别人造成了影响。当 A 认为自己所开发的功能已经完成, 那他将执行 git push origin master 这样的操作,将自己本地仓库所有不存在于中心仓库的提交都 push 到远端的中心仓库上。

4.程序员 B 在他本地仓库进行功能开发

B 在 clone 中心仓库后所做的操作和 A 一样,在本地仓库进行项目开发,并在本地仓库进行提交,他不需要知道中心仓库发生了什么样的变化。

5.程序员 B 将自己开发的功能并进行发布

B 在确认自己开发的功能已经完成后,想要将自己的代码通过 git push origin master 这样的操作发布至中心仓库,但是却被中心仓库提示他的修改已经和中心仓库有了分叉, 需要他先执行 git pull 之类的操作, 将中心仓库上 A 的提交与 B 本地的提交进行合并才允许他并入中心仓库。所以,他执行了 git pull --rebase origin master 来将中心仓库的修改并入他的本地仓库。使用 --rebase 参数的意义在于 fetch 执行完成后,将把 B 的所有提交移至 master 顶端。

当然这里不使用 --rebase 参数也会成功,只不过是会生成一个合并提交,有些情况下使用 --ff 参数也可以避免产生合并提交。在这里使用 --rebase 只是一个建议操作。

如果 A 和 B 修改的文件没有关联,一般情况下会直接完成合并,如果发生冲突,Git 将会暂停 rebase 的过程,并列出当前冲突的文件,你可以简单的使用 git statusgit add 等命令进行合并,合并后使用 git rebase --continue 继续 rebase 的过程。或者使用 git rebase --abort 退出 rebase 过程。

在 B 合并完成后,可以执行 git push origin master 将自己开发的功能发布至中心仓库。

至此,基础的中心化工作流方式就介绍完了,但是这里也很容易看出来其中的问题,除了前面说到过的以外,还有就是效率低下,如果很多人都在持续进行提交,那很影响新功能的提交(多人持续性进行提交)。 一个比较容易提升效率的方式就是切换到特性分支工作流的方式。

特性分支工作流

基于特性的分支工作流,可以为每个特性做隔离,避免对中心仓库主干代码造成影响。

工作细节

顾名思义, 就是根据每个特性都会开一个新的分支,每个分支都应该包含着描述性的名称,无论是一个人开发,还是多人协同,该特性的全部开发工作都在这个分支上进行。待该特性开发完成后, 并入主分支,然后删除分支,代码上线。

这种情况下, 最大的优势在于, 所有的特性开发都可以并行处理。 不必要像中心化工作流方式, 每个人的变动都可能引起其他的人的代码合并, 并且所有功能都杂糅在一起, 从测试和回滚都会变得很繁琐。 另外的一个好处就是特性分支可以推送到中心仓库,这样也便于多带带测试。

这里需要注意的是,特性分支往主分支合并的时机,应该是该特性开发完成,并测试通过,避免对主干代码造成污染。

在进行分支隔离后,我们发现,我们当前只处理了开发模式,但并没有涵盖一个很完备的产品生命周期, 开发、发布、维护等过程,所以,我们有了 Gitflow 工作流。

Gitflow 工作流

基于Gitflow 的工作流方式, 这种工作流方式, 主要是管理着新功能开发,发布及维护等模式,根据不同类型的工作对分支进行定义, 分为 特性分支修复分支release 分支开发分支主分支

主分支:中心仓库建立后的默认 master 分支(当然使用其他分支也可以,但要保证该分支是受保护的)。主分支随时保持代码是稳定的,并且有明确的版本标签,后续代码回滚等操作都将从主分支进行。

开发分支:中心仓库建立后,从 master 分支切出来,此时与 master 分支保持一致。后续演进中,开发分支随时保持代码最新,但却不一定是线上实际运行的代码。

git checkout -b develop

特性分支:应该从开发分支切出,开发完成后, 再合并进入开发分支, 如果达到了发布标准, 则从开发分支切出 release 分支, 切出来的这个分支,只做该版本内的代码修复, 不再加入新功能, 这时此分支处于锁定的状态。

修复分支, 用于对线上主分支代码的及时修复, 待修复完成后, 合并进入主分支, 再并入开发分支。 修复分支只能从主分支切出。

发版分支, 一般命名为 release-xxx 这个分支只能从开发分支切出, 最后并入主分支,打上版本号的标签,它也应该并入开发分支,如果中间有其他修复的话。

fork 工作流

fork 分支流和上面介绍的所有工作流都不太一样。它的上游有一个唯一仓库, 所有人都是 fork 这个仓库, 在自己的远端和自己的本地各维护一个仓库,待开发完成后推入自己的远端仓库,并结合 GitHub/GitLab等提交 Pull Request,进入了 review 阶段,待通过后,将会被合并入上游唯一的仓库。这种方式比较适合 GitHub 中的大型开源项目, 对于小团队的内部项目, 这种方式可能未必合适。
而且 fork 工作流, 会占用更多的资源(毕竟每个人都维护一份远端仓库)。 而且每个人都看不到其他人的动态,只有当提交 Pull Request 的时候, 才知道每个人发生了什么。

总结

我个人比较推荐的是 Gitflow 的开发工作流, 这种方式下,一切都是可控的, 每个分支都有各自独立的功能,目的性很明确, 同时,在做代码回滚之类的操作也是可以直接剔除。 另外, 在这种工作流方式下, 团队中的每个人都能很轻易的知道其他人在做什么, 做出了什么样的改变, 对于团队协作, 或许更加合适。

当然所有的工作流并不一定能完全套用, 可以吸取一些规范, 合并入自己的日常工作, 将代码仓库的合作流程标准化和规范化, 这也是一切自动化的基础。


可以通过公众号 MoeLove 和我联系

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/9680.html

相关文章

  • DevOps:持續整合 & 持續交付(Docker、CircleCI、AWS)

    摘要:原文出處持續整合持續交付這篇文章將一步一步介紹如何使用與來完成持續整合與持續交付的開發流程。前言什麼是持續整合持續交付持續整合持續交付,簡稱,具體介紹可以參考山姆鍋對持續整合持續部署持續交付的定義這篇文章。 原文出處:DevOps:持續整合&持續交付(Docker、CircleCI、AWS) showImg(https://segmentfault.com/img/bVlxh...

    Euphoria 评论0 收藏0
  • 企业级开发:Gitflow Workflow工作流

    摘要:同时,每一次更新,最好添加对应的版本号标签。在这个分支上的代码允许做小的缺陷修正准备发布版本所需的各项说明信息版本号发布时间编译时间等等。版本号的命名可以依据项目定义的版本号命名规则进行。 我说的以下流程,sourceTree等工具已经完美的支持了,鼠标点两下就完成了。简直是完美。 简介 Feature Branch Workflow是一种非常灵活的开发方式。对于一些规模比较大的团队,...

    rainyang 评论0 收藏0
  • github新出的action是什么? 用他做自动测试?

    摘要:体验分享本文一个尝鲜的体验分享并没有太复杂的技巧做了一个最少代码的例子展示让每个人都可以把用起来如果路过的大牛有高级技巧请留言分享我会补充下面正文开始是什么是一个免费的操作系统容器我们可以让他预装开发环境注后面的文章假设我们选了一台装有的服 体验分享 本文一个尝鲜的体验分享, 并没有太复杂的技巧, 做了一个最少代码的例子展示, 让每个人都可以把action用起来, 如果路过的大牛有高级...

    jimhs 评论0 收藏0
  • ES6指北【6】——详谈解构赋值【附赠练习题】

    摘要:指北详谈解构赋值附赠练习题一何谓解构赋值基本概念首先我们看一下给的定义解构赋值语法是一个表达式,这使得可以将值从数组或属性从对象提取到不同的变量中从定义中,我们可以发现解构赋值的作用是对变量进行赋值主要通过两个方面实现这个作用数组将数组中的 ES6指北【6】——详谈解构赋值【附赠练习题】 一、何谓解构赋值? 1. 基本概念 首先我们看一下MDN给的定义 解构赋值语法是一个 Javasc...

    sorra 评论0 收藏0
  • PHPer的月工作总结之构建抽奖工具

    摘要:这个月的计划本来是对基础的数据结构做一个沉淀,但是,但是,但是这个月的的状态就是工作工作既然这样就总结下这个月的工作吧。 前言 目标是每个月写一篇文章,对从事编程开发的基础知识做一个学习总结。这个月的计划本来是对基础的数据结构做一个沉淀,但是,但是,但是......这个月的的状态就是工作工作...既然这样就总结下这个月的工作吧。 工作内容 促销活动的抽奖工具,具备如下功能: 根据不同...

    W_BinaryTree 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<