版本管理之gitlab实践教程:进阶篇(1)

2019年12月06日 阅读数:46
这篇文章主要向大家介绍版本管理之gitlab实践教程:进阶篇(1),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

实践gitflow

结合git flow,使用gitlab做为远端仓库管理,在实际的项目中是一种可行的方式,并且这种方式对与复杂大型的项目有较好的适应方式。css

git flow

git flow源于Vincent Driessen在2010年提出的一个分支模型:
这里写图片描述java

主要特色

两个长期分支

git flow中有两个长期的分支,一直不会被删除,这两个分支是develop和master。git

分支 生命期 做用说明
master 长期 用于保持和生产环境一致或者半步先于生产环境,主要目的用于保证生产环境的实时可用状态
develop 长期 开发的集成分支,主要目的用于显示最新的开发情况

实践原则1:

master 分支时常保持着软件能够正常运行的状态,通常不容许开发者直接对master 分支的代码进行修改和提交。结合gitlab的具体方式,能够将改分支设定为protect方式。github

实践原则2:

master分支专人管理,结合gitlab的权限管理,设定团队负责发布的人具备owner或者master的权限,其他人禁止直接对此分支进行操做。web

master分支的使用场景

master分支主要在如下场景中会用到:sql

生产环境bug再现与调查

当代码规模和团队规模到了必定程度以后,若是缺少有效的管理,加之多团队的开发,还没有发布的功能,临时对应的bug,甚至还会有一些手动修改暂时未纳入版本管理的文件,这些混杂在一块儿会变得很是的复杂。因此在问题发生时,想清楚的知道bug发生的生产化境所对应的源码基线都是一件困难的事情,此分支与上线功能息息相关,必须严格管理。api

新的功能发布

特性分支开发完毕,完成测试,确认此分支内容能够进行发布以后,即可与master分支合并,发布时通常会附加版本编号。安全

紧急bug修正发布

紧急bug修正以后,须要当即体如今master分支上,否则下次发布依然会有不少问题ruby

实践原则3

建议在项目中添加自动化测试环节,使用gitlab的webhook设定,在merge时根据项目须要自动运行自动化测试验收,若是不经过及时报警,此自动化测试即便是不多的覆盖率,也能防范大部分人为因素致使的问题,好比不当心将一个编译都没有经过的版本推到了master上,即便专人负责,可是专人并不必定对全部的技术和项目功能以及实时状态都有全面的掌控,另外全部的问题都须要人去检查和确认,一张会无限增加的checklist今后产生,最终会造成一个几千行甚至更多的一个虽都不会去看的敷衍了事的检查环节,此环节在不少项目实践中已经获得证明:只在过后反省的时候有用,反省以后这张checklist会变得更长。app

develop分支的使用场景

特性开发合并

根据项目的模块进行拆分,不一样的模块不一样的团队负责,或者根据特性进行开发,不一样的特性不一样的团队负责,这些分支开发完毕时须要合并到develop分支上,以保证develop分支具备最新的功能。

紧急bug修正发布

紧急bug修正以后,须要当即体如今master分支上,可是同时须要在develop分支上进行反应,为什么不直接在develop分支上进行管理,有不少因素须要考虑,好比新的功能虽然开发完毕了,可是因为其余制约的因素,发布的时期还没有肯定,不能将这些已经完成开发和测试的内容发布到master分支上,简单来讲此模型的出发点在于master分支用于和生产环境直接关联,之因此多一条分支就是为了管理各类复杂的难以掌控的项目实际需求的。紧急bug修正以后,master和develop分支都须要进行更新,前者保证下次发布不会将此紧急修正的内容覆盖,后者保证经过下次经过测试的内容合并到master上时不会覆盖此内容或者尽量的减小merge操做。

实践原则4

develop分支是开发过程当中代码中心分支,与master 分支同样,这个分支也是很是重要的分支,这个分支的合并操做可能每一个人都会参与,若是作专人管理的话,基本上全部的开发者都须要参与。因此,合并以前须要创建基础的原则,好比java的项目最好作到以下内容才合并到本分支
本地编译经过
本地本次修改内容没有新的sonarqube高级别的defect对应
本地单体测试经过
手工或者自动化验收的测试经过

