【Git教程】(十七)发行版交付 — 概述及使用要求,执行过程及其实现,替代解决方案 ~

Git教程 · 发行版交付

  • 1️⃣ 概述
  • 2️⃣ 使用要求
  • 3️⃣ 执行过程及其实现
      • 3.1 预备阶段:创建 stable 分支
      • 3.2 预备并创建发行版
      • 3.3 创建补丁
  • 4️⃣ 替代解决方案

在这里插入图片描述

对于每个项目或产品来说,发布版本的创建都需要一定的时间,其具体过程因各公司或组织的情况而异。
Git 无法用来指定项目进入发布阶段的时间。但我们可以利用标签和分支这两个强大的Git 工具来为发布进度设置一个很宽泛的时间区间。

在本章的工作流中,我们将以一个典型的 Web 项目为例,为你介绍版本发布的过程。在 我们的这个 Web 项目中,始终会存在一个面向产品发布的发行版和一个未来要发布的版本。 产品发行版中出现的主要bug 和安全隐患往往能很快得到解决(以补丁的形式)。而后面这个 新版本在正式发布之前,往往要经过一个持续多天的详尽测试期(我们称之为“代码冻结阶段”)。与此同时,下一个版本的开发也会继续进行。

本章的工作流主要演示是如何用Git 来实施项目的发布阶段,它包含以下内容。

  • 产品发行版支持打补丁的功能。
  • 在代码冻结阶段并行开发新版本的可能性。
  • 确保在开发阶段能以补丁的形式修复所有错误,或者测试阶段的工作能回流到开发阶段。
  • 发行版的历史以及补丁的历史记录要能很容易地被访问。
  • 发行版与开发版之间的比对工作也要很容易进行。

1️⃣ 概述

在下图中,我们将会看到开发阶段和发布阶段各自所需要的分支。

在这里插入图片描述

如你所见,开发部分被放在了master 分支上。无论有没有设置feature 分支 ,master 分支都是决定将哪一些代码纳入发行版的唯一主角。
在预备发布阶段,我们会将启用一个独立的 codefreeze 分支,以便稳定住将要发布的版本。与此同时, master 分支上下一版本的开发工作将继续进行。

一旦稳定阶段的工作完成,我们就可以在 stable 分支上创建一个发行版提交,并同时生成一个相应的发行版标签。
如果产品发行版中出现了某个致命性的错误,我们就得为其新建一个热点修复分支。待排错工作完成之后,我们会在stable分支上创建一个相应的提交修复和发行版标签。

请注意, codefreeze 分支和 hotfix 分支只存在于项目的稳定阶段与排错阶段。另外,项目在稳定阶段和修复阶段所发生的修改始终会通过合并的方式返回到 master 分支上。


2️⃣ 使用要求

  • 产品发行版只有一个:项目的产品发行版只能有一个。也就是说同一个项目或产品不会同时维护多个版本。虽然 Git 有处理多个版本的能力,但根据本章工作流的设计, 我们只能处理一个产品发行版。
  • 开发的稳定性:开发分支需要经过良好的测试,并且在代码冻结阶段所可能出现的错误必须是可控的,以至于我们可以在短期内完成相关的工作。
  • 发行版的完整性:我们在开发分支上新增的内容以及所做的修改要始终被纳入到下一发行版中。

3️⃣ 执行过程及其实现

该工作流会为项目创建一个发行版。然后用一个独立分支来放置该发行版在预备阶段的内容。而修复相关的当作可以在产品发行版上完成。

3.1 预备阶段:创建 stable 分支

在接下来的这部分内容中,我们将要介绍如何在版本库独立的预备阶段中进行一次产品发布。
在这部分工作流中,我们需要有一个名为 stable 的分支,该分支中将只包含新发行版或 补丁所需要的提交。stable 分支上的第一父级提交历史可以直接用来充当发行版的历史,我们可以用log 命令来显示它们。

> git checkout stable
> git log --first-parent -oneline590lec9	Hotfix-Release-2.0.1
b955c9c	Release-2.0.0
5d0173d	Release-1.0.0
3a05e26	init

在上述命令中,我们用到了以下参数。

  • --first-parent: 只考虑第一父级提交。
  • -oneline: 令每条日志输出只打印一行。
    在这里,我们的重点是要正确地定义的 stable 分支的起点。如果 stable 分支被建在了 首次发布的提交上,那么 master 分支上之前的提交也必然会被纳入其第一父级提交的历史 (见下图)。

