gitflow 流程是非常专业而且标准的 git 处理流程,因为要学习其核心思想和应用,故有此文章系列,本文章系列会分为两部分,第一部分学习基本的内容和基础的流程,第二部分会学习其他流程和 hotfix,release 和 tag 之类的高级用法。
项目中长期存在的两个分支:
在 gitlab 里面可以设置这 2 个分支的权限是受保护的,只允许某些人才能进行操作。
其它分支为短期分支,其完成功能开发之后需要删除:
feature/*
:特性(功能)分支,用于开发新的功能,不同的功能创建不同的功能分支,功能分支开发完成并自测通过之后,需要合并到 develop 分支,之后删除该分支。bugfix/*
:bug 修复分支,用于修复不紧急的 bug,普通 bug 均需要创建 bugfix 分支开发,开发完成自测没问题后合并到 develop 分支后,删除该分支。release/*
:发布分支,用于代码上线准备,该分支从 develop 分支创建,创建之后由测试同学发布到测试环境进行测试,测试过程中发现 bug 需要开发人员在该 release 分支上进行 bug 修复,所有 bug 修复完后,在上线之前,需要合并该 release 分支到 master 分支和 develop 分支。hotfix/*
:紧急 bug 修复分支,该分支只有在紧急情况下使用,从 master 分支创建,用于紧急修复线上 bug,修复完成后,需要合并该分支到 master 分支以便上线,同时需要再合并到 develop 分支。标准的流程如下图:
因为这些图涉及的流程太多,一下子很难接受,所以需要逐个分解来学习。
项目背景:有一群人共同开发一个 blog 系统。
需要角色:
项目人员:
项目分工:
首先学习一个基本的流程,类似下图,但是本次暂时不涉及 tag 处理:
先创建一个服务端代码仓库,用 gitlab 来管理这个仓库,名字叫做 blog-project,仓库地址是git@xxx服务器地址/blog-project.git
。
项目刚开始,分支并不需要那么多,在代码仓库里只需要建两个分支即可:
// 远程服务器上代码master // 默认主分支(受保护)develop // 开发分支(受保护) |
---|
备注:
开发者 clone 这个库下来到本地:
// git 命令git clone git@xxx服务器地址/blog-project.git// clone 后每个人的本地仓库都如下:master // 默认主分支develop // 开发分支 |
---|
备注:
项目正式开始后,我们需要分工开发,有以下两种情况我们会遇到:
feature/articles
功能。feature/login
功能。feature/login
和feature/articles
功能都成为共享分支,所有人都参与开发// 开发者 a 执行 git 命令// 创建feature/articles 功能分支,并直接切换到该分支上进行开发git checkout -b feature/articles// 开发者 b 执行 git 命令// 创建feature/login 功能分支,并直接切换到该分支上进行开发git checkout -b feature/login |
---|
那么现在开发者 a 和 b 本地的代码库如下:
// 开发者 a master // 默认主分支develop // 开发分支feature/articles // 功能分支 articles 模块// 开发者 bmaster // 默认主分支develop // 开发分支feature/login // 功能分支 login 模块 |
---|
备注:
开发完成后各自提交代码到远端代码仓库:
// 开发者 agit add . // 添加当前目录所有文件的改动到本地 git 仓库git commit --m "Add user API" // 需要按照 commit 规范,这个只是样例git push origin feature/articles // // 开发者 bgit add . // 添加当前目录所有文件的改动到本地 git 仓库git commit --m "Add user API" // 需要按照 commit 规范,这个只是样例git push origin feature/login |
---|
备注:
git add
是添加文件到本地 git 仓库缓冲区,换句话来说,是将有改动的文件放在本地的 git 代码仓库中,以便记录版本和提交版本。// 开发者 a 执行命令,切换到相应到分支git fetch // 取回远端所有分支(branch)的更新git checkout feature/articles // a 切换到feature/articles分支git pull origin feature/articles // 拉取远端feature/articles分支的所有更新到本地代码git checkout feature/login // a 切换到feature/login分支git pull origin feature/login // 拉取远端feature/login分支的所有更新到本地代码// 开发者 a 的本地代码master // 默认主分支develop // 开发分支feature/articles // 功能分支 articles 模块feature/login // 功能分支 login 模块 |
---|
// 开发者 b 执行命令,切换到相应到分支git fetch // 取回远端所有分支(branch)的更新git checkout feature/articles // b 切换到feature/articles分支git pull origin feature/articles // 拉取远端feature/articles分支的所有更新到本地代码git checkout feature/login // b 切换到feature/login分支git pull origin feature/login // 拉取远端feature/login分支的所有更新到本地代码// 开发者 b 的本地代码master // 默认主分支develop // 开发分支feature/articles // 功能分支 articles 模块feature/login // 功能分支 login 模块 |
---|
解释:
feature/articles
分支和feature/login
分支都会由开发者 a 或者 b 同时开发,因为是在共享分支开发,所有有可能会有共享冲突的问题, 在代码开发之前, 应先更新好本地代码仓库,可以减少冲突的发生。git merge conflict
)备注:
git pull
相比git fetch
相当于是从远程获取最新版本到本地,但不会自动 merge。如果需要有选择的合并git fetch
是更好的选择。git pull
把过程的细节都隐藏了起来,以至于你不用去了解 git 中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。git pull
,多用git fetch
和merge
。开发者本地进行来基本的测试验证,确认功能满足需求,并且没有大的问题,然后会由开发者 leader 在 gitlab 上进行分支合并:
由开发者 leader c 来进行合并,将feature/articles
和 feature/login
分支合并到 develop 分支,合并完成后删除源分支(feature/articles
和 feature/login
)。
至此使用基本流程完成开发。
发生冲突的地方不止 pull 还有 merge 和 rebase,只要发生合并的地方就可能会有冲突的发生。
以下例子以 git pull
来样例:
// git pull 拉取代码的时候发生冲突了git pull XXXXX// 报错提示Auto-merging test.txtCONFLICT (content): Merge conflict in test.txtAutomatic merge failed; fix conflicts and then commit the result. |
---|
// 冲突文件 test.txt 内容a123<<<<<<< HEADb789=======b45678910>>>>>>> 6853e5ff961e684d3a6c02d4d06183b5ff330dccc |
---|
解释:
<<<<<<<
与=======
之间的内容是我的修改,=======
与>>>>>>>
之间的内容是别人的修改。备注:
git status
命令查看。// 执行 git 命令git status// 输出提示On branch masterYour branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits)// 你可以放弃合并,git merge --abort 选项会尝试恢复到你运行合并前的状态。You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge)Unmerged paths: (use "git add <file>..." to mark resolution)// 冲突的文件 both modified: readme.txtno changes added to commit (use "git add" and/or "git commit -a") |
---|
git diff --base
来查看文件在两边是如何改动的。// 执行 git 命令git diff --base -b // -b 是为了去除空白内容// 输出信息* Unmerged path hello.rb// 结果为git格式的diff。// 进行比较的是,a版本的f1(即变动前)和b版本的f1(即变动后)。diff --git a/hello.rb b/hello.rbindex ac51efd..44d0a25 100755// "---"表示变动前的文件,"+++"表示变动后的文件。--- a/hello.rb+++ b/hello.rb// 前面的"-1,7"分成三个部分:减号表示第一个文件(即f1),"1"表示第1行,"7"表示连续7行。合在一起,就表示下面是第一个文件从第1行开始的连续7行。同样的,"+1,8"表示变动后,成为第二个文件从第1行开始的连续9行@@ -1,7 +1,8 @@// 文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。 #! /usr/bin/env ruby+# prints out a greeting def hello- puts 'hello world'+ puts 'hello mundo' end hello() |
---|
gitpush origin master --force
或gitpush origin master -f
。但是这种方式存在覆盖掉其他人提交的危险,当确定不会影响到其他人提交的情况下可以使用,比如使用gitcommit –amend
修改提交日志等情况。为什么需要 commit 规范?主要是为了看清楚每次 commit 的内容,清楚知道 commit 变动的地方,从而方便排错和控制代码。
npm install -g commitizen
这个是一个格式化 commit message 的工具。npm install -g conventional-changelog-cli
这个是生成 changelog 的工具,changelog 是为了将这些格式化的 commit message 生成一个 CHANGELOG.md
文件的,这个文件可以规范看到提交的内容(如上图一个标准且优美的 git 提交记录图)。// 执行git 命令git cz // 输出 cz-cli@2.10.1, cz-conventional-changelog@2.1.0Line 1 will be cropped at 100 characters. All other lines will be wrapped after 100 characters.// 提示输入你的 commit类型,他会弹出提示给你选择? Select the type of change that you're committing: fix: A bug fix// 提示输入你的 scope类型,没有可以跳过? What is the scope of this change (e.g. component or file name)? (press enter to skip) test// 提示输入你的 subject,即标题? Write a short, imperative tense description of the change: 我来测试这个 commit 格式// 提示输入你的 body 内容,就是详细信息? Provide a longer description of the change: (press enter to skip) 详细? Are there any breaking changes? No// 当你有使用 issues 的时候就会关联到 issues? Does this change affect any open issues? No[master a4fd22c] fix(test): 我来测试这个 commit 格式 3 files changed, 14 insertions(+), 1 deletion(-) |
---|
提交记录会变成这样(使用 git log
命令可以查看):
// 输出结果是fix(test): 我来测试这个 commit 格式详细 |
---|
至于 CHANGELOG.md
内容则如下:
<a name="1.0.0"></a># 1.0.0 (2017-03-05)### Bug Fixes* fixed ([a9c3110](https://192.168.2.107/zpu/hello-koa/commits/a9c3110))### Features* add something ([53becaa](https://192.168.2.107/zpu/hello-koa/commits/53becaa)) |
---|
解析 md 文件之后,会很清晰的知道每个版本或者提交都负责了那些内容,类似这样:
本文参考到的资料地址: