# 分支的工作流程
分支的工作流程要取决于它的使用背景,我们可以将它分为两个主要的方面。
##### 注释
请记住,在这里它只是一个语义层面上的划分。在技术和实用层面上,一个分支就是一个分支,它们的原理都是一样的。
## (A) 短期分支(Short-Lived)/主题分支(Topic Branches)
在本书前面的章节中已经提到了我对建立分支的一些建议,例如:_对应新功能的分支_,_修复错误的分支_ 以及 _进行代码尝试所建立的分支_。这些分支都有两个重要共同特征:
* 它们只涉及一个**单一主题**,而且它包含的代码要和它的主题相对应。例如,你不应该建立一个关于购物车功能的分支,并且再在这个分支上去提交一些有关于邮件订阅功能和错误修复的改动。
* 它们都只有非常短暂的生命周期。通常情况下,这个生命周期只维持到这个开发主题的结束之后(例如当错误被修复,新功能被完成……),这个分支的改动就会被整合到项目的大环境中去,并且这个分支也会被随之删除掉。
![branch-types](https://box.kancloud.cn/2016-05-04_572967db84ade.png)
## (B) 长期分支 Long-Running Branches
相对于那些基于一个单一开发主题或是一个错误修复的短期分支来说,这类分支被定义在更高的层面上。它们代表了在整个项目生命周期的一种状态(比如:“产品”,“测试”,“研发”状态)。它们在项目中保存的时间比较长,甚至可能是整个项目的生命周期。这类分支有如下一些典型特点:
* 你不应该直接在这个分支上工作。但是你可以整合其他的分支(例如功能分支或是其他的长期分支)到这类分支中来,尽量不要对它直接进行提交。
* 一般来说,在长期分支之间也存在不同的等级。例如 “master” 分支一般被定义为最高等级。它应该只保存产品代码(production code)。在它之下应该存在一个 “开发(development)” 分支。它会被用来进行真正的开发和测试工作,然后整合入 “master” 分支……
我们应该为项目建立哪些长期分支呢?该如何使用它呢?这并不能一概而论。这在很大程度上取决于开发团队的规模,开发风格和项目的需求,甚至于不同的客户。这个规则必须被很清楚的定义出来,并且要得到整个开发团队的认同和遵守。
## 一个简单通用的分支策略
我们已经讲到了,不同的开发团队必须定义合适自己的分支策略。然而,还是有一种简单通用的流程,它应该适用于大多数的开发团队。
### 仅仅使用一个长期分支
虽然你可以在你的开发流程中引入多个长期分支,但是这样也会存在很多不利因素。最为显著的是会让你开发流程变得非常复杂!在你的工作流程中仅仅定义和使用一个单一的长期分支可以避免很多不必要工作,并且使项目的开发变得比较简单。
##### 概念
在一般的情况下, “master” 分支可以有效地代表你的产品代码。然而一个重要的前提就是,**所有被合并到 “master” 分支的代码都必须保证正确!** 你必须保证它们的质量。因此它们必须经过测试,它们的代码必须被检验过和确认过。
这也意味着,开发工作不应该直接在 “master” 分支上进行,这也是一个最基本的准则。因此当你使用了 “git checkout master” 命令切换到 “master” 分支后并提交改动时,你就要问问自己,这样是否符合流程?这些改动是否能保证正确?
### 主题分支
每当你开始着手开发一个新的功能的或是修复错误时,你都应该对应不同的主题建立一个新的分支。这是一种很通用的做法,并且也要成为你的一种习惯。
如果在你的项目仓库中只存在一个长期分支,那么所有的主题分支都必须基于这个 “master” 分支。当你所开发的功能完成后,或者是错误被修复后,这些所对应的改动就理所当然的要被合并回 “master” 分支。
在你开发你的新功能的同时,团队的其他开发人员已经把各自完成的改动整合回了 “master” 分支。在这种情况下,你就必须经常性地把那些在 “master” 分支上的改动合并到你的工作分支上来。这就确保了你的工作分支一直处于最新的状态,并且当你要把已完成的改动整合回 “master” 分支上时,可以减少可能出现的冲突和风险。
请不要忘记这个简单的黄金法则:只有正确和稳定的代码才能被整合到 “master” 分支上来!如何确保这些代码正确性呢?这就依靠你和你的团队了。例如使用单元测试(unit tests),代码审查(code reviews)等等。
### 保持远程同步
在 Git 中,远程和本地仓库可能彼此毫无依赖关系。不管怎样,本地和远程的分支必须被一致对待。
但是这样也并不代表你必须要发布你的 _每一个_ 本地分支,拥有一些完全属于你的私有分支也是非常必要和有意义的。例如当你单独的研究一些新功能,或是尝试调试一些新的技术时。
不管怎样,当你要发布你的一个本地分支时,你就应该给它对应的远程分支一个相同的名称。例如,如果你有一个本地分支被命名为 “login-ui”,当你要发布它时,在远程仓库上它也必须拥有 “login-ui” 这个名字。
### 频繁推送
保持与远程分支的同步并不是只停留在结构层面上,经常性地通过 “git push” 命令发布你的改动可以有助于团队里的其他的开发人员看到和使用你的最新开发成果。附带的还有一个最大的好处是,它可以作为你的远程备份。
## 其他分支策略
上述策略是最适用于小型的开发团队。而一个较大的开发团队可能会需要更多的规则和更复杂的结构。
在网络上搜索其他开发团队的策略将为你提供更多的选择。这是其中一个非常流行并且可能是值得尝试的一种工作流程 “[git-flow](https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/git-flow)”。
##### 注释
我个人认为 git-flow 有些过于强大了:
* 它拥有自己的脚本来诠释 Git 和拥有自己独有的命令。这使得它很难在一个 GUI 应用程序中被使用。
* 在它竭尽全力地简化 Git 的同时, 它又需要让使用者去学习一种几乎是全新语言定义的命令。
通过正确的学习 Git 的基本知识,并且在开发团队中确定一个专属的共同工作流程后,你可能会认为类似 git-flow 所定义的扩展有些过于束缚。
- Learn Version Control with Git 中文版
- 前言
- Part 1 - 基础知识
- 什么是版本控制?
- 为什么要使用版本控制系统?
- 准备工作
- 版本控制的基本工作流程
- 从一个未被纳入版本控制的项目开始
- 从一个已被纳入版本控制的项目开始
- 工作在你的项目上
- Part 2 - 分支与合并
- 分支可以改变你的生命
- 在分支上工作
- 暂时保存更改
- 切换一个本地分支
- 合并改动
- 分支的工作流程
- Part 3 - 远程仓库
- 关于远程仓库
- 连接一个远程仓库
- 查看远程数据
- 整合远程的改动
- 发布一个本地分支
- 删除分支
- Part 4 - 高级应用
- 撤销操作
- 用 diff 来检查改动
- 处理合并冲突
- Rebase 代替合并
- 子模块
- git-flow 的工作流程
- 使用 SSH 公钥验证
- Part 5 - 工具与服务
- 桌面应用程序
- 比较和整合工具
- 代码托管服务
- 更多学习资源
- 附录
- 版本控制的最佳实践
- 命令 101
- 从 Subversion 过渡到 Git
- 为什么选择 Git