大家好,今天我们来聊聊git当中一个很重要的功能——历史记录的修改

有的时候我们会突然发现某个地方需要修改,最常见的某个不应该被提交的文件被提交了进来。我们希望它不只是在后序的版本当中不再出现,而是希望整个从git仓库当中移除掉。这个时候我们就需要修改git之前的历史记录。这个时候应该怎么办呢?

不要着急,git当中有很多的手段可以修改之前的历史提交记录。

修改最后一次提交

这一点我们在之前的文章当中曾经提到过,如果我们只是想要修改最后一次的提交记录,这是比较简单的。我们只需要直接修改我们想要修改的部分,在提交的时候加上一个参数--amend即可。

git commit --amend

amend的意思是补丁,它可以把我们这一次的修改合并到上一条历史记录当中,而不会产生一个新的commit记录。运行之后,它会打开一个vim编辑器,我们还可以修改上一次commit时输入的提示信息。

我们使用git log检查的话,会发现历史记录的修改时间还是上一次的时间。看起来就好像什么也没有发生过一样,悄无声息地就改掉了。

修改多个信息

--amend虽然好用,但是它只能修改最后一次的提交信息,如果我们想要修改的提交记录在那之前,我们应该怎么办呢?

git当中并没有提供直接的工具来实现这一点,不过我们可以使用rebase来达成。我们可以加上-i进行交互式地变基,我们可以在任何想要的修改完成之后停止,也可以添加文件或者是做其他想要做的事情。但是我们变基的目标不是某一个分支而是当前分支的某一个历史节点,所以我们需要提供一个具体的commitid或者是指针位置

git rebase -i的功能非常强大,我们几乎可以使用它来完成所有一切我们想要完成的事情。

比如我们想要修改倒数第二次提交,我们可以执行git rebase -i HEAD~3。也就是以倒数第三个节点作为基准节点执行变基,这时候git会进入一个vim窗口,在这个窗口当中我们可以看到最近的三次提交记录。

首先我们可以看到上面的三行就是我们可以修改的三个commit,分别展示的是要执行的操作以及commitid以及commit message。这里的操作默认的是pick,也就是使用该commit。关于我们可以执行的操作git在下方也给了充分的提示,其中比较常用的有pick、edit以及squash

这一次我们想要做的是修改提交记录,所以我们应该执行edit,我们把想要修改的commit前的pick改成edit。比如这样:

退出之后,git会自动带我们回到我们选择edit的分支提交之后的版本。我们进行我们想要的修改,这里我在第15篇文章当中加上了一行:尝试rebase。之后再使用git add以及git commit --amend进行修改提交结果。

再之后我们执行git rebase --continue,把剩下要应用的变更应用完成。

一切都结束之后,我们可以使用一下git show命令查看一下我们修改的bee9ce3这个commit的记录。可以看到已经多了这一行,说明我们的修改成功了。

顺序变更、合并、拆分

顺序变更

我们不仅可以修改某一次commit当中的内容,还可以修改这些commit的相对顺序,以及可以让它们合并以及拆分。

修改顺序其实很简单,我们只需要人为地修改rebase -i之后弹出的vim文件即可。比如说原本的记录是:

pick A change A
pick B change B
pick C change C

如果我们想要更换顺序,我们只需要修改这个文件即可。比如变成:

pick B change B
pick A change A
pick C change C

那么当我们在退出vim的时候,git会首先应用B commit的变更,再应用A最后应用C。

合并

除此之外,我们还可以合并多个commit记录成一个。操作的方法也很简单,就是我们只需要把pick修改成squash。git会自动把所有squash的commit记录合并在一起。

pick A change A
squash B change B
squash C change C

拆分

有的时候一个commit非常巨大,我们可能也会想要将它拆分,其实操作也很简单。比如我们想要把commit B拆分成两条,首先,我们在rebase的时候将commit B前面的pick修改成edit。

pick A change A
edit B change B
pick C change C

当我们退出的时候,我们会进入到B commit刚刚提交完的状态。由于我们要做的是拆分B这个提交,所以我们需要执行git reset HEAD^,把上一次提交重置。然后再分别add我们想要拆分开来提交的文件。

整个操作如下:

git reset HEAD^
git add test/*
git ci -m 'add test'
git add code/*
git ci -m 'update code'
git rebase --continue

这样我们就把commit B拆分成了两个commit插入到了历史记录当中了。

最后的最后,大家需要注意,虽然这些手段在修改记录的时候非常好用。但是如果这些commit已经被提交到了远程,我们是不可以直接git push同步的。因为git会校验我们提交的hash值,发现对不上之后会禁止我们的提交。所以如果想要提交到远程的话,只能使用git push -f强制覆盖。但是这是一个非常非常危险的操作,如果你git push -f了,没有人会知道你到底修改了什么,只建议在自己独有的分支上如此操作,一定一定要谨慎使用。

今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

Git提交错了不用慌,这三招帮你修改记录的更多相关文章

  1. 设置Git提交时不用输入用户名和密码

    在用git提交时代码至github上时每次都要输入用户名和密码,当提交操作较为频繁时非常不方便,可以按下文中的介绍,设置成提交时不用输入用户名和密码: 1.在当前库下,已经运行过 git remote ...

  2. git,提交错了分支,想把远程的分支恢复到上一个版本

    1.先将本地分支回滚到上一个版本 2.删除远程分支(可以先备份一下) 3.创建新的分支,将本地分支push上去

  3. 如何三招帮你排查Linux中的硬件问题

    下列贴士帮助你更快速更轻松地为Linux中的硬件排查故障.许多不同的因素可能导致Linux硬件出现问题:在你开始尝试诊断之前,了解最常见的问题以及最有可能找到原因的环节是明智之举. Linux服务器在 ...

  4. 不用copy代码--eclipse使用git提交项目-转

    原文地址:http://blog.csdn.net/u014079773/article/details/51595127 准备工作: 目的:eclipse使用git提交本地项目,提交至远程githu ...

  5. vue+node+mongoDB 火车票H5(三)---git提交时忽略不想提交的文件

    想要把项目通过git提交到GitHub上,但提交时并不想提交node_modules文件夹,这个文件夹太大 git 提交代码时不提交配置文件夹node_modules 在.gitignore文件中添加 ...

  6. Git三招

    一.Git提交指令 git init git第一次使用在当前文件夹初始化一个git仓库,第二次不需要 git add . 把当前文件夹所有文件添加到缓存区中. 可以选特定的文件夹或文件.将后面的.改变 ...

  7. Git提交引用和引用日志

    转载自:https://github.com/geeeeeeeeek/git-recipes/wiki/5.5-Git%E6%8F%90%E4%BA%A4%E5%BC%95%E7%94%A8%E5%9 ...

  8. Git提交项目到GitHub

    一.GitHub新建项目 1.进入Github首页,点击New repository新建一个项目 2.填写相应信息后点击create即可 Repository name: 仓库名称 Descripti ...

  9. Git提交代码到主分区

    git 提交代码,本地新建一个my分支,不从本地master分支直接上传,而是先从本地my分支上提交至本地master分支,然后本地master提交至远程master分支 上.前提是远程只有一个mas ...

随机推荐

  1. Java线程池一:线程基础

    最近精读Netty源码,读到NioEventLoop部分的时候,发现对Java线程&线程池有些概念还有困惑, 所以深入总结一下 线程创建 Java线程创建主要有三种方式:继承Thread类.实 ...

  2. 获取Win和Linux系统启动时间,类似uptime功能,用于判断是否修改过系统时间

    目录 前言 测试代码 Win测试 Linux测试 总结 前言 有时候需要判断系统是否有修改过时间,最简单的方法就是获取当前时间A,然后sleep X秒,然后获取 时间B,如果 时间B - 时间A ≠ ...

  3. linux ssh远程连接控制 linux(centOS) 口令、密钥连接

    sshd服务提供两种安全验证的方法: 基于口令的安全验证:经过验证帐号与密码即可登陆到远程主机. 基于密钥的安全验证:需要在本地生成"密钥对"后将公钥传送至服务端,进行公共密钥的比 ...

  4. 思维导图学 Kotlin

    前言 最近做了<Kotlin实战>的思维导图笔记,Kotlin真香-- 目录 基础 函数 类.对象 λ表达式 类型 约定 高阶函数.泛型 公众号 coding 笔记.点滴记录,以后的文章也 ...

  5. oracle 流程控制句式

    --for loop declare val number(10):=0; begin for val in 0..10 loop dbms_output.put_line('val='||val); ...

  6. Kafka速度为什么那么快

    记录一下 Kafka速度为什么那么快 Kafka的消息是保存或缓存在磁盘上的,一般认为在磁盘上读写数据是会降低性能的,因为寻址会比较消耗时间,但是实际上,Kafka的特性之一就是高吞吐率. 即使是普通 ...

  7. 基于CefSharp开发(五)浏览器菜单样式

    一.菜单分析 上图为Edge浏览器现有的菜单内容,菜单中即有子菜单也有组合菜单. 本章节将开发浏览器菜单样式,菜单部分功能将后期进行处理. 二.创建菜单用户控件 新建用户控件命名为WebMenuUc, ...

  8. Tree--二叉树BinarySearchTree

    BinarySearchTreeMap的实现 1 public interface Map<K extends Comparable<K>, V> { 2 void put(K ...

  9. 关于老猿Python系列文章发布网址变化的说明

    老猿Python系列文章最开始在新浪发布,后逐渐开通了CSDN.博客园和简书三个网址,但老猿一来工作忙,二来Python需要学习的内容太多,因此实在没时间同时维护这么多博客,事实上除了CSDN其他网站 ...

  10. CTF SHOW WEB_AK赛

    CTF SHOW平台的WEB AK赛: 签到_观己 <?php ​ if(isset($_GET['file'])){ $file = $_GET['file']; if(preg_match( ...