commit 历史版本记录修正

news2024/12/27 18:45:49

commit 历史版本记录修正

当 Bug 发生的时候,我们会需要去追踪特定 bug 的历史记录,以查出该 bug 真正发生的原因,这个时候就是版本控制带来最大价值的时候。

因此,要怎样维持一个好的版本记录是非常重要的,下面是一些版本提交经验:

  • 做一个小功能修改就要进行提交,记录一个版本,这样才容易追踪变更;
  • 不要累积一大堆修改后才提交,这样就会导致记录的是一个大版本,不易追踪细节功能;
  • 有顺序、有逻辑的增加新功能,这样才能确保相关的版本可以按顺序提交,更有利于追踪变更;

不过,在多人协同合作开发的时候,很难保证所有人都能按照上面的几点进行版本控制。我们的习惯更多的可能是想到哪就改到哪,在改完之后就提交。基于这种情况,Git 中存在一个「修改版本」的机制,让我们在把提交推送至远程仓库之前,可以重写历史提交记录,这样就可以使得推送的版本已经是完美的状态。

在满意之前不要推送我们的工作
Git 的基本原则之一是,由于克隆中有很多工作是本地的,因此我们可以 在本地 随便重写历史记录。 然而一旦推送了我们的工作,那就完全是另一回事了,除非我们有充分的理由进行更改,否则应该将推送的工作视为最终结果。 简而言之,在对它感到满意并准备与他人分享之前,应当避免推送我们的工作。

需要修改记录的情况

在之前的几篇文章里,我们提到了 Git 的版本控制的仓库就处于 .git 文件夹中,如果我们是多人协同开发,那么到时候就有多人拥有这个仓库,如果有人任意窜改历史记录,那么这个版本控制就没有意义了。所以我们必须要谨记,修改记录只能在本地进行,在已经推送到远程仓库时,就不要在更改了

那么,在什么样的情况我们会需要去修改版本记录呢?以下几点大家可以参考一下:

  • 当某个版本提交错了,必须要删除这个版本的所有提交;
  • commit 的时候提交信息有误,想要修改信息,但是不会影响到文件的变更;
  • 想调整提交版本的顺序,让更改历史更加有逻辑性;
  • 当某个提交版本缺失重要文件,想重新添加上去;

修改记录的几种方法

在 Git 中有几种可以修改记录的方法,这些方法都有不同的适用情形,我们来逐个介绍一下:

commit --amend

修改最后一次提交。

修改我们最近一次提交可能是所有修改历史提交的操作中最常见的一个。对于我们的最近一次提交,我们往往想做两件事情:简单地修改提交信息,或者通过添加、移除或修改文件来更改提交实际的内容。

命令也非常简单:git commit --amend。不过命令的执行顺序需要注意一下:

  1. 如果我们只是想修改最近一次提交的提交信息,直接执行 git commit --amend 即可,在执行完后会打开一个编辑器,在这个编辑器中 Git 会将最后一次的提交信息载入到编辑器中供我们修改,当保存并关闭编辑器后,编辑器会将更新后的提交信息写入新提交中,它会成为新的最后一次提交。

    例如,我们的最新一次的提交信息写错了:

    在这里插入图片描述

    执行 git commit --amend 命令打开了一个编辑器,重新编辑信息:

    在这里插入图片描述

    之后再执行 git log 查看可以发现最新的提交信息已经更改,但是 hash 值变了,其实这是一个新的 commit:

    在这里插入图片描述

  2. 如果我们想修改最后一次提交的实际内容(修改文件或者添加文件),那么就需要先把这些改动添加到「暂存区」,之后再执行 git commit --amend:

    例如我们需要在这次提交添加多一个 file2.txt 文件:

    在这里插入图片描述
    在这里插入图片描述

reset

git reset 主要用来重置目前的工作目录。不过,也可以用来修正版本历史记录。

删除最新一次的版本

例如当前我们有三个提交版本:

在这里插入图片描述

想要删除最新一次版本,可以执行 git reset --hard “HEAD^” 命令(HEAD 是一个指针,指向当前最新一次提交,保存在 .git/HEAD 文件中)。

在「命令提示符」中 ^ 是特殊符号,所以必须用双引号括起来

在这里插入图片描述

此时我们可以看见,原本的最新版被删除了,那是因为刚刚我们执行 git reset --hard “HEAD^” 这个动作,把 HEAD 指向的位址改到了前一个版本 ( HEAD^ ),所以我们执行 git log 命令就看不到这个版本了。

事实上,原本我们感觉被删除的版本,其实一直储存在 Git 的对象储存区中(也就是在 .git/objects 目录下)。我们还是可以用 git show 5846df 取得该版本 (即「commit 对象」) 的详细信息:

在这里插入图片描述

执行有风险的操作,如 merge,reset、rebase 等会影响当前指针的操作,都会把当前指针储存在 .git/ORIG_HEAD 文件中,只要执行 git reset --hard ORIG_HEAD 都可以还原回去。

删除最新一次的版本,但保留最后一次的变更

git reset --soft “HEAD^” 命令可以删除最新一次的版本,但是在「暂存区」仍然保留着文件变更的信息。

例如在最新的一次提交中添加了一个 file4.txt 文件,然后执行 git reset --soft “HEAD^” 命令删除掉这次的版本,此时 file4.txt 仍处于「暂存区」中,通过 git status 即可看到 file4.txt 文件的状态

在这里插入图片描述
在这里插入图片描述

这也意味着,我们可以保留最后一次的变更,再加上一些变更后,重新执行 git commit,就可以重新提交一个新的 commit。

revert

还有个常见的情况,那就是当执行了多个版本之后,才发现前面有一个版本改错了,但是我们想保留改错版本之后的所有变动,只想把改错的版本修复好,这样的话 reset 就不适用了,可以考虑 revert 命令:

比如说我们添加了一个 file.txt 文件,改动了一次,之后又添加了一个 file2.txt 文件:

在这里插入图片描述

最后发现把 file.txt 的内容改成 2 是错的,而此时我们希望可以将该版本还原成原始版本就好,而不是修改当前版本成第一版然后提交,那么就可以试试 git revert <hashName> 指令:

由于改动是从 682b7e… 版本(把内容改成2)开始的,因此需要返回到这个版本:

再执行了 git revert 682b7 命令后,会打开一个编辑器让我们编辑最后要 commit 的消息,预设会加上 Revert 字样,还有会在第二行的地方加上 This reverts commit xxxx 告诉我们说这个版本主要目的是从 xxxx 版本还原的。

在这里插入图片描述

保存后会额外再建立一个新版本,执行 git log 命令看看结果:

在这里插入图片描述

解决冲突

如果我们要还原的版本与当前的版本的文件存在差异,那么就会导致冲突(Git 内部会执行合并操作)。

我们把上面的还原版本重置一下,重置成未还原的版本:

在这里插入图片描述

然后修改 file.txt 的内容为 3,此时再执行 git revert 682b7 把 file.txt 的内容还原成 3,就会造成冲突:

在这里插入图片描述

发生本次冲突的原因就在于,我们想还原的 682b7 这个版本,这次的变更原本是 1 改成 2,由于我们想还原内容,则是把 2 改为 1,但我们现在的内容却是 3 而不是 2,因而发生了冲突状況。

解决冲突的方法我们在 git 中分支的概念及使用 中讲过了,这里就不再赘述。

在解决完冲突之后,我们仍需要执行 git add 命令把已解决冲突的文件放入「暂存区」,之后执行 git revert --continue 继续执行还原流程,这个命令同样会打开编辑器,这里的预设内容也会标示那些文件发生了冲突:

在这里插入图片描述

cherry-pick

如果我们在某个分支上开发,但后来决定整个分支都不要了,不过当中却有几个版本还想留下,这时要删除分支也不是,把这个分支合并回来也不是、这时候就可以使用 git cherry-pick <hashId> 命令了。

使用 git cherry-pick 跟使用 git revert 非常相似,也是让我们「挑选」任意一个或多个版本,然后合并到当前分支的最新版上。

在这里插入图片描述

目前我们存在一个 newBranch 分支领先 master 分支两个版本,我们切换回 master 分支,并执行 git cherry-pick 225bac9 命令把 225bac9 版本合并到 master 上,若成功执行,则会在目前的 master 分支建立一个新版本。

在这里插入图片描述

不过,与 git revert 最大的不同之处,就在于执行完 git cherry-pick 命令后,其建立的版本消息,将会与我们指定挑选的那些版本一模一样,其中包括 Author 与 Date 栏位,都会一模一样,并不会用我们在选项设定中指定的 user.name 与 user.email 参数。这点我们必须特别注意!

-x 参数

如果我们在命令上加上 -x 参数,就会像 git revert 那样,自动加上 (cherry picked from commit xxxx) 的消息:

在这里插入图片描述

不过,做这个动作之前也请先思考,我们这次挑选的版本是不是只有「本地才有的分支」上挑选的,如果是的话,这样的记录可能会造成其他人的混淆,因为他们查不到该版本的任何信息。这在使用远端仓库的情境比较会碰到。

rebase

