Git 最佳实践:分支管理
5月份,为统一团队git分支管理规范,刚开始准备自己写,在网上搜了下,发现不少不错的git分支管理实践。最后我为团队选择了这个git分支管理实践
A successful Git branching model ,网上有不少参考这篇文章写的中文版gitflow实践,推荐一个中文版的Git 最佳实践:分支管理。
除了团队git管理的需要,我自己在github上有重要的开源项目采用github flow,这里转载一篇关于这两种分支管理的文章:GitHub Flow & Git Flow 基于Git 的两种协作开发模式 。
【转载自】:https://www.cnblogs.com/sloong/p/5868292.html
介绍基于Git 两种协作开发模式,GitHub Flow & Git Flow
对于Github 一些好用的特殊操作技巧 ,可以见GitHub 特殊操作技巧 和Git的基本操作
一 GitHub Flow
GitHub Flow —— 以部署为中心的开发模式,通过简单的功能和规则,持续且高速 安全地进行部署。在实际开发中往往一天之内会实施几十次部署,而支撑这一切的,就是足够简单的开发流程以及完全的自动化。

GitHub Flow 特点:
- 令master 分支时常保持可以部署的状态
- 进行新的作业时要从master 分支创建新的分支,新分支名称要具有描述性
- 在
2新建的本地仓库分支中进行提交 - 在Github 端仓库创建同名分支,定期push
- 需要帮助、反馈,或者branch已经准备merging时,创建Pull Request,以Pull Request 进行交流
- 让其他开发者进行审查,确认作业完成后与master分支进行合并(合并的代码一定要测试
- 与master分支合并后,立刻部署
使用Github Flow 的前提条件:
- 团队规模最好控制在15-20人之内,具体见 how-github-works
- 部署作业完全自动化。必须自动化,一天之类需要多次部署
- 使用部署工具(Capistrano,Mina,Fabric,Webistrano,Strano等),让部署时所需的一系列流程自动化。
- 通过Web界面进行部署,Capistrano 等部署工具需要命令执行操作,开发者以外的人很难实施部署
- Capistrano http://github.com/capistrano/capistrano //Ruby开发的代表性部署工具
- Webistrano http://kentaro/webistrano //可以通过Web执行Capistrano的工具
- 导入开发时注意事项:随着团队人数的增多及成熟度的提高,开发速度会越来越快。往往一个部署尚未完成,另一名开发者就已经处理完下一个pull request,开始实施下一个部署。在这种情况下,一旦正式环境出现问题,很难分辨哪个部署造成了影响。为了应对该情况,建议在部署实施过程中通过工具加锁。
- Git Hook 自动部署
- 重视测试
- 让测试自动化
- 编写测试代码,通过全部测试
- 维护测试代码

二 Git Flow
荷兰程序员 Vincent Driessen 曾发表了一篇博客,让一个分支策略广为人知。具体流程见下图(引用该博客的一幅图片)

这一流程最大的亮点是考虑了紧急Bug的应对措施,整个流程显得过于复杂,所以在实施该方案前,需要对整个开发流程进行系统的学习。也需要借助Git flow 等工具的辅助。
下面根据上图,按不同分支 进行 说明:
master 分支和 develop分支
在Git Flow 中,这两个分支至关重要,它们会贯彻整个流程始终,绝对不会被删除。
master 分支
master 分支时常保持着软件可以正常运行的状态。由于要维护这一状态,所以不允许开发者直接对master 分支的代码进行修改和提交。
其他分支的开发工作进展到可以发布的程度后,将会与master分支进行合并,并且这一合并只在发布成品时进行。发布时将会附加版本编号的Git标签。
develop分支
develop分支是开发过程中代码中心分支。与master 分支一样,这个分支也不允许开发者直接进行修改和提交。
程序员要以develop分支为起点新建feature 分支,在feature 分支中进行新功能的开发或者代码的修正。也就是说develop分支维系着开发过程中的最新代码,以便程序员创建feature分支进行自己的工作。
在feature 中工作
feature 分支以develop分支为起点,是开发者直接更改代码发送提交的分支。开发流程:
- 从develop分支创建feature分支
- 从feature分支中实现目标功能
- 通过Github 向develop发送pull request
- 接受其他开发者审核后,将Pull Request合并至develop分支
具体指令:
$ git checkout develop
$ git pull
$ git flow feature start add-user //add branch feature/add-user
$ git branch
// feature/add user start commit commit ....
$ git push orgin feature/add-user
//到github 上去代码审查,切到develop分支,进行pull request
$ git checkout develop
$ git pull // 当feature/add-user 合并到 develop后,本地develop 需要更新到最新状态
注意,默认状态是pull request 到master。这时需要手动切换到develop分支,再进行pull Request 操作。
如果采用该开发策略,那么可以在setting 中 Option 中,修改Default Branch 为 develop ,这样就省去了手动修改的麻烦。
与develop分支合并后,已经完成工作的feature分支可以在适当的时机删除

更新本地的develop分支
我们发送的pull request 在github 端与develop 合并后,为了让其反应到本地的develop分支中,我们需要进行以下操作:
- 切换到develop分支
- 执行git pull (fetch & merge)
每当需要从develop分支创建feature等分支时,记得一定要先执行上述操作,保证develop分支处于最新状态。
release分支
创建 release分支 ,在这个分支,我们只处理与发布前准备相关的提交,比如版本编号变更的元数据的添加工作。如果软件部署到预演环境后测试出bug,相关修正也要提交到这个分支。
注意:该分支绝对不能包含需求变更或者功能变更等重大修正。这一阶段的提交数应该限制到最低。
$ git checkout develop
$ git pull
$ git flow release start '1.0.0'
当所有修正处理完后,我们结束这分支
$ git flow release finish '1.0.0'
//期间会需要填写 提交信息、这个版本的提交信息、合并的提交信息。无特殊情况,一般默认。
全部结束后,会显示如下
$ git flow release finish '1.0.0'
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Merge made by the 'recursive' strategy.
README.md | 2 ++
1 file changed, 2 insertions(+)
Switched to branch 'develop'
Your branch is up-to-date with 'origin/develop'.
Already up-to-date!
Merge made by the 'recursive' strategy.
Deleted branch release/1.0.0 (was d3f54a0).
Summary of actions:
- Release branch 'release/1.0.0' has been merged into 'master'
- The release was tagged '1.0.0'
- Release tag '1.0.0' has been back-merged into 'develop'
- Release branch 'release/1.0.0' has been locally deleted
- You are now on branch 'develop'
查看版本tag
通过前面一系列的操作,我们创建了与发布版本号相同的Git标签
$ git tag
1.0.0
更新到远程仓库
对此,我们对多个分支进行了修改,所以需要利用push操作将修改更新到Github端的远程仓库。先从develop开始
$ git push origin develop
然后是master
$ git checkout master
$ git push origin master
再push 标签信息
$ git push --tags
这样版本号 1.0.0 的标签信息就已经push 完成
在hotfix 分支下进行工作
下述情况需要创建 hotfix 分支
- release 版本中发现了bug 或者漏洞
- develop 分支正在开发新功能,无法面向用户进行发布
- 漏洞需要及早处理,无法等到下一次版本发布
假设修复BUG 后的版本至 1.0.1
$ git fetch origin
现在以1.0.0的标签信息为起点,创建名为1.0.1 的hotfix分支。
$ git flow hotfix start '1.0.1' '1.0.0'
修复工作结束后,将hotfix 分支push 到github端的远程仓库,并向master分支发起Pull Request
$ git push origin hotfix/1.0.1

创建标签和进行发布
在Github项目主页,点击release ,为本次hotfix 创建1.0.1标签。点击 Draft a new release 按钮,输入相关标签信息,在Target中指定master分支(master分支已经合并了hotfix1.0.1的修改)。然后填写相关信息,点击Publish release 进行发布
1.0.1发布后,之前发布的成品也就完成了生命周期
$ git fetch origin
从 hotfix 分支合并到develop 分支
登录到Github,从hotfix1.0.1分支向develop分支发送Pull Request即可。审查后便会被合并到develop分支
Git Flow 的小结
建议把开发流程图放大贴在墙上,这样能够有效帮助团队成员理解流程内容
版本号的分配规则 x.y.z
x: 在重大功能变更,或者版本不向下兼容+1,此时y z归零
y: 在添加新功能或者删除已有功能+1 此时z归零
z: 只在进行内部修改后+1.

Git 最佳实践:分支管理的更多相关文章
- 干货:基于 Git Flow 的 Git 最佳实践(附加解决大家经常碰到的问题)
突然想写这一篇Git的使用心得,主要有几个原因,其一是自己使用Git也有快3年时间了,其间自己经历过一些坑,也有迷茫的时候,在呆过的大大小小的团队中,其实每个人也都并不是Git专家,很多对于流程以及G ...
- Maven最佳实践:管理依赖
From:http://juvenshun.iteye.com/blog/337405 Maven最佳实践:管理依赖 "If I have seen further it is by sta ...
- python使用git进行版本控制-分支管理
1.远程克隆 最好的方式是先创建远程库,然后,从远程库克隆: 首先在github上创建一个新的仓库,名字叫gitskills 我们勾选Initialize this repository with a ...
- Git如何进行分支管理?
Git如何进行分支管理? 1.创建分支 创建分支很简单:git branch <分支名> 2.切换分支 git checkout <分支名> ...
- Git 远程仓库分支管理
目录 目录 速查表 关联远程代码仓库 克隆远程仓库 分支管理 创建分支 切换分支 合并分支 删除分支 解决冲突 速查表 指令 作用 git branch 查看分支 git branch newBran ...
- git最佳实践之feature和hotfix分支
先来复习一波,git的最佳分支管理流程: 再简单复习各个分支: master: 主分支,主要用来版本发布. develop:日常开发分支,该分支正常保存了开发的最新代码. feature:具体的功能开 ...
- 【Git教程】Git教程之分支管理
在前一篇文章中,主要针对Git本地仓库和远程仓库的基本操作命令进行了简要介绍,本文主要集中介绍Git的另一个主要的特点:分支管理和多人协作. 什么是分支管理 当一个任务需要多人协作完成时,每个 ...
- git flow开发分支管理模型
Git Flow 是什么 Git Flow是构建在Git之上的一个组织软件开发活动的模型,是在Git之上构建的一项软件开发最佳实践.Git Flow是一套使用Git进行源代码管理时的一套行为规范和简化 ...
- Git远程和分支管理
一.远程 Git是分布式版本控制系统,最重要的优点就是远程仓库托管代码.不用自己搭建一个服务器,在github上面注册一个账户就可免费获取远程仓库. 首先需要先在github上面 ...
随机推荐
- [Swift]LeetCode688. “马”在棋盘上的概率 | Knight Probability in Chessboard
On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K ...
- [Swift]LeetCode1031. 两个非重叠子数组的最大和 | Maximum Sum of Two Non-Overlapping Subarrays
Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping ...
- 有点深度的聊聊JDK动态代理
在接触SpringAOP的时候,大家一定会被这神奇的功能所折服,想知道其中的奥秘,底层到底是如何实现的.于是,大家会通过搜索引擎,知道了一个陌生的名词:动态代理,慢慢的又知道了动态代理有多种实现方式, ...
- 论Java访问权限控制的重要性
人在什么面前最容易失去抵抗力? 美色,算是一个,比如说西施的贡献薄就是忍辱负重.以身报国.助越灭吴:金钱,算是另外一个,我们古人常说“钱乃身外之物,生不带来死不带去”,但我们又都知道“有钱能使鬼推磨” ...
- JVM基础系列第13讲:JVM参数之追踪类信息
我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演 ...
- .NET Core中的数据保护组件
原文地址: PREVENTING INSECURE OBJECT REFERENCES IN ASP.NET CORE 2.0 作者: Tahir Naushad 背景介绍 在 OWASP(开放式 W ...
- 【干货】Chrome插件(扩展)开发全攻略
写在前面 我花了将近一个多月的时间断断续续写下这篇博文,并精心写下完整demo,写博客的辛苦大家懂的,所以转载务必保留出处.本文所有涉及到的大部分代码均在这个demo里面:https://github ...
- NMF学习练习:做电影推荐
NMF是很久以前学的,基本快忘没了,昨天YX提出来一个关于NMF(同音同字不同义)的问题,才又想起来. 自己的学习笔记写的比较乱,好在网上资料多,摘了一篇,补充上自己笔记的内容,留此助记. NMF概念 ...
- JDK源码分析(9)之 WeakHashMap 相关
平时我们使用最多的数据结构肯定是 HashMap,但是在使用的时候我们必须知道每个键值对的生命周期,并且手动清除它:但是如果我们不是很清楚它的生命周期,这时候就比较麻烦:通常有这样几种处理方式: 由一 ...
- 程序员十大热门flag,有你的吗?
2018的尾声,南方人期盼已久的下雪天终于到了,实在是太鸡冻了! 而赏雪的喜悦也伴随着寒冷的忧伤 早上起床越来越难,衣服怎么裹都还是冷 这时,穿搭届的神话般的人物——程序员们,可能又要引起轰动了吧! ...