实践原则5

develop分支进行传统的每日构建甚至实时构建,结合不断完善的自动化测试,以能够接受的成本和代价保证开发的流水线不会断开。

实践原则6

设立时限原则:develop分支一旦发生构建或者关联的自动化测试出现问题,结合工具第一时间定位到对应的负责人进行回滚或者紧急修正,根据项目集成状况进行设立时限,好比平均每日由各个临时分支提交的功能为4次,则可设立时限最长不超过2小时,若是超过2小时没法对应,则意味着下次会有人在这个错误的版本上进行再一次的提交,错上加错是最须要避免的,发现问题在第一时间解决,超过期限,当即止损回滚。

三种临时分支

相比于长期存在的分支,git flow的模型中还有三种临时性的分支

分支类型 说明 是否可为多条
Feature分支 特性分支 可为多条
Hotfix分支 bug对应分支 可为多条
Release分支 release实施分支 可为多条

特性分支

特性分支有时也被称为Topic分支,通常是用来开发新的特性,而其关联的发布可能近在眼前,也有可能须要很长一段时间,特性分支最终会被合并到develop分支或者最终会被丢弃。
丢弃特性分支开发的内容在敏捷开发中并不罕见,尤为是当项目须要不断地试验的阶段。

根据DevOps的调查显示,Trunc-based开发方式是主流推进的开发方式,可是因为项目的复杂性和实际推行时候各类制约因素的存在,
多条分支长时间的并行仍是很难避免的,特性分支开发的时候在git flow模型中通常遵循以下步骤:

步骤 内容 git 命令
Step 1 以develop分支为基础建立特性分支 git checkout -b 特性分支名称 develop
Step 2 进行特性内容开发直至能够提交
Step 3 特性分支开发完成后切换至develop分支 git checkout develop
Step 4 合并特性分支开发内容到develop分支 git merge –no-ff 特性分支名称
Step 5 删除特性分支 git branch -d 特性分支名称
Step 6 push修改内容到远端仓库保存 git push origin develop

特性分支的使用注意事项以下:

注意事项 详细说明
源分支 特性分支须要以develop分支为源分支
目标分支 特性分支的合并目标分支为develop分支,此模型中只能合并回develop分支
分支命名 除去master/develop/hotfix-/release-命名的全部分支

实践原则6

特性分支合并或者其余的分支合并,尽量不使用fast forward的方式,以方便回滚和状态确认。

实践原则7

特性分支在git flow中仍然是临时性分支,使用以后请删除此分支,同时删除远程仓库上的该分支。另外,分支的增多觉得着可能的沟通/合并/冲突等的增长,而这些正是精益开发中
所要规避的“waste”,不用即删,由于在实践中咱们已经利用了git的非fast forward的方式,因此特性分支开发的信息已经完整地在develop分支保存,删除不会引发问题追踪上的问题。

Release分支

Release分支基于develop分支为基础进行建立,主要用于版本的发布,主要用于保证最后一步的安全和顺畅,为发布所须要的各类准备以及手工操做,甚至小规模的bug对应均可以在此分支上完成。而当Release分支上的一切作完以后,标志着最新develop分支的功能已经发布到了master,同时为下一次发布的功能特性的接收已经开始。

实践原则8

特性分支或者其余分支合并到develop开发主分支的策略须要项目根据状况自行建立,最主要的原则之一在于尽可能避免因为发布时期的不一样致使频繁的分支合并/版本挑选等手工做业的发生。
好比发布计划明明是最后,可是在项目已开始的时候就合并进了主分支,这样会致使后续每次发布的时候都须要将此内容挑选出去,虽然使用gitlab的rebase+cherry pick等功能能够实现这种要求,
可是单纯在提交的规范上进行要求则能够避免这种无用的浪费的发生。

实践原则9

