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

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

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

相关文章

Rockchip linux USB 驱动开发

Linux USB 驱动架构 Linux USB 协议栈是一个分层的架构&#xff0c;如下图 5-1 所示&#xff0c;左边是 USB Device 驱动&#xff0c;右边是 USB Host 驱动&#xff0c;最底层是 Rockchip 系列芯片不同 USB 控制器和 PHY 的驱动。 Linux USB 驱动架构 USB PHY 驱动开发 USB 2…

手机也能随时随地玩红警啦!

还在为找不到红警安装包苦恼吗&#xff1f; 现在可以随时随地&#xff0c;无论手机、ipad、电脑都可以无需安装包在线玩红警啦&#xff01;&#xff01; 不仅能本地单机玩耍&#xff0c;还能联网玩耍&#xff08;可以和老外一起玩哦&#xff5e;&#xff09; 具体在线链接可…

算法第二十一天-丑数

丑数 题目要求 解题思路 首先判断数字是不是为0或者负数&#xff0c;两者均不可能成为丑数&#xff1b; 之后对n进行不断整除&#xff0c;直到无法除尽为止。 简单判断最后的数是不是1即可。 代码 class Solution:def isUgly(self, n: int) -> bool:if n<0:return Fa…

Linux启动流程梳理值得收藏

Linux启动流程总的来说可以分成三个阶段 Linux启动流程图 第一步&#xff1a;上电 在 x86 系统中&#xff0c;将 1M 空间最上面的 0xF0000 到 0xFFFFF 这 64K 映射给 ROM。 当电脑刚加电的时候&#xff0c;会做一些重置的工作&#xff0c;将 CS 设置为 0xFFFF&#xff0c;将 IP…

Docker命令---搜索镜像

介绍 使用docker命令搜索镜像。 命令 docker search 镜像命令:版本号示例 以搜索ElasticSearch镜像为例 docker search ElasticSearch

【unity】麦克风声音驱动,控制身体做出不同动作

1.在角色对象上挂在animator组件&#xff0c;并将动作控制器与其关联 2.在角色对象上挂在audio source组件。 3.新建voice control脚本&#xff0c;编写代码如下&#xff1a; using System; using System.Collections; using System.Collections.Generic; using UnityEngine;…

复现PointNet++(语义分割网络):Windows + PyTorch + S3DIS语义分割 + 代码

一、平台 Windows 10 GPU RTX 3090 CUDA 11.1 cudnn 8.9.6 Python 3.9 Torch 1.9.1 cu111 所用的原始代码&#xff1a;https://github.com/yanx27/Pointnet_Pointnet2_pytorch 二、数据 Stanford3dDataset_v1.2_Aligned_Version 三、代码 分享给有需要的人&#xf…

算法专题[递归-搜索-回溯-2-DFS]

算法专题[递归-搜索-回溯-2-DFS] 一.计算布尔二叉树的值&#xff1a;1.思路一&#xff1a;2.GIF题目解析 二.求根节点到叶子节点的数字之和1.思路一&#xff1a;2.GIF题目解析 三.二叉树剪枝1.思路一&#xff1a;2.GIF题目解析 四.验证二叉搜索树1.思路一&#xff1a;2.GIF题目…

1.2 数据模型

数据模型是对现实世界数据特征的抽象&#xff0c;是现实世界的模拟 数据模型是用来描述数据、组织数据和对数据进行操作的 数据模型应满足三方面要求&#xff1a; 1 能比较真实地模拟现实世界 2 容易为人所理解 3 便于在计算机上实现 数据模型…

08. Springboot集成webmagic实现网页爬虫

目录 1、前言 2、WebMagic 3、Springboot集成Webmagic 3.1、创建Springboot&#xff0c;并引入webmagic依赖 3.2、定义PageProcessor 3.3、元素选择 3.3.1、F12查看网页元素 3.3.2、元素选择 3.3.3、注意事项 4、小结 1、前言 在信息化的时代&#xff0c;网络爬虫已…

QT的绘图系统QPainterDevice与文件系统QIODevice