严格上来说 git revert 与 git cherry-pick 并不算是修正历史版本记录,而是套用先前曾经 commit 过的版本,而这个所谓的 rebase 机制就是真的用来修改 commit 记录的功能了,其功能重要而且强大。

什么是rebase

git rebase 是一个命令,可以帮助我们将更改的代码从一个分支集成到另一个分支。想象一下我们正在建造一座塔,我们已经建立了一个坚固的基础,但在中途,我们决定在不影响上面的结构的情况下改变基础。这就是 rebase 的作用 —— 它改变了分支的基础。

用技术术语来说,rebase 是将一系列提交移动或组合到新的基础提交的过程。

我们来个跟 merge 对比的示意图来更好的理解:

假设我们有个存在 master、dev 分支的仓库,且各自都有提交版本:

在这里插入图片描述

当我们在 master 分支执行 git merge dev 命令后,结构示意图如下:

在这里插入图片描述

而当在 master 分支执行 git rebase dev 命令后,结构示意图如下:

在这里插入图片描述

将master 分支的整个历史记录放在 dev 分支顶部来提供线性历史记录。

我们用一个实例结合 sourceTree 看看会容易理解:

在这个实例中存在 master、newBranch 两个分支:

在这里插入图片描述

当我们在 master 执行 git merge newBranch 后,图谱里提交记录变成了一条直线:

在这里插入图片描述

虽然此时看起来像只有一条 master 分支,其实还是存在两个(master、newBranch)的。

地址

文章仓库地址:https://github.com/leopord-lau/easy-git

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

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

相关文章

第91讲:MySQL主从复制集群主库与从库状态信息的含义

文章目录 1.主从复制集群正常状态信息2.从库状态信息中重要参数的含义 1.主从复制集群正常状态信息 通过以下命令查看主库的状态信息。 mysql> show processlist;在主库中查询当前数据库中的进程&#xff0c;看到Master has sent all binlog to slave; waiting for more u…

通俗易懂理解小波池化/WaveCNet

重要说明&#xff1a;本文从网上资料整理而来&#xff0c;仅记录博主学习相关知识点的过程&#xff0c;侵删。 一、参考资料 github代码&#xff1a;WaveCNet 通俗易懂理解小波变换(Wavelet Transform) 二、相关介绍 关于小波变换的详细介绍&#xff0c;请参考另一篇博客&…

【工具与中间件】GitGitHub相关知识与一些问题解决、工具推荐

文章目录 前言1. Git 基础快速回顾1.1 Git 相关概念简单回顾1.2 Git 基本命令1.2.1 分支命令1.2.2 推拉命令 2. Git Hub 创建仓库3. 版本控制实战3.1 创建本地项目3.2 绑定远程仓库3.3 代码推拉3.3.1 推拉实战3.3.2 合并请求 4. 补充与总结4.1 可能会遇到的问题4.2 补充&#x…

Unity -简单键鼠事件和虚拟轴

简单键鼠事件 — “Test_03” KeyTest 键鼠事件每帧都要监听&#xff0c;要放在Update()中处理 public class KeyTest : MonoBehaviour {// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){// 【鼠标点击事件…

15.1_使用Verilog设计:一个简单的状态机设计——序列检测器(可实现重复性检测)

使用Verilog设计&#xff1a;一个简单的状态机设计——序列检测器&#xff08;可实现重复性检测&#xff09; 1&#xff0c;一个简单的状态机设计&#xff1a;可重复性序列检测器2&#xff0c;可重复性状态机序列检测实现2.1&#xff0c;RTL设计代码实现2.2&#xff0c;tb测试代…

加码OT安全丨Fortinet与施耐德电气携手共创工业零信任安全创新方案

近日&#xff0c;专注于推动网络与安全融合的全球网络安全领导者 Fortinet在施耐德电气举办的第四季“绿色智能制造创赢计划”结营仪式上&#xff0c;正式与其签署联创方案合作协议&#xff0c;成为施耐德电气“生态合作伙伴”。双方将依托“基于关键装置/设备的微隔离防护”这…

【RT-DETR有效改进】Google | EfficientNetV2一种超轻量又高效的网络 (轻量化网络)

前言 大家好&#xff0c;我是Snu77&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持Re…

Oracle 高级网络压缩 白皮书

英文版白皮书在这里 或 这里。 本文包括了对英文白皮书的翻译&#xff0c;和我觉得较重要的要点总结。 执行概述 Oracle Database 12 引入了一项新功能&#xff1a;高级网络压缩&#xff0c;作为高级压缩选项的一部分。 本文概述了高级网络压缩、其优点、配置细节和性能分析…