Release分支主要目的是用于大型项目中各个特性分支开发完毕以后,定义了一个准备就绪到工做完成的中间阶段,通常会和项目的管理工做结合进行,好比进行发布的申请和批准,结果确认和审核,
因为不一样的开发流程不只须要考虑到技术自己,还要考虑到各个公司实际的流程规范/audit等等,以保证release可以正常进行。虽然能够在此分支上进行小量的修改,可是大规模的功能修改请尽量地规避。

Release分支在使用时候通常遵循以下步骤:

步骤 内容 git 命令
Step 1 以develop分支为基础建立release分支 git checkout -b release-版本号 develop
Step 2 作Release准备或者小的bug对应,而后进行提交 git commit -a -m “release相关信息”
Step 3 切换至master分支 git checkout master
Step 4 合并Release分支内容到master分支 git merge –no-ff release-版本号
Step 5 设定tag git tag -a 版本号 -m “release的tag信息”
Step 6 切换至develop分支 git checkout develop
Step 7 合并Release分支内容到develop分支 git merge –no-ff release-版本号
Step 8 删除release分支 git branch -d release-版本号
Step 9 推送develop分支到远程仓库 git push origin develop
Step 10 切换至master分支并推送master分支到远程仓库 git checkout master; git push origin master
Step 11 推送tag信息到远程分支 git push origin 版本号

Release分支的使用注意事项以下:

注意事项 详细说明
源分支 release分支须要以develop分支为源分支
目标分支 特性分支的合并目标分支为develop分支和master,在此分支上的诸如小的bug修正必须同时反映到develop分支和master分支,否则就会给下次发布留下隐患
分支命名 release-*

实践原则10

为了不提交或者tag信息被恶意修改,能够在使用签名技术实现这一保障。签名使得操做具备了不可抵赖性和没法篡改性两种保证。而在git中只是须要加入-u或者-s选项便可简单实现。

hotfix分支

hotfix分支与release分支很是相像,都牵扯到向生产环境ready的master进行版本的更新。可是不一样的是hotfix每每是由于生产环境上出现了很是紧急的问题对应,须要当即对应,而项目的特性开发等又不想受到影响而中断,这时就能够依据master生成一个新的hotfix的分支,在此分支上进行bug的对应,既不影响develop主开发分支,又能保证到生产环境紧急问题的及时对应,而对应完毕以后同时向develop主开发分支进行同步跟新便可。

实践原则11

诸如hotfix和release上的对应须要向git flow的两条主线同时进行更新,若是一旦忘记其中一条,势必会引发没必要要的后续问题,在流程规范或者工具的自动化里面创建增长对此操做执行的确认。

Hotfix分支在使用时候通常遵循以下步骤:

步骤 内容 git 命令
Step 1 以master分支为基础建立hotfix分支 git checkout -b hotfix-版本号 master
Step 2 进行bug对应,而后进行提交 git commit -a -m “hotfix相关信息”
Step 3 切换至master分支 git checkout master
Step 4 合并hotfix分支内容到master分支 git merge –no-ff hotfix-版本号
Step 5 设定tag git tag -a 版本号 -m “hotfix的tag信息”
Step 6 切换至develop分支 git checkout develop
Step 7 合并hotfix分支内容到develop分支 git merge –no-ff hotfix-版本号
Step 8 删除hotfix分支 git branch -d hotfix-版本号
Step 9 推送develop分支到远程仓库 git push origin develop
Step 10 切换至master分支并推送master分支到远程仓库 git checkout master; git push origin master
Step 11 推送tag信息到远程分支 git push origin 版本号

hotfix分支的使用注意事项以下:

注意事项 详细说明
源分支 hotfix分支须要以master分支为源分支
目标分支 特性分支的合并目标分支为develop分支和master,修正必须同时反映到develop分支和master分支,否则就会给下次发布留下隐患
分支命名 hotfix-*

实际使用

接下来咱们使用gitlab10.4.2以及git1.8.3.1来模拟一下git flow开发的流程。

建立一个项目

