git 入门教程之分支策略
默认情况下合并分支常常直接使用 git merge 命令,是最方便快速的合并方法.其实这种情况下 git 采用的是 fast forward 模式,特点是删除分支后,会丢失分支信息,好像从来没存在该分支一样,而我们推荐的是recursive 模式,能够保留分支的版本记录.
递归模式(recursive)
创建并切换 dev 分支,提交版本后切换回 master 分支,然后再合并 dev 分支,这不过这一次不再使用 git merge dev 命令:
# 创建并切换 dev 分支
$ git checkout -b dev
Switched to a new branch 'dev'
# 提交版本
$ echo "git checkout -b dev" >> test.txt
$ git add test.txt
$ git commit -m "git checkout -b dev"
[dev 44d68f6] git checkout -b dev
1 file changed, 1 insertion(+)
# 切换回 master 分支
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$
现在添加 --no-ff 参数禁用 fast forward 模式,即git merge --no-ff:
$ git merge --no-ff -m "git merge --no-ff dev" dev
Merge made by the 'recursive' strategy.
test.txt | 1 +
1 file changed, 1 insertion(+)
$
上述内容显示,这次使用的不再是 fast forward 模式,而是 recursive 模式,那让我们看一下提交历史有什么不同吧!
$ git log --pretty=oneline --graph
* 22fbef7 (HEAD -> master) git merge --no-ff dev
|\
| * 44d68f6(dev) git checkout -b dev
|/
* 3b8f434 fix conflict
|\
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e51 learn git branch
* b3d8193 (origin/master, origin/HEAD) see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit
$

这种递归模式(recursive) 有一个明显的特点就是会产生一个新的 commit ,并不会像之前快速前进模式(fast forward)那样单纯更改 HEAD 的指向.
秉承着阅后即焚的习惯,分支一旦合并后就立即删除,现在删除 dev 分支,看一下会发生什么:
# 删除 dev 分支
$ git branch -d dev
Deleted branch dev (was 44d68f6).
# 查看提交历史
$ git log --pretty=oneline --graph
* 22fbef7 (HEAD -> master) git merge --no-ff dev
|\
| * 44d68f6 git checkout -b dev
|/
* 3b8f434 fix conflict
|\
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 (origin/master, origin/HEAD) see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit
$

由此可见,删除 dev 分支后仅仅少了 dev 的引用而已,原来 dev 分支所做的更改全部保留下来了!
快速前进模式(fast forward)
创建并切换 dev 分支,提交版本后切换回 master 分支,然后再合并 dev 分支,使用 git merge dev 命令:
# 创建并切换 dev 分支
$ git checkout -b dev
Switched to a new branch 'dev'
# 提交版本
$ echo "fast forward" >> test.txt
$ git add test.txt
$ git commit -m "fast forward"
[dev 3fe94c0] fast forward
1 file changed, 1 insertion(+)
$
现在切换回 master 分支,采用默认的git merge 命令合并 dev 分支:
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 8 commits.
(use "git push" to publish your local commits)
sunpodeMacBook-Pro:git-demo sunpo$ git merge dev
Updating 22fbef7..3fe94c0
Fast-forward
test.txt | 1 +
1 file changed, 1 insertion(+)
$
上述内容显示这次合并采用的是快速前进模式(fast forward),让我们看一下提交历史:
$ git log --pretty=oneline --graph
* 3fe94c0 (HEAD -> master, dev) fast forward
* 22fbef7 git merge --no-ff dev
|\
| * 44d68f6 git checkout -b dev
|/
* 3b8f434 fix conflict
|\
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 (origin/master, origin/HEAD) see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit
$
上述内容表明,此次合并并没有产生新的 commit ,只是更改下 HEAD 指向而已(HEAD -> master, dev).

同样,现在删除 dev 分支,再看一下提交历史:
# 删除 dev 分支
$ git branch -d dev
Deleted branch dev (was 3fe94c0).
# 查看提交历史
$ git log --pretty=oneline --graph
* 3fe94c0 (HEAD -> master) fast forward
* 22fbef7 git merge --no-ff dev
|\
| * 44d68f6 git checkout -b dev
|/
* 3b8f434 fix conflict
|\
| * 0fe95f8 git commit c2
* | 0949cc3 git commit c3
|/
* 5c482cd git commit c1
* 413a4d1 see https://snowdreams1006.github.io/git/usage/branch-overview.html
* 9c30e50 learn git branch
* b3d8193 (origin/master, origin/HEAD) see https://snowdreams1006.github.io/git/usage/remote-repository.html
* 8e62564 add test.txt
* 9b196aa Initial commit
$

由此可见,快速前进模式一旦删除分支后就彻底丢失了分支的信息,即便是从提交历史中也找不到曾经存在的痕迹!
分支策略
git 是分布式版本控制系统,同时鼓励大量使用分支,如此一来大量的分支该如何管理?
实际开发中,建议准从以下原则进行分支管理:
master分支作为主干分支,负责对外提供服务,要求稳定可靠,因为应该专人负责更新维护.dev分支作为开发分支,取代master分支的开发地位,积累到一定产出时再合并到master分支.feature分支作为新功能分支,根据实际情况动态创建,删除分支,并适时合并到dev分支.bugFixed分支作为修复特定 bug 分支,可能由master分支衍生而来,也可能由dev分支衍生等等,修复后及时合并到原分支.custom自定义分支,项目成员私有分支,由上级领导分配任务后各开发人员自行选择创建自己的分支,并根据实际情况决定合并到dev分支或feature等分支.

