大家好,今天我们来聊聊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继承的两道实验题目

    设计一个表示二维平面上点的类Point,包含有表示坐标位置的Protect类型的成员变量 获取和设置x和y值的public方法 package classwork_6; public class Po ...

  2. mysql建表和建数据库语句

    一.数据库操作语言 数据库在操作时,需要使用专门的数据库操作规则和语法,这个语法就是 SQL(Structured Query Language) 结构化查询语言. SQL 的主要功能是和数据库建立连 ...

  3. kali putty远程连接允许以root身份登录

    原文链接:https://blog.csdn.net/long_long_chuang/article/details/70227874 kali linux通过ssh+putty来实现远程登录(亲测 ...

  4. BYTE WORD DWORD

    在Visual C++ 6.0中,BYTE与WORD,DWORD本质上都是一种无符号整型,它们在WINDEF.H中被定义,定义如下:typedef unsigned char       BYTE;t ...

  5. 网络拓扑实例09:VRRP组网下同网段内配置基于全局地址池的DHCP服务器

    组网图形 DHCP服务器简介 见前面DHCP服务器文章,不再赘述. 组网需求 如图1所示,某企业内的一台主机通过Switch双归属到SwitchA和SwitchB,SwitchA为主设备,作为DHCP ...

  6. 关于esp8266的SDK开发串口打印mismatch map 3,spi_size_map 6 system_partition_table_regist fail解决办法

    最近在学习esp8266 用的sdk开发,烧录碰到个问题,本人使用的esp8266模块是esp8266-12f,模块是4M的也就是32Mbit 参考了网上的很多办法,大部分写的不清楚也没解决,摸索了几 ...

  7. C#设计模式-组合模式(Composite Pattern)

    概念 组合是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们. 组合模式(Composite Pattern)是将对象组合成树形结构以表示'部分-整体'的层次 ...

  8. TextClip构造方法报OSError:MoviePy creation of None failed because of the following [WinError 2]系统找不到指定的文件

    ☞ ░ 前往老猿Python博文目录 ░ 在使用moviepy的构造方法创建实例时报错: "C:\Program Files\Python37\python.exe" F:/stu ...

  9. 第15.32节 PyQt(Python+Qt)入门学习:containers容器类部件QToolBox工具箱介绍及使用案例

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  10. 第11.26节 Python正则表达式运算符优先级

    正则表达式从左到右进行计算,并遵循优先级顺序,相关运算符的优先级顺序按下表从高到低排列. 例如:字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或 ...