首先咱们使用gitlab的restapi建立一个项目,固然也能够直接在gitlab上进行图形界面操做,具体命令以下,请根据本身的gitlab的URL和token进行修改, 另外jq命令若是没有能够不使用,对结果不产生影响,仅仅对结果的显示格式进行整形而已

执行命令

curl –request POST –header “PRIVATE-TOKEN: sqiSUhn3tHYXe8nSGRDi” –data “name=gitflowmodel” “http://127.0.0.1:32001/api/v4/projects” |jq .

执行log

[root@devops ~]# curl --request POST --header "PRIVATE-TOKEN: sqiSUhn3tHYXe8nSGRDi" --data "name=gitflowmodel" "http://127.0.0.1:32001/api/v4/projects" |jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1907  100  1890  100    17   1711     15  0:00:01  0:00:01 --:--:--  1711
{
  "id": 2,
  "description": null,
  "name": "gitflowmodel",
  "name_with_namespace": "Administrator / gitflowmodel",
  "path": "gitflowmodel",
  "path_with_namespace": "root/gitflowmodel",
  "created_at": "2018-02-04T14:11:10.055Z",
  "default_branch": null,
  "tag_list": [],
  "ssh_url_to_repo": "git@3ff5a6afdc80:root/gitflowmodel.git",
  "http_url_to_repo": "http://3ff5a6afdc80/root/gitflowmodel.git",
  "web_url": "http://3ff5a6afdc80/root/gitflowmodel",
  "avatar_url": null,
  "star_count": 0,
  "forks_count": 0,
  "last_activity_at": "2018-02-04T14:11:10.055Z",
  "_links": {
    "self": "http://3ff5a6afdc80/api/v4/projects/2",
    "issues": "http://3ff5a6afdc80/api/v4/projects/2/issues",
    "merge_requests": "http://3ff5a6afdc80/api/v4/projects/2/merge_requests",
    "repo_branches": "http://3ff5a6afdc80/api/v4/projects/2/repository/branches",
    "labels": "http://3ff5a6afdc80/api/v4/projects/2/labels",
    "events": "http://3ff5a6afdc80/api/v4/projects/2/events",
    "members": "http://3ff5a6afdc80/api/v4/projects/2/members"
  },
  "archived": false,
  "visibility": "private",
  "owner": {
    "id": 1,
    "name": "Administrator",
    "username": "root",
    "state": "active",
    "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
    "web_url": "http://3ff5a6afdc80/root"
  },
  "resolve_outdated_diff_discussions": false,
  "container_registry_enabled": true,
  "issues_enabled": true,
  "merge_requests_enabled": true,
  "wiki_enabled": true,
  "jobs_enabled": true,
  "snippets_enabled": true,
  "shared_runners_enabled": true,
  "lfs_enabled": true,
  "creator_id": 1,
  "namespace": {
    "id": 1,
    "name": "root",
    "path": "root",
    "kind": "user",
    "full_path": "root",
    "parent_id": null
  },
  "import_status": "none",
  "import_error": null,
  "open_issues_count": 0,
  "runners_token": "iCwH41nomRPp-nwF4xoP",
  "public_jobs": true,
  "ci_config_path": null,
  "shared_with_groups": [],
  "only_allow_merge_if_pipeline_succeeds": false,
  "request_access_enabled": false,
  "only_allow_merge_if_all_discussions_are_resolved": false,
  "printing_merge_request_link_enabled": true
}
[root@devops ~]# 

这样咱们就建立了一个名为gitflowmodel的gitlab项目了。

初期化项目

初期化master分支

git clone远程仓库内容,进行结果确认

[root@devops ~]# git clone http://192.168.163.154:32001/root/gitflowmodel.git
Cloning into 'gitflowmodel'...
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
warning: You appear to have cloned an empty repository.
[root@devops ~]# cd gitflowmodel/
[root@devops gitflowmodel]# git branch
[root@devops gitflowmodel]# git remote -v
origin  http://192.168.163.154:32001/root/gitflowmodel.git (fetch)
origin  http://192.168.163.154:32001/root/gitflowmodel.git (push)
[root@devops gitflowmodel]# 

