本文首发于 刘星的个人网站
Git 是目前世界上最先进的分布式版本控制系统。它使我们更方便的跟踪,管理和组织代码。也帮助了我们更好的与其他开发者进行协作开发。但是没有规矩不成方圆。协作开发必须有一个规范来约束各个贡献者的行为。这个规范就是 Git 工作流程(Git Workflow),也为我们规范各个分支管理策略等行为。
Git 工作流程是有关如何使用 Git 以高效协作开发的规则或策略建议,下文这些常见工作流程只是作为指导参考,这些工作流不是一成不变的,我们应该根据自己的项目选择或制定合适自己的工作流。
首先我们来介绍最简单粗暴的集中式工作流,如果你用过SVN,那么你可以无痛切换到 Git 集中式工作流。该工作流只用到 master
这一个主分支来维护我们的代码,这也是该工作流的主要工作方式。
1 、首先 clone 远程仓库到本地
git clone ssh://user@host/path/to/repo.git
2 、然后在本地的 master 分支做出修改完成开发后,创建一个提交
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
3 、然后推送到远程仓库
git push origin master
4 、 如果此时本地仓库与远程仓库有了分歧,Git 将拒绝操作并报错。这时我们就应该先 pull 远程仓库的修改到本地仓库后再解决重新推送
git pull --rebase origin master
5 、如果有冲突,Git 会在合并有冲突的提交处暂停 rebase 过程,并报出错误信息,我们在解决掉冲突后可以使用一下命令将更改加入暂存区后继续只能执行 rebase:
git add <some-file>
git rebase --continue
如果遇到一个搞不定的冲突,这可以使用一下命令来终止 rebase
git rebase --abort
master
这一个分支,所有的修改都推送到 master 分支master
分支代表了项目的正式发布版本,所以提交历史应该被尊重且是稳定不变的SVN
迁移过来的团队来说很友好当您的团队规模扩大时,上面详述的冲突解决过程可能会成为瓶颈
完全没有发挥 Git 的优势,在实际使用 Git 协作的项目开发中很少使用集中式工作流
如果在稍大的团队中使用前面的集中式工作流,那么可能会在解决冲突中浪费很多时间。在实际开发中我们基本上都是都 功能驱动式开发,基于功能需求,创建相应的分支进行开发,完成开发合并到主分支后再被删除掉。接下来我们介绍的三个工作流:GitHub Flow,Git Flow 及 Gitlab Flow 都是基于不同的分支管理策略运作的。
GitHub Flow 是一个轻量级的基于分支的工作流程。它由 GitHub 在 2011 年创建。分支是 Git 中的核心概念,并且 GitHub 工作流程中的一切都以此为基础。
最重要的的一点就是:**main
/ master
分支中的任何内容始终都是可部署的**。其他分支(功能分支)创建用于新功能和错误修复的工作,并且在工作完成并经过检查后,这些分支将合并回到主分支中后删除。这些分支名应该是具有描述性的如 refactor-authentication
, user-content-cache-key
, make-retina-avatars
。
1 、首先 clone 远程仓库到本地
git clone ssh://user@host/path/to/repo.git
2 、根据要实现的功能创建一个新的分支,分支名应该具有描述性,如实现鉴权功能:feature-auth
git checkout -b feature-auth
3 、然后将新工作提交到该分支下,并定期将工作推送到远程仓库
# 创建一个 commit
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
# 将分支推送到远程仓库
git push --set-upstream origin feature-auth
4 、当你需要帮助或者反馈,或是你觉得你已经完成该功能的工作准备合进主分支的时候创建 pull request
5 、当你的这部分工作在 pull request 中,被 review 以及 approved 后,则可以合并到主分支。
git checkout master
git pull
git pull origin feature-auth
git push
6 、合并到主分支后,应立即对其进行部署
master
分支中的任何内容都是可部署的master
创建出一个分支,并给出描述性的名称(如:new-oauth2-scopes
)master
master
,你可以并且应该立即进行部署基于功能分支的工作流是一中相当灵活的方式。但是问题也是有时候过于灵活。对于大型团队,常常需要给不同分支分配一个更具体的角色。Git Flow 工作流是管理功能开发、预发布和维护的常用模式。
Git Flow 是最早诞生并且相当流行的工作流程。它由 Vincent Driessen 于 2010 年创建。Git Flow 工作流定义了一个围绕项目发布的严格分支模型。虽然比 GitHub Flow 的功能分支工作流复杂一点,但提供了用于一个健壮的用于管理大型项目的框架。
Git Flow 工作流没有用超出功能分支工作流的概念和命令,Git Flow 为不同的分支分配一个很明确的角色,并定义分支之间如何和什么时候进行交互。
假设你已经创建好了中央仓库,并且已将其 clone 到本地
1 、首先我们来从主分支创建一个开发分支 develop, 并推送到服务器
git branch develop
git push -u origin develop
以后这个分支将会包含了项目的全部历史,而 master
分支将只包含了部分历史
2 、接下来我们开始开发新功能,基于 develop 分支创建新的功能分支
git checkout -b some-feature develop
并在自己的功能分支上进行开发、创建提交:
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
3 、当你在你的分支上完成工作,准备好进行合并时,请打开一个 Pull Request,用于合并到develop
分支。如果你的团队没使用 Pull Request 则可以直接合并到本地的 develop 分支然后推送到中央仓库。
git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push
# 删除本地分支
git branch -d some-feature
并且在功能分支合并后应该立即删除
4 、当我们的 develop
分支进行到需要发布时,需要从develop
分支创建一个新的发布分支,命名为release-*
或release/*
。这一步也确定了发布的版本号:
git checkout -b release-0.1.0 develop
这个分支是一个预发布的版本,只做 bug 修复、文档生成等面向发布的任务。新功能不再添加到这个分支上
5 、经过一系列测试确认没有问题,准备好了对外发布后,我们需要将发布分支合并到 master 分支,并打下 tag
git checkout master
git merge --no-ff release-0.1
git push
git tag -a 0.1 -m "release 0.1 publish" master
git push --tags
6 、同时我们还需要将这个发布分支合并回去 master 分支
git checkout develop
git merge --no-ff release-0.1.0
git push
最后我们还需要删除掉这个发布分支 release-0.1.0
7 、如果我们的线上版本出现问题时,就需要创建一个维护分支,用于快速给产品打补丁。这个维护分支需要从master
分支上创建,提交修改以解决问题,然后再直接合并回master
分支:
git checkout -b hotfix-auth master
修复完成后将其合并到 master 分支
git checkout master
git merge --no-ff hotfix-auth
git push
同时打下新的 tag
git tag -a 0.1.1 -m "release 0.1.1 publish" master
git push --tags
同样也需要将修复分支合并到 develop 分支
git checkout develop
git merge --no-ff hotfix-auth
git push
最后删除掉这个热修复分支
git branch -d hotfix-auth
它基于两个长期的主要分支:
master
该分支包含生产代码。 该分支是稳定的发布版develop
此分支包含预生产代码。所有的功能分支完成后需要合并到该分支其次在开发中还有三种短期分支
develop
分支中检出也必须合并回develop
。master
和 develop
分支分别记录发布和功能开发的历史master
和 develop
GitLab Flow 是通过创建工作流 GitLab在 2014 年。它将功能驱动的开发和功能分支以及问题跟踪结合在一起。它是 Git Flow 与 GithubFflow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。GitLab Flow 和 GitHub Flow 之间的最大区别是 GitLab Flow 中的环境分支支持(例如staging
和production
),
GitLab Flow 的最大原则叫做"上游优先"( upsteam first ),即只存在一个主分支master
,它是所有其他分支的"上游"。只有上游分支采纳的代码变化,才能应用到其他分支。
GitLab Flow 分成两种情形来应付不同的开发流程
对于持续发布的项目,它建议在master
分支以外,再建立不同的环境分支,每个环境都会有对应的分支。比如,开发环境的分支是master
,预发环境的分支是pre-production
,生产环境的分支是production
。
master
用于发布到测试环境,该分支为受保护的分支pre-production
用于发布到预发环境,上游分支为 master
production
用于发布到正式环境,上游分支为 pre-production
如果生产环境(production)发生错误,则要建一个新分支修改完后合并到最上游的开发分支(master)此时就是 Upstream first),且经过测试,再继续往 pre-production branch,要经过测试没有问题了才能够再往下合并到生产环境。
对于"版本发布"的项目,建议的做法是每一个稳定版本,都要从master
分支拉出一个分支,比如2-3-stable
、2-4-stable
等等。
再出现 bug 后,根据对应的 release branch 创建一个修复分支,修复工作万和城呢个后,一样要按着上游优选的原则,先合并到 master 分支,经过测试才能到才能够合并到 release 分支,并且此时要更新小版本号。
和之前一样。首先 clone 项目到本地
1 、当我们要实现新功能或是修复 bug 时。从 master 检出新的分支如:feature-auth
git checkout -b feature-auth
2 、然后在该分支下进行工作,完成后创建提交
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
推送代码到远程仓库,
git push origin feature-auth
3 、代码推送到仓库后,自定运行 GitLab CI
4 、当我们开发完成准备合并进 master 时,在 GitLab 上创建一个 Merge Request
5 、项目管理者进行代码审查,通过后,合并到master
6 、运行第二次 GitLab CI
7 、通过相应的测试后,将master
分支合并到stable
,如果是新版本则创建一个新的stable
分支
8 、为stable
打上 tag,并进行发布
相比较于 GitHub Flow 更复杂
当需要在生产中维护多个版本时,它可能会像 Git Flow 一样变得复杂
没有一个万能的适合所有项目的 Git 工作流程及分支策略,无论最终选择哪种策略,你都可以通过进一步的修改来优化它。就像前文所说的,Git 工作流程对我们提升团队生产力非常重要,在制定我们的工作流程时,应该尽量符合我们的项目具体业务需求及开发环境。但是也有如下几点小建议:
临时分支不应该存在太久,每个分支应尽量保持精简,用完即删
工作流应该尽量简单,同时方便回滚
工作流程应该符合我们的项目发布计划
本文完
欢迎可以关注我的公众号,一起玩耍。有技术干货也有扯淡乱谈
左手代码右手砖,抛砖引玉
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.