shushu2013.github.io icon indicating copy to clipboard operation
shushu2013.github.io copied to clipboard

Git 工作流规范

Open shushu2013 opened this issue 7 years ago • 0 comments

Git 工作流规范

Git 学习资料

在阅读该开发规范前需熟悉 Git 的使用,推荐如下链接:

1、Pro Git 简体中文版 (很好的学习 Git 的书)
2、git-recipes (GitHub 上开源的手册,图文并茂)

三篇关于 Git 工作流的参考文章:

1、Git 工作流程
2、常见工作流比较 (这个是上面 git-recipes 中的文章)
3、简介我的 Git Work Flow

规范不是金科玉律,实际情况可能更加复杂,大家可以根据实际情况调整规范

1、分支规范

1.1 master 分支(主分支):存储官方发布历史
1.2 develop 分支(开发分支):用来整合各功能分支

image

1.3 feature 分支(特性/功能分支):每个新功能都放置在自己的分支中,可以在备份/协作时推送到中央仓库

feature 分支develop 分支 作为父分支,当一个功能完成时,它将被合并回 develop 分支。(功能永远不应该直接在 master 分支 上交互 )

image

1.4 release 分支(发布分支):一旦 develop 分支 的新功能足够发布(或者预先确定的发布日期即将到来),从 develop 分支 fork 的 一个分支。

release 分支 的创建开始了下个发布周期,只有和发布相关的任务应该在这个分支进行,如修复 bug、生成文档等。

一旦准备好发布,发布分支将合并进 master 分支,并打上版本号的标签。另外,它也应该合并回 develop 分支

