commit 历史版本记录修正

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习--Matplotlib

机器学习–Matplotlib Matplotlib 是专门用于开发2D图表(包括3D图表)以渐进、交互式方式实现数据可视化 简单的Matplotlib画图 — 以折线图为例 matplotlib.pyplot模块 matplotlib.pytplot包含了一系列类似于matlab的画图函数。 import matplotlib.pyplot as plt图形绘制流…

7.【CPP】String类

一.汉字的编码 我们知道计算机存储英文字母&#xff0c;标点&#xff0c;数字用的是ascall码&#xff0c;128种用一个字节表示绰绰有余。而汉字远远不止128种&#xff0c;因此汉字需要两个字节表示。 1.gbk编码中汉字占两个字节。 2.utf-8中&#xff0c;一个汉字占三个字节。…

Java - 深入四大限流算法:原理、实现与应用

文章目录 Pre概述简单计数器原理实现测试优缺点 滑动窗口算法原理实现测试优缺点 漏桶算法原理实现测试优缺点 令牌桶算法原理实现测试优缺点 小结 Pre 深入理解分布式技术 - 限流 并发编程-25 高并发处理手段之消息队列思路 应用拆分思路 应用限流思路 SpringBoot - 优雅…

(上) C语言中的语句分类及分支语句:if语句、switch语句介绍

目录 前言 一、语句的分类 1. 空语句 2. 表达式语句 3. 函数调用语句 4. 复合语句 5. 控制语句 二、分支语句 1. if语句 (1) if的使用 (2) else的使用 (3) 分支中包含多条语句 (4) 嵌套if (5) 悬空else问题 2. switch语句 (1) if语句和switch语句的对比 (2) s…

摇臂MG995舵机模块实战教程

简介 舵机也叫伺服电机&#xff0c;最早用于船舶上实现其转向功能&#xff0c;由于可以通过程序连续控制其转角&#xff0c;因而被广泛应用智能小车以实现转向以及机器人各类关节运动中。舵机&#xff08;英文叫Servo&#xff09;&#xff1a;它由直流电机、减速齿轮组、传感器…

计算机网络——面试问题

1 从输⼊ URL 到⻚⾯展示到底发⽣了什么&#xff1f; 1. 先检查浏览器缓存⾥是否有缓存该资源&#xff0c;如果有直接返回&#xff1b;如果没有进⼊下⼀ 步⽹络请求。 2. ⽹络请求前&#xff0c;进⾏ DNS 解析 &#xff0c;以获取请求域名的 IP地址 。 3. 浏览器与服务器…

Sqoop与Kafka的集成:实时数据导入

将Sqoop与Kafka集成是实现实时数据导入和流处理的关键步骤之一。Sqoop用于将数据从关系型数据库导入到Hadoop生态系统中&#xff0c;而Kafka则用于数据流的传输和处理。本文将深入探讨如何使用Sqoop与Kafka集成&#xff0c;提供详细的步骤、示例代码和最佳实践&#xff0c;以确…

Git与GitHub零基础教学

大家好&#xff0c;我是星恒&#xff0c;这个帖子给大家分享的是git和github的全套教程&#xff0c;包含github初始&#xff0c;git常用命令以及基本使用&#xff0c;git的ssh链接github&#xff0c;github使用token登录&#xff0c;github和idea的配合&#xff0c;一些平时常用…

适合初学者的 机器学习 资料合集(可快速下载)

AI时代已经来临&#xff0c;机器学习成为了当今的热潮。但是&#xff0c;很多人在面对机器学习时却不知道如何开始学习。 今天&#xff0c;我为大家推荐几个适合初学者的机器学习开源项目&#xff0c;帮助大家更好地了解和掌握机器学习的知识。这些项目都是开源的&#xff0c;…

EtherNet/IP开发:C++开发CIP源代码

① 介绍一下CIP CIP是一种考虑到自动化行业而设计的通用协议。然而&#xff0c;由于其开放性&#xff0c;它可以并且已经应用于更多的领域。CIP网络库包含若干卷&#xff1a; 第1卷介绍了适用于所有网络自适应的CIP的常见方面。本卷包含通用对象库和设备配置文件库&#xff0…