stable 分支更好的起点应该是在 master 分支的首次提交上。这样一来,发行版的历史记录中就只有一个不必要的提交了(见下图中的首次提交)。

在这里插入图片描述

  • 第1步:确定首次提交的位置
    不幸的是 ,Git 中没有命令可用于找出某一分支上的首次提交。所以我们最好的办法是查看日志中的最后一项。

    > git log -oneline --first-parent | tail -1
    3a05e26 init
    

    在上述命令中,我们用到了以下参数。

    • -oneline: 令输出内容只以单行形式打印。
    • --first-parent: 令其只返回各提交的第一父级提交,这可以加快其执行速度。
    • | tail -1: 只打印日志输出中的最后一行。
  • 第2步:创建 stable 分支
    在找到首次提交的位置之后,我们就可以创建stable 分支了。这里需要用到branch 命令,并且也可以额外指定分支的名称。

    > git branch stable 3a05e26
    

3.2 预备并创建发行版

在接下来这部分内容中,我们来介绍用Git 发布项目的步骤。
由于项目的开发过程被放在了 master 分支中,所以一些必要的单元测试和整合测试也要在这个分支上执行。

当开发工作完成,该项目也准备好被发布时,我们通常都会有越来越密集的测试要执行。 这就是我们所谓的“代码冻结”阶段。 一旦进入了这个阶段,项目代码中就只有会对发行版造成影响的 bug 修复及可能的回避措施才会被执行。这个阶段的持续时间很大程度上取决于项目的开发过程,我们可以从现有代码的质量和测试情况推导出大致的范围,结果可能是几小时,也可能是几个星期。

在代码冻结阶段,我们对于下一发行版的开发工作并不会停止,因为我们将要发表的内容会被稳定在一个独立的 codefreeze 分支中。该分支只存在到新的发行版稳定为止。待下一次要发布新的发行版时,我们又会再重新创建一个新的 codefreeze 分支。

  • 第1步:创建 codefreeze 分支
    codefreeze 分支是基于当前的 master 分支来创建的。我们可以用 checkout 命令来创建这个新分支并激活它。

    > git checkout -b codefreeze master
    
  • 第2步:稳定 codefreeze 分支
    在 codefreeze 分支中,只有那些会影响发行版的错误才会被纠正。这部分的修复动作将遵循最小变更原则。如果我们没有简单的解决方案实现最小化的错误修改,在必要时我们也可以考虑实现某种规避错误的措施。
    另外, codefreeze 分支上新增的提交必须要定期合并到 master 分支。这些一次性的修复措施也会从当前的开发工作中被清除出去。

    > git checkout master
    > git merge codefreeze
    

    相关的规避措施应该也会被纳入到 codefreeze 分支中,因为这些内容将在 master 分支中被保留。这些规避措施可以在 master 分支中是可以被恢复的(例如通过revert 命令), 并由此创建出一个更好的实现(见下图)。

    在这里插入图片描述

  • 第3步:创建发行版
    待 codefreeze 分支上的测试成功完成之后,我们就可以创建发行版了。
    同样地,来自 codefreeze 分支的合并操作也必须要基于stable 分支来进行。这对于 stable 分支中那些尚未在 codefreeze 分支中被测试过的提交来说非常重要。这些提交会导致我们的合并操作在尚未经过完全测试的 stable 分支上创建出一个主要发行版。
    下面,我们就用 log 命令来检查一下 stable 分支中是否存在 codefreeze 分支中缺失的提交。如果它没有任何输出,就说明 stable 分支上没有新增的提交。

    > git log codefreeze..stable --oneline
    

    如果 log 命令返回了某种输出,我们就要stable 分支与 codefreeze 分支进行重新合并,并针对发行版再次对其进行必要的测试。
    如果日志输出为空, codefreeze分支上的合并提交就可以在stable分支被执行了。

    通常,Git 会对这次合并采用快进式合并,因为我们已经确保了stable 分支上没有新的提交。但为了获取 stable 分支一份有意义的第一父级提交历史,我们还是应该对其使用--no-ff选项。另外,我们也应该使用注释明确标识一下这个发行版的新提交。

    > git checkout stable
    > git merge codefreeze --no-ff -m "Release-2.0.0"
    

    这里的--no-ff 选项主要用于指示 merge 命令不地执行快进式合并。也就是说,该命令始终要新建一个提交对象。
    除了提交之外,我们还需要为发行版创建一个新的标签。该标签主要用于快速访问该发 行版提交,例如我们将其配合 diff命令一起使用。

    > git tag -a release-2.0.0 -m "Release-2.0.0"
    

    最后,我们要将 codefreeze 分支删除,因为该分支只存在于项目的稳定阶段。待下一轮发布时我们又会重建它。

    > git branch -d codefreeze
    
  • 第4步:更新 master 分支
    既然发行版已被发布,我们也就确保了发行版中所有的修改也都被纳入到了 master 分支中。
    尽管 codefreeze分支中所有的bug 修复提交都已经被合并到了master 分支提交中,但新 发行版的提交仍然还存在(见下图)。虽然该发行版提交不会改变任何文件,因此与 master 分支并无关系,但当我们查询“属于stable分支,但不属于master分支的提交”时它还是会不时冒出来。因此,我们需要将 stable分支合并到master分支中。

    在这里插入图片描述

    > git checkout master
    > git merge stable -m "Nach Release-2.0.0"
    

    到目前为止,从版本管理的角度来看,新发行版已经完全被创建了。