发布分支命名规范:release-* or release/*

image

1.5 bugfix 分支:修复在 release 分支 上发现的 bug(类似 hotfix 分支

标准的 GitFlow 是没有该分支的,因为可以直接在 release 分支 上提交 commit 来修复 bug
为了修复 bug 的方便,我加了这个分支规范,可以根据自己的开发规范来决定是否需要

image

1.6 hotfix 分支(维护/补丁分支):用来快速给产品的发布打上补丁

这是唯一可以从 master 分支 上 fork 的分支,一旦修复完成了,它应该被并入 masterdevelop 分支,master 分支 应该打上更新的版本号的标签。

有一个专门的 bug 修复开发线使得你的团队能够处理 issues,而不打断其他工作流或是要等到下一个发布周期。你可以将维护分支看作在 master 分支 上工作的临时发布分支。

image

2、流程规范

创建本地仓库

创建本地仓库后,一般还需要进行一些设置,来与远程仓库进行交互

有两种方式:本地新建仓库 或者 克隆远程仓库

方法一 : 本地新建仓库

1、新建并初始化本地仓库

// 创建项目目录,如 Development-spec
$ mkdir Development-spec

// 进入项目目录 
$ cd Development-spec

// 初始化目录,把目录变成 Git 可以管理的仓库
// 这时当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的
$ git init

git init 命令默认创建了本地 master 分支,所以几乎每一个仓库都有 master 分支

注意:
master 分支 类似于新建的孤儿分支,没有任何提交信息
使用 git branch -v 查看分支时,显示不出来
一旦有提交历史,就成为真正的分支,可以查看到

创建孤儿分支命令:git checkout --orphan <branch>
孤儿分支意思为该分支中没有任何内容,与之前创建的其他分支没有任何关联

之后所有 git 命令 都是在本地仓库目录 Development-spec 下执行

2、关联远程仓库

git remote add <name> <url>

name: 作为远程仓库的别名(一般命名为 origin)
url: 远程仓库地址,支持 HTTPS 和 SSH 协议

HTTPS 是允许匿名、只读访问仓库的简易方式

如果希望对仓库进行读写,你需要使用 SSH 协议,而且需要在托管的服务器上有一个有效的 SSH 账户
$ git remote add origin [email protected]:shushu2013/Development-specification.git

一些操作远程仓库的命令

$ git remote                // 列出本地仓库和其他远程仓库的连接
$ git remote -v             // 与 git remote 相同,但同时显示每个连接的 URL
$ git remote show <name>    // 查看远程仓库信息,name: 为远程仓库的别名

$ git remote rm <name>      // 移除名为 name 的远程仓库的连接
$ git remote rename <old-name> <new-name>   // 将远程仓库别名从 old-name 重命名为 new-name

3、从远程仓库抓取数据

$ git fetch

此命令会从所有远程仓库中拉取本地仓库中没有的数据
你就可以在本地访问所有远程仓库中的所有分支,分支以远程仓库名开头
例如:远程仓库 origin 中的 master 分支,fetch 后在本地对应的分支名字是 origin/master
你可以将其中某个分支合并到本地,或者切换到这个分支,看看有些什么有趣的更新

git fetch 详细命令

$ git fetch <remote>

此命令会到远程仓库 remote 中拉取所有你本地仓库中还没有的数据
运行完成后,你就可以在本地访问该远程仓库中的所有分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟

$ git fetch <remote> <branch>

和上一个命令相同,但是指定了远程仓库的分支名

4、跟踪远程分支

跟踪远程分支:将本地分支和某个远程分支进行关联

关联后,该本地分支也称为 跟踪分支(tracking branch)
在该分支中输入 git push,Git会自行推断应该向哪个服务器的哪个分支推送数据
同样,在该分支里运行 git pull 会获取远程分支索引,并把它的数据都合并到本地分支中来

设定跟踪分支相关命令

1、当分支不存在,或者是新建的孤儿分支,且没有任何提交历史,可使用如下命令,否则会报错

$ git checkout -b <branch> <remote-branch>

branch: 本地分支
remote-branch: 远程分支

该命令会创建 branch 分支,设置 branch 分支跟踪远程分支 remote-branch,并切换到 branch 分支

$ git checkout --track/-t <remote-branch>

--track/-t : -t 是 --track 命令的简写
remote-branch : 本地 fetch 下来的远程分支

该命令是 git checkout -b <branch> <remote-branch> 的简化版本,默认创建的本地分支为 remote-branch 的 branch
如:创建本地的 master 分支设定为跟踪远程仓库 origin 的 master 分支,并切换到 master 分支
$ git checkout -t origin/master

2、当分支存在,并且已有提交历史,可使用如下命令

$ git branch --set-upstream-to=<remote-branch>  <branch>

该命令设置本地 branch 分支跟踪远程分支 remote-branch

注意:设置后,因为分支已经有提交历史,可能需要运行 git pull 或 git merger 命令来合并远程仓库的数据
在 2.9.0 之后,会报错:fatal: refusing to merge unrelated histories (拒绝合并历史无关的分支)
需要添加 --allow-unrelated-histories 选项
$ git merge <remote-branch> <branch> --allow-unrelated-histories
这样会产生一个新的合并提交历史
方法二:克隆远程仓库
$ git clone <url>               // 下载一个项目和它的整个代码历史
$ git clone <url> <directory>   // 指定下载目录

// 会在当前目录下创建一个 Development-specification 目录,包含了对远程仓库的克隆
$ git clone https://github.com/shushu2013/Development-specification.git

克隆远程仓库的好处:
1、本地仓库默认关联了远程仓库,远程仓库别名为 origin
2、远程仓库的所有分支都下载到了本地,可通过 git branch -r 查看
2、默认创建了 master 分支 并设置为 origin/master 远程分支的跟踪分支

创建 develop 分支
// 以 master 分支创建一个互补的 develop 分支
$ git branch develop master

// 把 develop 分支推送到服务器上
$ git push -u <remote> develop

develop 分支 将会包含项目中所有的历史,而 master 分支 将包含不完全的版本
其他开发者应该将中央仓库克隆到本地,创建一个分支来追踪 develop 分支

$ git clone [email protected]:shushu2013/Development-specification.git
$ git checkout -b develop origin/develop
创建 feature 分支

feature 分支 都应该基于 develop 分支,而不是 master 分支

$ git checkout -b <some-feature> develop

开发者使用 [ 编辑、缓存、提交 ] 的一般约定来向功能分支 feature 分支 添加提交:

$ git status    // 查看当前文件状态

$ git add <file>    // 跟踪新文件、暂存已修改文件
$ git add .         // . 表示所有文件

$ git commit -m "<commit-message>"  // 提交更新

在添加了一些提交之后,开发者确信开发的功能已经准备好了
如果团队使用 Pull Request,现在正是发起 Pull Request 的好时候,请求将 feature 分支 并入 develop 分支
否则,可以向下面一样,将它并入本地的 develop 分支,然后推送到中央仓库:

// 一般在远程仓库的 develop 分支会有频繁提交,需在本地更新,并解决合并冲突
$ git pull <remote> develop      // 更新本地的 develop 分支数据
$ git checkout <some-feature>   // 切换到 some-feature 分支
$ git rebase develop            // 把整个 some-feature 分支移动到 develop 分支的后面

在合并之前,在 some-feature 分支使用 rebase 命令:
它会把整个 some-feature 分支移动到 develop 分支的后面,有效地把所有 develop 分支上新的提交并入过来
但是,rebase 为原分支上每一个提交创建一个新的提交,重写了项目历史,并且不会带来合并提交
参考:5.1-代码合并:Merge、Rebase-的选择

$ git checkout develop              // 切换到 develop 分支
$ git merge --no-ff <some-feature>  // 将功能分支数据合并到 develop 分支,--no-ff : 表示不使用默认的快速合并
$ git push                          // 推送 develop 分支数据到远程仓库的 develop 分支

---

$ git branch -d <some-feature> // 删除功能分支    
创建 release 分支

当功能开发完成或者开发周期结束,准备项目的官方发布时,新建一个 release 分支 来封装发布的准备工作
这也正是发布的版本号创建的一步:

// 从 develop 分支 fork 一个 release 分支
$ git checkout -b <release-version> develop

// 把 release 分支推送到服务器上,当正式发布到 master 分支后,可以删除本地和服务器上的 release 分支
$ git push -u <remote> <release-version>

这个 release 分支 用来整理提交,充分测试,更新文档,为即将到来的发布做各种准备
它就像是一个专门用来完善发布的功能分支,期间添加的 commit 基本都是 bug fix
开发结束后同时合并进 develop 分支master 分支,并在 master 分支 打上发布 tag 最后可以删除本地和服务器上的 release 分支

创建 bugfix 分支

release 分支 的 bug 修复
可以直接提交 commit 修复 bug,或者在本地开一个 bugfix 分支(类似 hotfix 分支),修复好后合并进 release 分支,然后删除 bugfix 分支

$ git pull <remote> <release-version>               // 从远程仓库更新 release-version 分支数据                  
$ git checkout -b <bugfix-issue> <release-version>  // fork 一个 bugfix-issue 分支,进行 bug 修复

--- bug 修复后

// 以下三步在远程仓库的 release-version 分支有频繁提交的情况下才需要
$ git pull <remote> <release-version>    // 更新 release-version 分支
$ git checkout <bugfix-issue>            // 切换到 bugfix-issue 分支
$ git rebase <release-version>           // 把整个 bugfix-issue 分支移动到 release-version 分支的后面

$ git checkout <release-version>    // 切换到 release-version 分支
$ git merge --no-ff <bugfix-issue>  // 把 bugfix-issue 分支的数据合并进 release-version 分支
$ git push                          // 推送 release-version 分支到远程仓库

$ git branch -d <bugfix-issue>      // 删除 bugfix-issue 分支

最后 release 分支 合并进 master 分支develop 分支

$ git pull <remote> <release-version>   // 更新 release-version 分支
$ git checkout master                   // 切换到 master 分支
$ git merge --no-ff <release-version>   // 将 release-version 分支合并进 master 分支
$ git tag <tag-version>                 // 打上对应的版本标签

$ git push                          // 推送到远程仓库,默认不会把标签推送上去
$ git push <remote> <tag-version>   // 把 tag-version 标签推送到远程仓库

-----
$ git pull <remote> develop         // 更新 develop 分支
$ git checkout <release-version>    // 切换到 release-version 分支
$ git rebase develop                // 把整个 release-version 分支移动到 develop 分支的后面

$ git checkout develop                  // 切换到 develop 分支
$ git merge --no-ff <release-version>   // 合并进 develop 分支,保证将来的版本也会包含 release-version 上的 bug 修复
$ git push                              // 推送到远程仓库

---- 正式发布完 master 分支

$ git branch -d <release-version>       // 删除本地 release-version 分支
$ git push <remote> :<release-version>  // 删除远程 release-version 分支

标签相关额外命令介绍,更多参考 [ Git 基础 - 打标签 ]

// 列出所有标签
$ git tag

// 打上含附注的标签
$ git tag -a <tag-version> -m <tag-message>

-m :选项则指定了对应的标签说明,Git会将此说明一同保存在标签对象中
    如果没有给出该选项,Git会启动文本编辑软件供你输入标签说明

// 一次推送所有本地新增的标签上去
$ git push origin --tags

创建 hotfix 分支

hotfix 分支 创建时间在项目正式发布之后

发布后,用户发现了 bug,这时从 master 分支 fork 一个 hotfix 分支,修复完成后,合并回 master 分支develop 分支,最后删除这个 hotfix 分支

// 从 master 分支 fork 一个 hotfix-issue 分支,并切换到 hotfix-issue 分支
$ git checkout -b <hotfix-issue> <master>

--- 修复 bug

// 开发者使用 [ 编辑、缓存、提交 ] 的一般约定来向修复 hotfix-issue 分支 添加提交:
$ git checkout <hotfix-issue>   // 切换到 hotfix-issue 分支
$ git status                    // 查看当前文件状态

$ git add <file>    // 跟踪新文件、暂存已修改文件
                    // 或者使用 git add . 命令,其中 . 表示所有文件

$ git commit -m "<commit-message>"  // 提交更新

--- 修复完成,合并回 master 分支 和 develop 分支

$ git checkout master
$ git merge --no-ff <hotfix-issue>
$ git tag <tag-version>             // 打上标签
$ git push
$ git push <remote> <tag-version>

$ git checkout develop
$ git pull
$ git merge --no-ff <hotfix-issue>
$ git push

--- 删除 hotfix-issue 分支

$ git branch -d <hotfix-issue>

shushu2013 avatar Dec 27 '17 10:12 shushu2013