对项目进行初期化,建立master分支,在master分支上添加一个文件C1,并将此文件推送到远端仓库。

[root@devops gitflowmodel]# touch C1
[root@devops gitflowmodel]# git add C1; git commit -m"add C1"
[master (root-commit) 858d807] add C1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C1
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 3, done.
Writing objects: 100% (3/3), 199 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new branch]      master -> master
[root@devops gitflowmodel]# 

初期化develop分支

在目前master的状态下建立develop分支,添加一个文件C2,并将此文件推送到远端仓库。

[root@devops gitflowmodel]# git checkout -b develop master
Switched to a new branch 'develop'
[root@devops gitflowmodel]# ls
C1
[root@devops gitflowmodel]# touch C2; git add C2; git commit -m "add C2";
[develop e9aff8a] add C2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C2
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 225 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new branch]      develop -> develop
[root@devops gitflowmodel]#

这样两条长期分支master和develop已经就绪,接下来咱们开始模拟实际上的分支开发/bug对应/release等临时分支操做。

特性分支使用过程

步骤 内容 git 命令
Step 1 以develop分支为基础建立特性分支 git checkout -b 特性分支名称 develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git checkout -b feature_F1001 develop
Switched to a new branch 'feature_F1001'
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 2 进行特性内容开发直至能够提交
[root@devops gitflowmodel]# touch C3; git add C3; git commit -m "add C3";
[feature_F1001 fa40dce] add C3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C3
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 3 特性分支开发完成后切换至develop分支 git checkout develop
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# ls
C1  C2
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 4 合并特性分支开发内容到develop分支 git merge –no-ff 特性分支名称
[root@devops gitflowmodel]# git merge --no-ff feature_F1001
Merge made by the 'recursive' strategy.
 C3 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C3
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 5 删除特性分支 git branch -d 特性分支名称
[root@devops gitflowmodel]# git branch
* develop
  feature_F1001
  master
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch -d feature_F1001
Deleted branch feature_F1001 (was fa40dce).
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 6 push修改内容到远端仓库保存 git push origin develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# ls
C1  C2  C3
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 331 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
   e9aff8a..eb06c4a  develop -> develop
[root@devops gitflowmodel]#

此时git仓库的状态

[root@devops gitflowmodel]# git log --graph --pretty=oneline
*   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
|\  
| * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
|/  
* e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[root@devops gitflowmodel]#

Release分支的使用过程

步骤 内容 git 命令
Step 1 以develop分支为基础建立release分支 git checkout -b release-版本号 develop
root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# ls
C1  C2  C3
[root@devops gitflowmodel]# git checkout -b release-0.1 develop
Switched to a new branch 'release-0.1'
[root@devops gitflowmodel]#
步骤 内容 git 命令
Step 2 作Release准备或者小的bug对应,而后进行提交 git commit -a -m “release相关信息”
[root@devops gitflowmodel]# touch C4; git add C4; git commit -m "add C4";
[release-0.1 fcca679] add C4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C4
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 3 切换至master分支 git checkout master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
[root@devops gitflowmodel]#
步骤 内容 git 命令
Step 4 合并Release分支内容到master分支 git merge –no-ff release-版本号
[root@devops gitflowmodel]# git merge --no-ff release-0.1
Merge made by the 'recursive' strategy.
 C2 | 0
 C3 | 0
 C4 | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C2
 create mode 100644 C3
 create mode 100644 C4