3.3 创建补丁

补丁所处理的是一种带有紧迫性的修改,它应该尽可能地快速,且独立于其他修改。补 丁通常都是直接实现在当前发行的版本中的。像 Web应用程序中那些不太重要的错误通常会 等到下一版本发布时再纠正。但如果有一个错误会得系统无法正常工作,或者会导致安全风险,那它就必须立即得到纠正。

  • 第1步:创建 hotfix 分支并进行排错
    这样的纠错任务通常需要在一个独立的 hotfix 分支中进行。为了能并行启用多个补丁,我们可以让每个人都设置一个属于自己的 hotfix 分支。
    它的起点应该是 stable 分支,指向的是最后一个产品发行版。

    > git checkout -b hotfix-al stable
    

    现在,我们可以对项目做一些必要的修改了。

  • 第2步:验证补丁被并行化创建的可能性
    如果我们已经完成了错误纠正和新发行版的创建,接下来就必须要检查以下提交历史, 看看在此期间是否还有另一个补丁在运行。为此,我们就需要用log 命令来查看该历史记录中是否还存在属于stable 分支,但不属于hotfix 分支的提交。

    > git log hotfix-al..stable --oneline
    

    如果 stable 分支在补丁被安置之前的这段时间里发生了其他修改,我们就必须要检查一 下这些修改是否也将以补丁的形式工作。这样的话,我们的历史记录将会保持线性发展,这些补丁应该通过变基操作被放置在stable 分支的最新提交中(见下图)。

    在这里插入图片描述

    > git rebase stable
    

    这样一来,该补丁提交就被建在了stable 分支的最后一次提交之上。

  • 第3步:发布补丁
    现在来正式发布这个补丁,为此我们需要对 hotfix 分支和stable 分支来一次合并操作。 自然,我们会再次不允许快进式合并,因为我们要创建一个新的提交。而且该合并提交的注释中也应该注明必要的发行版信息。

    > git checkout stable
    > git merge hotfix-al --no-ff -m "Hotfix-Release-2.0.1"
    

    除了提交之外,我们还需要为发行版创建一个新的标签。

    > git tag -a release-2.0.1 -m "Hotfix-Release 2.0.1"
    

    最后,我们可以将hotfix分支删除。

  • 第4步:在其他分支上接受补丁所做的修改
    当然,我们在hotfix 分支中所修复的错误还必须被传送给其他活动分支。
    在代码冻结阶段,补丁只能将其所做的修改传递给 codefreeze 分支。之后,codefreeze 分支会将这部分修改再传递给 master分支(见下图)。

    在这里插入图片描述

    > git checkout codefreeze
    > git merge stable -m "Hotfix 2.0.1"
    > git checkout master
    > git merge codefreeze -m "Hotfix 2.0.1"
    

    而在非代码冻结阶段,补丁中的修改可以直接被传递给 master 分支(见下图)。

    在这里插入图片描述

    > git checkout master
    > git merge stable -m "Hotfix 2.0.1"
    

