经过本文你能够了解到:
- git 的起源
- git 的根底知识
- gitflow 流程的根本方法
- 依据 git 的多种作业流
在讲 Git Flow 之前,咱们先讲讲其他东西
-
什么是版别?
版是指印刷时的版,本便是印刷出来的书本;版别是一种称谓,用于描绘同一事物的相互之间有差异的各种形式、状况或内容。
换言之,任何事物只要有差异化都会触及到版别这个概念,可是,咱们这儿说的版别,包含后边聊到的东西,都应该是一些有意义的版别,举个例子,小明 1 月 1 日 至 1 月 31 日 每天都在改一份策划书,2 月 1 号小明的甲方说仍是上一个版别好,此刻对于小明来说,上一个版别是什么?也许是最近一次小明发给甲方的一个计划,也许是上一个甲方说还能够的计划,但小明可能现已不记得具体是几号改完给甲方的计划了。 -
常见的版别操控有哪些?
copy 文件以命名区分的方法、本编辑器的撤回/行进功用、运用专业工具如 svn、git 等等都归于版别操控的领域,不同的版别操控有不同的用途,比方文本编辑器的撤回,能够轻松撤销本次修改,比方 copy 文件,能够让新旧文件一起存在,便利对比,但这些方法过分简略了,而且中心进程都是一些暂时性的东西,不足以作为一个修改前史参考或许完好版别来看待,为此,还需求一些专业工具,如 集中式版别办理体系 SVN、CVS,分布式版别办理体系 BitKeeper、Git 等。 -
Git 开发背景
同生活中的许多伟大事物相同,Git 诞生于一个极富纷争大举创新的时代。 Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护作业都花在了提交补丁和保存归档的繁琐业务上(1991-2002年间)。 到 2002 年,整个项目组开端启用一个专有的分布式版别操控体系 BitKeeper 来办理和维护代码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的协作联系结束,他们收回了 Linux 内核社区免费运用 BitKeeper 的权利。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)依据运用 BitKeeper 时的经验教训,开发出自己的版别体系。 他们对新的体系制订了若干方针:- 速度
- 简略的规划
- 对非线性开发形式的强力支持(答应不计其数个并行开发的分支)
- 完全分布式
- 有能力高效办理相似 Linux 内核相同的超大规模项目(速度和数据量) 自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的一起,依然保留着初期设定的方针。 它的速度飞快,极端合适办理大项目,有着令人难以置信的非线性分支办理体系(拜见 Git 分支)。
-
1991 年 Linux 开发了 linux 体系这个开源项目,采用邮件发送源文件顺便patch的方法进行写作开发,由 Linux 自己进行手工兼并;
-
2002 年 BitKeeper 与 Linux 社区达成协议,答应 Linux 社区免费试用 BitKeeper,因为免费试用,协议内容更多地是维护 BitKeeper 本身。
-
2005 年 BitKeeper 不满 Linux 社区损坏协议内容(说白了便是反编译 BitKeeper,试图做破解版或其他),停止协作;
-
同 2005 年,Linux 花费了 2 周时刻,开发了 Git 第一版,一个月内运用 Git 来办理 Linux 代码;
Git 根底知识
作业区(Workspace)、暂存区(Index)、版别库(Repository)
# 创立并进入 testGitFlow 目录
# 此刻 testGitFlow 便是咱们的作业区(Workspace),也便是作业目录
$ mkdir testGitFlow && cd testGitFlow
# 初始化 git 库房
# 此刻目录中添加了 .git 目录,.git 目录便是 git 库房,不归于作业区
$ git init
# 新增两个文件
$ echo 111 > a.txt
$ echo 222 > b.txt
# 添加两个文件到暂存区/索引(Index)
$ git add .
# 把索引中的两个文件添加到版别库(Repository)
$ git commit -m 'init'
以上触及的几个概念:
Workspace: 简略理解便是咱们的项目目录
Index: 简略理解便是存储即将提交的内容的区域
Repository: 版别库房
Commit、Tree、Blob 目标
# 经过 git log 检查版别
$ git log
>
commit 2b304a56998989dbcfd77f370f4b43fcad9e5872 (HEAD -> master)
Author: huihuipan <huihuipan163@163.com>
Date: Mon Feb 27 17:56:53 2023 +0800
init
# 经过 git cat-file 检查 commit 信息
# 检查 commit 类型
$ git cat-file -t 2b304a
> commit
# 检查 commit 内容
$ git cat-file -p 10d717
>
tree 4caaa1a9ae0b274fba9e3675f9ef071616e5b209
author huihuipan <huihuipan163@163.com> 1677491813 +0800
committer huihuipan <huihuipan163@163.com> 1677491813 +0800
init
# 能够发现有 tree, author, committer 等信息
# 继续检查 tree 内容
$ git cat-file -t 4caaa1
> tree
$ git cat-file -p 4caaa1
>
100644 blob 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c a.txt
100644 blob c200906efd24ec5e783bee7f23b5d7c941b0c12c b.txt
# 能够发现有 blob 信息
# 继续检查 blob 内容
$ git cat-file -t 58c9bd
> blob
$ git cat-file -p 58c9bd
> 111
# 能够看到里面存储的是 a.txt 的内容
以上触及的几个概念:
commit: commit 记载提交的版别
tree: tree 记载不同版别下的目录结构和文件名
blob: blob 记载文件内容
此刻咱们的 git 项目结构如下
修改文件及提交 commit 的时产生了什么?
- 首先,a.txt 内容 从 111 修改为 333,此刻 git 库房没有变化,仅仅作业区和索引的内容对不上了;
- 履行 git add 指令
- git 库房依据新的 a.txt 内容(333)创立出一个新的 blob 结点,记载 a.txt 内容
- 索引从旧 blob 的指向新的 blob
- 履行 git commit 指令
- 依据索引的状况,生成 tree 目标
- 依据新生成的 tree 目标和 上一个 commit 目标,生成新的 commit 目标
- 把分支指针从旧的 commit 目标移动到新的 commit 目标
HEAD、Branch、Tag
Branch: 是指向 Commit 的指针,每一次提交新的commit,当前的 Branch 都会指向最新的 commit;
HEAD: 指向 Branch 的指针,当checkout 到非 branch 时,会提示处于分离头指针状况,能够做一些试验性的动作;
Tag: 指向 Commit 的指针,用作标签,一般用作记载固定版别,也能够理解为是指定 commit 的别名;
以上咱们能够得知,git 的版别办理粒度去到了文件等级,blob 之间的对比即可得到 diff,这儿也引申出了一个开发上的一个思考,当咱们的程序规划的根底是一个比较小粒度的时候,后续开发和扩展就会愈加灵敏,事实上git 对commit 的操作也是十分灵敏,灵敏到稍不留意就有可能变成事端。
Checkout、Merge、Rebase、Fetch、Pull
checkout 检出: 把 HEAD 检出到指定 branch 或 commit,或许检出指定版别指定文件的内容,因为在 git 里面checkout 承载了太多的功用,一切切换分支有专属指令 switch
。
merge 兼并:
rebase 变基:
rebase 会修改版别前史,即使 rebase 前与 rebase 后的内容共同,但版别不再是同一个版别
fetch: 从另一个存储库下载目标和引用,如远程库
pull: git pull = fetch + merge
依据 Git 的几种作业流
Git Flow
简介
出自 Vincent Driessen 在 2010年写的一篇文章
《A successful Git branching model》
首要分支
有两个分支会贯穿整个版别的生命周期,也便是长时间分支:
- master 分支:用于发布
- develop 分支:用于开发 master 分支和 develop 分支的联系如上,虚线部分指着两个分支并不是直接产生相关,而是经过 release/hotfix 分支产生相关
支撑分支
- feature branches: 用于需求开发
开发需求时从 develop 分支拉出 feature 分支,feature 分支开发结束后(开发自测无问题)则兼并回 develop 分支,兼并后删去分支,后续呈现 bug 则在 develop 分支修改。
- release branches: 用于发布
当 develop 分支处于一个相对安稳的状况时即可从 develop 分支拉出 release 分支准备发布,release 分支不进行功用开发,仅进行 bug 修正,直至无问题时兼并到 master 分支进行发布,一起兼并回 develop 分支后删去 release 分支。
- hotfix branches: 用于修正生产问题
hotfix 分支用于修正生产环境上急需修正的 bug, 当生产环境呈现 bug 时,从 master 分支拉出 hotfix 分支,修正后兼并回 master 分支进行发布,一起兼并到 develop 分支后删去。
最终回忆一下完好的 gitflow
补充
在 2020年 Vincent Driessen 补充了一条反思笔记,大概说 Git Flow这种形式在继续交给的软件下显得杂乱,能够考虑运用 Github Flow 而不是将 Git Flow 硬塞到项目中。
继 Git Flow 之后 Adam Ruka 针对 Git Flow 的技术细节做了优化,提出了 One Flow
Github Flow
相对于 Git Flow,Github Flow 只有一条主干分支,经过 github 平台加持添加 PR 流程: 进行某功用开发时,从 master 分支拉出 feature 分支,完成功用后提交 pr, 让相关人员进行 review, review 期间仍能够对 feature 进行提交,直至承认无问题后经过 pr, 能够把 feature 分支兼并到 master 分支进行发布
GitLab Flow
GitLab Flow 运用 master 分支作为开发分支,依据 master 分支另起发布分支 production
GitLab Flow 添加以下分支定义:
环境分支:当你需求在不同环境发布不同的版别时运用
发布分支:当项目需求发布不同的版别时运用,声明晰一个发布分支后,这个分支只会兼并严峻的缝隙修正更新。
继续发布
gitlab-flow 引荐运用 master 分支进行开发,依据 master 分支另建 production 分支进行发布,另外提出了 环境分支的概念,依据不同环境,逐层兼并,最终汇总到 production 发布分支后进行发布
版别发布
假如你的项目需求发布不同的版别, gitlab-flow 版别发布形式可能更合适,在继续发布形式下,不同的版别会有不同的发布分支进行发布。
Aone Flow
Aone-flow 是以 master 分支为根底,除 master 分支外其他都是暂时分支。依据 master 分支拉出环境分支,环境分支之间不进行任何相关,独立发展,环境分支也不答应直接修改,而是经过兼并不同的 feature 分支进行组合。 feature 分支直至兼并到 发布分支后才会删去。有点是操作粒度更高更可控,缺点是环境分支的内容即使是相同的,但版别前史却有可能不共同。
怎样挑选版别操控
上面介绍了好几种 flow, 从 gitflow 开端,gitflow 让自由度超高的 git 得到了指导性的运用方法;
而 github-flow 又针对了 gitflow 的杂乱性提出了极简版的 flow;
gitlab-flow 又针对 gitflow 和 github-flow 过于杂乱或过于简略的方法,提出了自己折中的计划,一起还给出了两种交给方法(继续交给、版别交给)的计划;
最终也介绍了 AoneFlow,一种操作粒度更自由的计划。
其实没有一种万能计划,不同的团队/项目有着其特殊的状况,针对不同状况,flow 也在变化,合适的便是最好的。
最终
To conclude, always remember that panaceas don’t exist. Consider your own context. Don’t be hating. Decide for yourself.
引用 Vincent Driessen 的一句话:“最终,永久记住万能药不存在。考虑你自己的背景。不要厌烦。自己决定”
参考
- Git 简史
- git 的诞生 — 廖雪峰
- git的宿世,和BitKeeper
- A successful Git branching model
- OneFlow – a Git branching model and workflow
- GitHub Flow
- GitLab Flow
- Aone Flow
- Git 作业流程 – 阮一峰
- 分支的实质 – 智客工坊
- 深化理解 git 兼并操作
- git merge 的原理(递归三路兼并算法)
- 关于Git rebase你必须要知道的几件事 – DevUI团队
- Commit message 和 Change log 编写攻略 – 阮一峰
- Git 兼并战略选项及示例
- Git 工具 – 高级兼并
- Git 可视化在线操练
- Git内部原理揭秘 – 李泽帆