[root@devops gitflowmodel]# ls
C1  C2  C3  C4
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 5 设定tag git tag -a 版本号 -m “release的tag信息”
[root@devops gitflowmodel]# git tag -a 0.1
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 6 切换至develop分支 git checkout develop
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 7 合并Release分支内容到develop分支 git merge –no-ff release-版本号
[root@devops gitflowmodel]# git merge --no-ff release-0.1
Merge made by the 'recursive' strategy.
 C4 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C4
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 8 删除release分支 git branch -d release-版本号
[root@devops gitflowmodel]# git branch -d release-0.1
Deleted branch release-0.1 (was fcca679).
[root@devops gitflowmodel]#
步骤 内容 git 命令
Step 9 推送develop分支到远程仓库 git push origin develop
[root@devops gitflowmodel]# git branch
* develop
  master
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 339 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
   eb06c4a..ff52200  develop -> develop
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 10 切换至master分支并推送master分支到远程仓库 git checkout master; git push origin master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
fatal: Authentication failed for 'http://192.168.163.154:32001/root/gitflowmodel.git/'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 223 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
   858d807..1ad3d55  master -> master
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 11 推送tag信息到远程分支 git push origin 版本号
[root@devops gitflowmodel]# git push origin 0.1
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 152 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new tag]         0.1 -> 0.1
[root@devops gitflowmodel]#

确认分支状态

[root@devops gitflowmodel]# git log --graph --pretty=oneline
*   1ad3d55b2b35220d30f00be7da0c82d385aeb48d Merge branch 'release-0.1'
|\  
| * fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
| *   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
| |\  
| | * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
| |/  
| * e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
|/  
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
  develop
* master
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# git log --graph --pretty=oneline
*   ff52200742dc3515c85d41e206b4b7c5208881c2 Merge branch 'release-0.1' into develop
|\  
| * fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
|/  
*   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
|\  
| * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
|/  
* e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[root@devops gitflowmodel]# 

hotfix分支的使用过程

步骤 内容 git 命令
Step 1 以master分支为基础建立hotfix分支 git checkout -b hotfix-版本号 master
[root@devops gitflowmodel]# git checkout -b hotfix-0.1.1 master
Switched to a new branch 'hotfix-0.1.1'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
  develop
* hotfix-0.1.1
  master
[root@devops gitflowmodel]#
步骤 内容 git 命令
Step 2 进行bug对应,而后进行提交 git commit -a -m “hotfix相关信息”
[root@devops gitflowmodel]# touch C5; git add C5; git commit -m "add C5";
[hotfix-0.1.1 7190442] add C5
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 3 切换至master分支 git checkout master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 4 合并hotfix分支内容到master分支 git merge –no-ff hotfix-版本号
[root@devops gitflowmodel]# git merge --no-ff hotfix-0.1.1
Merge made by the 'recursive' strategy.
 C5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 5 设定tag git tag -a 版本号 -m “hotfix的tag信息”
[root@devops gitflowmodel]# git tag -a 0.1.1 -m "hotfix for 0.1.1"
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 6 切换至develop分支 git checkout develop
root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git branch
* develop
  hotfix-0.1.1
  master
[root@devops gitflowmodel]#
步骤 内容 git 命令
Step 7 合并hotfix分支内容到develop分支 git merge –no-ff hotfix-版本号
[root@devops gitflowmodel]# git merge --no-ff hotfix-0.1.1
Merge made by the 'recursive' strategy.
 C5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 8 删除hotfix分支 git branch -d hotfix-版本号
[root@devops gitflowmodel]# git branch -d hotfix-0.1.1
Deleted branch hotfix-0.1.1 (was 7190442).
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 9 推送develop分支到远程仓库 git push origin develop
[root@devops gitflowmodel]# git push origin develop
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 382 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: 
remote: To create a merge request for develop, visit:
remote:   http://3ff5a6afdc80/root/gitflowmodel/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote: 
To http://192.168.163.154:32001/root/gitflowmodel.git
   ff52200..e4b3be8  develop -> develop
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 10 切换至master分支并推送master分支到远程仓库 git checkout master; git push origin master
[root@devops gitflowmodel]# git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
[root@devops gitflowmodel]# git push origin master
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 223 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
   1ad3d55..b843ef1  master -> master
[root@devops gitflowmodel]# 
步骤 内容 git 命令
Step 11 推送tag信息到远程分支 git push origin 版本号
[root@devops gitflowmodel]# git tag
0.1
0.1.1
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git push origin 0.1.1
Username for 'http://192.168.163.154:32001': root
Password for 'http://root@192.168.163.154:32001': 
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://192.168.163.154:32001/root/gitflowmodel.git
 * [new tag]         0.1.1 -> 0.1.1