基于SpringBoot的儿童疫苗预约系统的设计与实现-计算机毕业设计源码12222

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 儿童疫苗预约管理&#xff0c;主要的模块包括查看首页、站点管理&#xff08;轮播图、公告栏&#xff09;用户管理&#xff08;管理员、系统用…

【开源】基于JAVA语言的课程案例资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员需求分析2.2 用户需求分析 三、系统设计3.1 业务流程设计3.1.1 管理员业务流程设计3.1.2 用户业务流程设计3.1.3 首页功能模块及业务流程分析3.1.4 案例资源中心功能模块及业务流程分析3.1.5 用户信息中心功能模块…

seaborn可视化示例详解

目录 1、散点图 2、散点图回归线 3、折线图 4、频数柱状图 5、分组散点图 6、箱型图 7、数值分布柱状图 8、频数分布图 9、联合分布图 10、数值分布柱状图 11、相关系数热力图 划重点 少走10年弯路 Seaborn是一个基于Python的数据可视化库&#xff0c;Seaborn提供了许多用…

Keepalived + Nginx双主架构

Keepalived Nginx双主架构 环境准备&#xff1a; keepalived_master1服务器nginx&#xff1a;172.20.26.167 keepalived_master2服务器nginx&#xff1a;172.20.26.198 各服务器关闭selinux、防火墙等服务。 开机安装部署nginx 在172.20.26.167服务器上 yum install ngi…

(2023版)斯坦福CS231n学习笔记:DL与CV教程 (15) | 变分自编码器和扩散模型

前言 &#x1f4da; 笔记专栏&#xff1a;斯坦福CS231N&#xff1a;面向视觉识别的卷积神经网络&#xff08;23&#xff09;&#x1f517; 课程链接&#xff1a;https://www.bilibili.com/video/BV1xV411R7i5&#x1f4bb; CS231n: 深度学习计算机视觉&#xff08;2017&#xf…

冒泡排序-BubbleSort

1、基本思路 从数组的左边开始&#xff0c;比较两个元素的大小&#xff0c;当左边大于右边时&#xff0c;更换左右元素位置&#xff0c;否则不改变&#xff1b;接着向右移动一步&#xff0c;比较第二个元素和第三个元素的大小&#xff0c;重复上述操作&#xff0c;直到最后一个…

chapter12-实战成绩通知短信系统(下)

注意&#xff01;成绩短息通知服务的源码共分为两种&#xff1a;第一种为线性的程序&#xff0c;逻辑简单&#xff0c;但是格式杂乱&#xff1b;第二种为以类作为基础&#xff0c;封装了各种函数&#xff0c;逻辑较为复杂&#xff0c;但是格式清晰。建议新手先学习第一种代码风…

2. SpringBoot3 实战之用户模块接口开发

文章目录 开发模式和环境搭建开发模式环境搭建 1. 用户注册1.1 注册接口基本代码编写1.2 注册接口参数校验 2. 用户登录2.1 登录接口基本代码编写2.2 登录认证2.2.1 登录认证引入2.2.2 JWT 简介2.2.3 登录功能集成 JWT2.2.4 拦截器 3. 获取用户详细信息3.1 获取用户详细信息基本…

优化算法--李沐

目录 1.1梯度下降 1.2随机梯度下降 1.3小批量随机梯度下降 1.4冲量法 1.5 Adam 损失值也就是预测值与真实值之间的差值是f(x)&#xff0c;x是所有超参数组成的一条向量&#xff0c;c是可以限制的&#xff0c;比如说权重大于等于0。 使用迭代优化算法求解一般只能保证找到局…

web开发学习笔记(12.mysql数据库进阶)

1.多表查询 2.内连接 3.外连接&#xff0c;分为左外连接和右外连接 左外连接完全包含左表的数据和两个表的交集 右外连接完全包含右表的数据和两个表的交集 4.子查询&#xff0c;又成为嵌套查询 分为标量子查询和列子查询和行子查询 首先是标量子查询 列子查询 in, not in…

sqlilabs第六十一六十二关

Less-61(GET - challenge - Double Query- 5 queries allowed -Variation 4) 手工注入 报错注入 Less-62(GET - challenge - Bilnd- 130 queries allowed -Variation 1) 手工注入 过于复杂简单写写 这个应该是用不了只能用延时 自动注入 写个脚本就可以

Mysql-全局锁、表锁、行锁

本文已收录于专栏 《数据库》 目录 全局锁概述说明开启方式应用场景 表锁概念说明实现方式意向锁 开启方式 行锁概念说明实现方式记录锁&#xff1a;间隙锁临键锁 总结提升 全局锁 概述说明 全局锁是是对整个数据库实例加锁&#xff0c;加锁后整个实例就处于只读状态&#xff…