4️⃣ 替代解决方案

  • 只用标签
    在本章工作流中,我们所描述的是stable 分支与标识版本的附加标签之间的搭配使用。 那么,如果只用标签行不行呢?
    对于那些纯标记性的,并可据此重现的发行版来说,当然使用丰富的标签是足以应对实际需要了。

    但如果我们要谈及对于版本发布历史及补丁发布历史的理解的话,单独依靠标签就不切 实际了。这样的话,我们只能根据标记名称来猜测时间顺序快乐。而通过 stable 分支,我们 就可以用第一父级提交历史来做这件事。

  • 不用标签
    标签实际上就是我们为提交设置的符号名称。如果我们想比较以下当前开发版本与某一特定发行版之间的区别(使用diff命令), 标签确实是比提交的散列值要更实用一些。

    > git diff release-1.0.0
    

    如果消除掉了这些标签,我们就必须要先在 stable 分支找到相应的提交,然后再指定它的散列值了。

    > git diff 5d0173d
    
  • 用快进式合并
    在Git 中,分支中能引用的只有一些提交。如果某一分支被激活(通过 checkout 命令), 那么该分支所引用的各个新提交都会被自动更新。提交在创建它的这个分支上并不会留下历史信息。因此分支上的第一父级提交历史是它唯一可选的、“启发式”的历史形式。

    对两个分支进行快进式合并的结果会指向同一个提交对象。如果我们想使用的是第一父级提交历史,这种做法就无法对这两个分支中的其中一个父级提交的创建动作进行跟踪了。
    如果我们不允许执行快进式合并,那么合并操作就始终会去创建新的提交。这样一来,它的第一父级提交就是当前分支下的最后一次提交,而第二父级提交则是之前已添加的那次提交。

  • 直接在 stable 分支上实现补丁
    本章工作流所介绍的是如何纠正一个严重的错误,它应该建立一个独立的 hotfix 分支。
    从原则上来说,直接在 stable分支上做这件事也是可以的。

    但在某些情况下,有些与发行版无关的提交也会出现在 stable 分支的第一父级提交的历史中。当这种情况发生时,要创建的补丁往往就不止一个了。
    而且,这样做会使我们很难并行化地创建补丁。



温习回顾上一篇(点击跳转)
《【Git教程】(十六)基于构建服务器的工作 — 概述及使用要求,执行过程及其实现,替代解决方案 ~》

继续阅读下一篇(点击跳转)
《》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ Qt QMainWindow实现无边框窗口自定义标题栏可拖拽移动拉伸改变窗口大小

本篇博客介绍C Qt QMainWindow实现无边框窗口,适用于win10/win11系统。 QMainWindow相对于QWidget多了dockedwidget功能,跟多人可能更喜欢用QMainWindow做主窗口,如果不需要dockedwidget功能,QMainWindow与QWidget做主窗口基本无…

MATLAB实现蚁群算法栅格路径优化

蚁群算法是一种模拟自然界中蚂蚁觅食行为的优化算法,常用于解决路径规划问题。在栅格路径优化中,蚁群算法可以帮助找到从起点到终点的最优路径。以下是蚁群算法栅格路径优化的基本流程步骤: 初始化参数: (1)设置蚂蚁数量&#xff…

linux的“>”和“>>”

在Linux中,>和>>都是用于文件重定向的操作符,它们用于将命令的输出发送到文件中。 > 用于创建一个新文件或覆盖现有文件的内容。当你执行一个如 command > file.txt 的命令时,如果 file.txt 文件存在,它的内容将被…

2024最新版JavaScript逆向爬虫教程-------基础篇之深入JavaScript运行原理以及内存管理

目录 一、JavaScript运行原理1.1 前端需要掌握的三大技术1.2 为什么要学习JavaScript1.3 浏览器的工作原理1.4 浏览器的内核1.5 浏览器渲染过程1.6 认识JavaScript引擎1.7 V8引擎以及JavaScript的执行过程1.8 V8引擎执行过程 二、JavaScript的执行过程2.1 初始化全局对象2.2 执…

【3】Head First Java 学习笔记

HeadFirst Java 本人有C语言基础,通过阅读Java廖雪峰网站,简单速成了java,但对其中一些入门概念有所疏漏,阅读本书以弥补。 第一章 Java入门 第二章 面向对象 第三章 变量 变量的类型 primitive 主数据引用 变量 primitive主…

OriginPro作图之箱线图

前言 箱线图(Box-plot) 又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。因型状如箱子而得名。 本文将结合实例阐述其意义和绘图过程。 箱线图简介 箱线图(Boxplot) 也称箱须图( Box-whisker Plot),是利用数据中的五个统计量…

ffmpeg的安装以及使用

1.FFmpeg 的主要功能和特性: 格式转换:FFmpeg 可以将一个媒体文件从一种格式转换为另一种格式,支持几乎所有常见的音频和视频格式,包括 MP4、AVI、MKV、MOV、FLV、MP3、AAC 等。视频处理:FFmpeg 可以进行视频编码、解…

ArcGIS无法开始编辑TIN!开始编辑TIN显示灰色