信息安全的脆弱性及常见安全攻击

目录 信息安全概述信息安全现状及挑战传统安全防护逐步失效 安全风险能见度不足看不清资产看不见新型威胁看不见内网潜藏风险 常见的网络安全术语信息安全的脆弱性及常见安全攻击网络环境的开放性协议栈的脆弱性及常见攻击常见安全风险 协议栈自身的脆弱性网络的基本攻击模式 链…

Dubbo的几个序列化方式

欢迎订阅专栏&#xff0c;会分享Dubbo里面相关的技术实现 这篇文章就不详细的介绍每种序列化方式的实现细节&#xff0c;大家可以自行去问度娘&#xff0c;我也会找一些资料。需要注意的是&#xff0c;这个先后顺序不表示性能优越 ObjectInput、ObjectOutput 这两是Dubbo序列…

Linux_清理docker磁盘占用

文章目录 前言一、docker system 命令1. docker system df&#xff08;本文重点使用&#xff09;2. docker system prune&#xff08;本文重点使用&#xff09;3. docker system info4. docker system events 二、开始清理三、单独清理Build Cache四、单独清理未被使用的网络 前…

如何理解 GO 语言的接口 - 鸭子模型

个人认为&#xff0c;要理解 Go 的接口&#xff0c;一定先了解下鸭子模型。 鸭子模型 那什么鸭子模型&#xff1f; 鸭子模型的解释&#xff0c;通常会用了一个非常有趣的例子&#xff0c;一个东西究竟是不是鸭子&#xff0c;取决于它的能力。游泳起来像鸭子、叫起来也像鸭子…

【Emgu CV教程】5.6、几何变换之LinearPolar()极坐标变换

LinearPolar()线性极坐标转换函数用于将图像从笛卡尔坐标系转换为极坐标系&#xff0c;太难懂了&#xff0c;还是简单的说吧 笛卡尔坐标系就是平面直角坐标系&#xff0c;用X轴、Y轴表示的图像&#xff0c;最常用的表示方式&#xff0c;比如灰度图Point(360,100) 230&#xff…

数据结构与算法教程,数据结构C语言版教程!(第五部分、数组和广义表详解)四

第五部分、数组和广义表详解 数组和广义表&#xff0c;都用于存储逻辑关系为“一对一”的数据。 数组存储结构&#xff0c;99% 的编程语言都包含的存储结构&#xff0c;用于存储不可再分的单一数据&#xff1b;而广义表不同&#xff0c;它还可以存储子广义表。 本章重点从矩阵…

【工具使用】Keil5软件使用-基础使用篇

一、概述 本文面向未接触过Keil的新手&#xff0c;如果是职场老手可跳过此篇。为了快速上手&#xff0c;本文会跳过很多细节及解释&#xff0c;如需要了解原理&#xff0c;请移步进阶篇。 二、 软件介绍 Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调…

【Git不走弯路】(二)提交与分支的本质

1. 前言 提交与分支是Git中两个基本对象&#xff0c;对初学者而言需要花些时间理解。正如我们之前所说&#xff0c;计算机中很多新概念是新瓶装旧酒。计算机技术来源于需求&#xff0c;服务于需求&#xff0c;需求是计算机技术的出发点和落脚点。梳理清楚工程实践中&#xff0…

【开源】基于JAVA的停车场收费系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 停车位模块2.2 车辆模块2.3 停车收费模块2.4 IC卡模块2.5 IC卡挂失模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 停车场表3.2.2 车辆表3.2.3 停车收费表3.2.4 IC 卡表3.2.5 IC 卡挂失表 四、系统实现五、核心代码…

2023.1.21 关于 Redis 主从复制详解

目录 引言 单点问题 分布式系统 ​​​​​​​​​​​​​​主从模式 配置 Redis 主从结构 断开主从关系 切换主从关系 补充知识点一 只读 网络延迟 拓扑结构 一主一从 一主多从 树形主从结构 主从复制的基本流程 数据同步 replicationid offset pzync 运…