小结
- 快速前进模式(
git merge <name>)不保留分支合并历史,递归模式(git merge --no-ff -m <remark> <name>)保留分支合并历史. - 制定大家都认同的分支管理原则,并严格准守规则.
git 入门教程之分支策略的更多相关文章
- git 入门教程之分支总览
分支就是一条独立的时间线,既有分支,必有主干,正如一棵树谈到树枝,必有树干一样的道理.我们先前对git 的全部操作默认都是在主干上进行的,这个主干也是一种特殊的分支,名为 master 分支. 无论是 ...
- git 入门教程之分支管理
背景 什么是分支?简单地说,分支就是两个相对独立的时间线,正常情况下,独立的时间线永远不会有交集,彼此不知道对方的存在,只有特定情况下,两条时间线才会相遇,因为相遇,所以相知,因为相知,所以改变! 正 ...
- git 入门教程
git 入门教程之协同开发 前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协 ...
- 廖雪峰Git入门教程
廖雪峰Git入门教程 2018-05-24 23:05:11 0 0 0 https://www.liaoxuefeng.com/wiki/00137395163059296 ...
- 创建与合并分支-git入门教程
在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而 ...
- git 入门教程之远程仓库
远程仓库 如果说本地仓库已经足够个人进行版本控制了,那么远程仓库则使多人合作开发成为可能. 如果你只是打算自己使用git,你的工作内容不需要发布给其他人看,那就用不到远程仓库的概念. git 是分布式 ...
- 史上最简单Git入门教程
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 工作原理 / 流程: Workspace:工作区Index / Stage:暂存区Repository:仓库区(或本地仓库)Remo ...
- 解决冲突-git入门教程
人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发: $ git checkout -b feature1 Switched to a new ...
- 深入学习:Windows下Git入门教程(下)
声明:由于本人对于Git的学习还处于摸索阶段,对有些概念的理解或许只是我断章取义,有曲解误导的地方还请见谅指正! 一.分支 1.1分支的概念. 对于的分支的理解,我们可以用模块化这个词来解释:在日常工 ...
随机推荐
- multiprocessing- 基于进程的并行性
介绍 multiprocessing是一个使用类似于threading模块的API支持生成进程的包.该multiprocessing软件包提供本地和远程并发,通过使用子进程而不是线程有效地支持 全局解 ...
- [python]使用virtualenvWrapper
什么是virtualenv virtualenv是python的环境管理工具,用于隔离python的运行环境.也就是说,一个项目可以有一个属于这个项目的运行环境,从而避免了因为依赖不同的模块而产生的错 ...
- .Net Self Hosting 的几种方式
写在前面: IIS是Windows平台非常关键的组件,它是微软自带的Web服务器,可以很方便的帮助我们运行起一个网站,WebApi等服务,提供给外部来访问.即使它被很多java或者ruby的同学各种鄙 ...
- 【转载】uCOS2 关于进程调度的O(1)算法
uCOS2唯一值得学习的一个地方就是关于进程调度的O(1)算法: 最简单也是最愚蠢的方法是维护一个链表List. 这种方法的问题是:当一个Thread就绪时,如果根据其优先级插入List,则算法的时间 ...
- python基本操作
创建列表 sample_list = ['a',1,('a','b')] Python 列表操作 sample_list = ['a','b',0,1,3] 得到列表中的某一个值 value_star ...
- python重试库retryiny源码剖析
上篇博文介绍了常见需要进行请求重试的场景,本篇博文试着剖析有名的python第三方库retrying源码. 在剖析其源码之前,有必要讲一下retrying的用法,方便理解. 安装: pip insta ...
- Jenkins自动化构建配置
写在前头 我每次修改代码一点东西,都要进行一个重新发布.重新发布的流程大概如下: 将最新代码同步上传到git上面 Maven打包 mvn clean install 将最新的jar包上传到服务器上面, ...
- vue_drf之实现极验滑动验证码
一.需求 1,场景 我们在很多登录和注册场景里,为了避免某些恶意攻击程序,我们会添加一些验证码,也就是行为验证,让我们相信现在是一个人在交互,而不是一段爬虫程序.现在市面上用的比较多的,比较流行的是极 ...
- [转]Angular开发(十八)-路由的基本认识
angular router https://angular.io/guide/router 本文转自:https://blog.csdn.net/kuangshp128/article/detail ...
- 【转载】访问IIS中网站出现 403.14 - Forbidden报错信息
将网站发布后部署到IIS后,配置完应用程序池以及相关设置项后,在浏览器中访问设置好的网站,出现403.14 - Forbidden的错误信息,从错误信息的提示来看,应该是IIS服务器此网站目录的内容被 ...