ArcGIS无法开始编辑TIN!开始编辑TIN显示灰色? 解决方案! 1、确认自定义——扩展模块中空间分析、3D分析模块勾选。 2、确认以上后,还是不能编辑的话,我们可以调出 3D分析分析工具条,你就会发现。TIN编辑工…

Window + Ubuntu 双系统无Ubuntu Bios 启动项

文章目录 安装硬盘位置不重要!!!(但是我安装在了第二张HDD)问题是多盘分位置会导致磁盘主分区变成了简单卷 Bios Ubuntu 启动项修复参考Ubuntu安装U盘进入Try Ubuntu 使用Terminal修复完提示Disable Secure Boot进入Te…

【存储】cosbench对象存储测试工具

目录 简略说明 原理 用法 详细说明 简介 用法 一 安装 二 简单验证 三 编写配置文件 四 提交配置文件下IO 五 测试结果查看 结果概览 查看详情 每秒钟的io情况查看 工作负载配置 参数配置(controller和driver) 查看错误的方法和错误记录 查看错误的方法 …

【匹配】匈牙利匹配算法

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 匈牙利匹配算法 1. 正文 1.1 基础概念 二分图 顶点分为两个集合,集合间顶点相连,集合内点不相连 匹配 一个匹配就是一个边的…

彻底解决SimpleDateFormat的线程不安全问题

重现SimpleDateFormat类的线程安全问题 在Java中,SimpleDateFormat是一个非常常用的类,它用于将日期转换成需要的格式或者将文本日期转换为Date对象。然而,在多线程环境下使用SimpleDateFormat可能会遇到一些意想不到的问题。下面通过一个例…

CentOS7配置NFS文件共享

环境准备 准备3个linux服务器: 192.168.137.120(nfs server端) 192.168.137.121 192.168.137.122 安装nfs-utils工具 # 在3个节点上都执行 yum install nfs-utils -y服务端配置 # 在120上执行 systemctl enable nfs-server systemctl sta…

Oracle Linux 8.8 一键安装 Oracle 11GR2 RAC(231017)

前言 Oracle 一键安装脚本,演示 Oracle Linux 8.8 一键安装 Oracle 11GR2 RAC(231017)过程(全程无需人工干预):(脚本包括 ORALCE PSU/OJVM 等补丁自动安装) ⭐️ 脚本下载地址&…

Scala OOP

前序 1、Scala 为纯粹OOP1.1、不支持基本类型:一切皆为对象 Byte,Int,... 1.2、不支持静态关键字:static1.3、支持类型推断,和类型预定,动静结合 类 /*关键字:class创建对象:new内含:成员变量…

linux下查看网络路由信息,找到请求过多的IP

netstat -nat|awk {print} |awk -F : {print$1} |sort|uniq -c |sort -n 命令netstat -nat|awk {print} |awk -F : {print$1} |sort|uniq -c |sort -n是用于分析网络连接状态的管道命令序列。下面逐个解释每个命令及其作用: netstat -nat: netstat 是一个用于显示…

代理IP干货:如何正确使用防范风险?

在今天的数字时代,代理IP地址已成为互联网世界中不可或缺的一部分。无论您是寻求绕过地理限制、保护个人隐私还是执行网络任务,代理IP地址都发挥着关键作用。我们将为您探讨代理IP地址的重要性以及如何防范潜在的风险和威胁。 一、代理IP地址的潜在风险 …

STM32H7独立看门狗 (IWDG)的应用方法介绍

目录 概述 1 认识独立看门狗 (IWDG) 1.1 定义独立看门狗 (IWDG) 1.2 IWDG 主要特性 2 IWDG 功能说明 2.1 IWDG 框图 2.2 IWDG 内部信号 2.3 窗口选项 2.3.1 Enable WIN IWDG 2.3.2 Disable WIN IWDG 2.4 硬件看门狗 2.5 低功耗冻结 2.6 停止和待机模式下的行为 …

网工学习云计算HCIE感受如何?

作为一名网工,我经常会在各种网络论坛里查询搜索一些网络技术资料,以及跟论坛里的网友交流讨论平时在工作、学习中遇到的问题、故障,因此也经常能在论坛的首页看到誉天的宣传信息。机缘巧合之下关注了誉天的B站号,自从关注了誉天的…

初级银行从业资格证知识点(二)

系统内联行清算包括: 全国联行往来、分行辖内往来、支行辖内往来 普通支票既可以支取现金也可以转账;划线支票只能转账不能取现。 进出口业务中采用的结算方式: 汇款、托收、信用证 银行常见的清算模式: 全额清算、净额批量清算、…