[root@devops gitflowmodel]#

确认分支状态

[root@devops gitflowmodel]# git branch
  develop
* master
[root@devops gitflowmodel]# git log --graph --pretty=oneline
*   b843ef1d58bca6afdf8d3ecd9b363e4725c6ce24 Merge branch 'hotfix-0.1.1'
|\  
| * 7190442a53e054bc0a4715f135f5f3fae347e839 add C5
|/  
*   1ad3d55b2b35220d30f00be7da0c82d385aeb48d Merge branch 'release-0.1'
|\  
| * fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
| *   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
| |\  
| | * fa40dce00a8878824641c281bd91e10749e8cc86 add C3
| |/  
| * e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
|/  
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[root@devops gitflowmodel]# 
[root@devops gitflowmodel]# git checkout develop
Switched to branch 'develop'
[root@devops gitflowmodel]# git log --graph --pretty=oneline
*   e4b3be8a572f3d3efcbaf94c12211dd622b66779 Merge branch 'hotfix-0.1.1' into develop
|\  
| * 7190442a53e054bc0a4715f135f5f3fae347e839 add C5
| *   1ad3d55b2b35220d30f00be7da0c82d385aeb48d Merge branch 'release-0.1'
| |\  
* | \   ff52200742dc3515c85d41e206b4b7c5208881c2 Merge branch 'release-0.1' into develop
|\ \ \  
| | |/  
| |/|   
| * | fcca679ee89ad9e2ed90e7b319ba78d10cd22dac add C4
|/ /  
* |   eb06c4ad2a9bd1f70d1ec3135f7b8bdc8703f41f Merge branch 'feature_F1001' into develop
|\ \  
| * | fa40dce00a8878824641c281bd91e10749e8cc86 add C3
|/ /  
* | e9aff8adf4b6344c5d7f59155134ef2e579f1e32 add C2
|/  
* 858d8070c8176c42e35f453a3394e4ff1bdc7e94 add C1
[root@devops gitflowmodel]#

其余工具

除了git的基础命令,还有其余的一些工具能够辅助进行git flow的使用使之更加简单,有命令行的操做也有图形化的工具,因为git命令自己已经较为简单,就再也不对其余的方式进行进一步的介绍了。

模型的扩展或者变种

除了git flow以外还有github flow以及gitlab flow,咱们会在后续的文章中进一步的展开,相较于git flow,后面两种模型更为简单,推行起来更加方便,
可是大型复杂项目下的对应,尤为是从传统方式过分的项目,在朝着trunk-based的构成前进的途中,中间状态的对应使用git flow仍是有很明显的效果的。

git flow的主要思路是两条长期存在的主分支,一条对应主开发分支,一条对应主生产分支,根据项目的复杂程度能够进行调节已达到适合当前项目的结构,甚至使用的不是git这种版本管理工具,
这种思路的延伸和扩展仍是值得讨论的,好比在实际的更为复杂的项目中,使用传统的RCS这种古老的分支管理技术,使用过3条长期存在的主分支在一个超大型的项目中稳定地的管理了整个软件的生命周期。
master:用于保存和生产环境如出一辙的分支
premaster:用于保存经过内部部署流程及奖发布到生产环境的分支
develop:开发分支的主分支

能够看出,这种方式下使用premaster分支做为两条主分支之间的过渡分支,一旦出现各类意外状况,能够保证不管任什么时候候都能知道生产环境的最新情况而没必要经过一些版本工具的额外操做来实现,
一旦生产环境软硬件出现问题,能够以最快速度进行重构,以保证服务的可用性。

其实对照git flow进行思考会发现,其实这是git flow的一种变种,若是将release分支长期化,从临时性的分支变成一条长期存在的分支,即为此实践的方式。因此git flow的精华之处在于此版本管理模型的抽出,其实远在git产生以前,实际类型的实践已经在不少大型的项目中有过实践只是没有上升到共用的版本模型的高度而已。

参考文章

http://nvie.com/posts/a-successful-git-branching-model/