QT的绘图系统&#xff08;QPainterDevice&#xff09;与文件系统&#xff08;QIODevice&#xff09; 文章目录 1、Qt 的绘图系统1、QPainter的使用2、QPen(画笔&#xff09;及QBursh&#xff08;画刷&#xff09;3、手动更新窗口4、绘图设备1、四种绘图设备的 区别2、 QBitmap3…

零食折扣店,注定昙花一现?

年终岁末&#xff0c;又到了各类休闲零食产品一年一度的销售旺季。与过去不同的是&#xff0c;近年来的休闲零食赛道正因大量零食折扣店的涌现而显得热闹非凡。 随着主打折扣、低价的零食折扣店成为消费者特别是三四线下沉市场消费者的新宠&#xff0c;资本开始涌入并快速推动…

SpringCloud之OpenFeign的学习、快速上手

1、什么是OpenFeign OpenFeign简化了Http的开发。在RestTemplate的基础上做了封装&#xff0c;在微服务中的服务调用发送网络请求起到了重要的作用&#xff0c;简化了开发&#xff0c;可以让我们跟写接口一样调其他服务。 并且OpenFeign内置了Ribbon实现负载均衡。 官方文档…

69.使用Go标准库compress/gzip压缩数据存入Redis避免BigKey

文章目录 一&#xff1a;简介二&#xff1a;Go标准库compress/gzip包介绍ConstantsVariablestype Headertype Reader 三&#xff1a;代码实践1、压缩与解压工具包2、单元测试3、为何压缩后还要用base64编码 代码地址&#xff1a; https://gitee.com/lymgoforIT/golang-trick/t…

SpringBoot3整合OpenAPI3(Swagger3)

文章目录 一、引入依赖二、使用1. OpenAPIDefinition Info2. Tag3. Operation4. Parameter5. Schema6. ApiResponse swagger2更新到3后&#xff0c;再使用方法上发生了很大的变化&#xff0c;名称也变为OpenAPI3。 官方文档 一、引入依赖 <dependency><groupId>…

深度解析Python关键字:掌握核心语法的基石(新版本35+4)

目录 关键字 keyword 关键字列表 kwlist softkwlist 关键字分类 数据类型 True、False None 运算类型 and、or、not in is 模块导入 import 辅助关键字 from、as 上下文管理 with 占位语句 pass 流程控制 if、elif、else for while break、continue…

第十回 朱贵水亭施号箭 林冲雪夜上梁山-FreeBSD/Linux 控制台基础操作

林冲被众庄客捉住&#xff0c;吊在门楼下&#xff0c;正被打时&#xff0c;柴进来了&#xff0c;赶快把林冲救下来。原来这是柴进打猎用的小庄子&#xff0c; 林冲就把火烧草料场一事跟柴进详细的说了。柴进说兄弟真是命运多磨难啊。林冲住了几日&#xff0c;恐怕连累柴进&…

Laykefu客服系统 任意文件上传漏洞复现

0x01 产品简介 Laykefu 是一款基于workerman+gatawayworker+thinkphp5搭建的全功能webim客服系统,旨在帮助企业有效管理和提供优质的客户服务。 0x02 漏洞概述 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞,而且当请求中Cookie中的”user_name“不为…

[学习笔记]刘知远团队大模型技术与交叉应用L3-Transformer_and_PLMs

RNN存在信息瓶颈的问题。 注意力机制的核心就是在decoder的每一步&#xff0c;都把encoder的所有向量提供给decoder模型。 具体的例子 先获得encoder隐向量的一个注意力分数。 注意力机制的各种变体 一&#xff1a;直接点积 二&#xff1a;中间乘以一个矩阵 三&#xff1a;…

找不到vcruntime140_1.dll无法继续执行怎么办?全面分析修复方法

当系统提示vcruntime140_1.dll文件出现错误时&#xff0c;可能会引发一系列影响计算机正常运行的问题。这个特定的动态链接库文件&#xff08;DLL&#xff09;是Microsoft Visual C Redistributable的一部分&#xff0c;对于许多基于Windows的应用程序来说至关重要。一旦vcrunt…