在上篇文章中介绍了git restore命令,该命令的可以看作是撤销命令,文件在不同的状态下,使用git restore <file> 命令,会撤销对文件的修改,是文件回到修改前的状态也就是暂存区或者本地代码区,而使用git restore --staged <file>命令,则是使文件从暂存区回到工作区,且保留文件的修改。那么如果使文件从本地代码区移除那,或者说如何撤销已commit的文件那。

一、概述

通过前边的介绍,了解到使用git commit -m "提交说明" <file>可以把文件提交到本地代码库,如果是误提交,要把提交的文件撤回要使用git reset 命令。

二、详述

命令格式如下,

git reset [--hard | --mixed | --soft] HEAD^

git reset --hard

命令如下,

git reset --hard HEAD^/git reset --hard HEAD~1 其中HEAD^指的是后退一次提交,同理HEAD^^后退两次提交;HEAD~1 后退一次提交,HEAD~2 后退两次提交;

现在看下我的提交记录,

那么现在我执行下git reset --hard HEAD^命令,再看提交记录

从上图可以看到提交记录回到了上个版本,那么此刻文件的内容也发生变化。

现在又这样一种情况,如果在MyFirst.java、MyFirst2.java均提交的情况下,修改MyFirst.java、MyFirst2.java,然后把MyFirst2.java执行git add命令后再执行git reset --hard HEAD^命令后两个文件会发生什么变化,

现在两个文件的内容如下,

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a"); } }
package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) {
System.out.println("b");
}
}

再看下现在git的状态,

现在对MyFirst.java进行修改,但不执行git add 命令

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a");
System.out.println("修改未追踪"); } }

对MyFirst2.java,执行git add命令

package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) {
System.out.println("b");
System.out.println("修改且追踪");
}
}

现在看下git的状态,

现在执行git reset --hard HEAD~1命令,两个文件的内容如下,

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a");
System.out.println("提交后修改"); } }
package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) { }
}

对比下上面的文件,发现和上边的修改后的也不一样,这说明,git reset --hard HEAD~1 命令会回退到上个版本,中间做的修改会被撤销,包括在工作区中的修改和已放入暂存区的修改都会被撤销。

git reset --soft

现在看下git的状态,

可以看到没有待提交的文件也就是没有在暂存区的文件,现在修改MyFirst.java、修改MyFirst2.java并加入到暂存区,看下当前的状态,

可以看到MyFirst2.java在暂存区中等待commit,而MyFirst.java在工作区中未被追踪,看下两个文件的内容,

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a");
System.out.println("提交后修改");
System.out.println("MyFirst,2020-11-22");
System.out.println("MyFirst,2020-11-22-2"); } }
package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) {
System.out.println("MyFirst2,2020-11-22");
System.out.println("MyFirst2,2020-11-22-2");
}
}

下面执行git reset --soft HEAD~1命令,并查看git的状态,

可以看到在暂存区有MyFirst.java、MyFirst2.java两个文件,在工作区有MyFirst.java,在工作区有MyFirst.java可以理解,因为该文件被修改过未执行git add命令,回退和这个没关系。那么为什么MyFirst.java还会出现在暂存区那,因为git reset --soft HEAD~1命令,该命令会让版本回退一个版本,且在工作区和暂存区的文件不会发生改变,但是会把回退前的版本和回退后版本的差异放到暂存区,那么就好理解了,从MyFirst2.java说起,在回退前该文件做了修改并提交到了暂存区,回退后肯定也在暂存区,MyFirst.java在回退前进行了修改,但是没有保存到暂存区,在回退后,MyFirst.java回退到了上个版本,回退前和回退后会两个版本会有差异,这个差异在回退后被放到了暂存区,所以在暂存区肯定会出现MyFirst.java,为什么会有未追踪的MyFirst.java,因为回退前对其进行了修改未追踪该文件。

git reset --mixed/git reset

下面看最后一个参数--mixed或者说默认的参数

演示环境仍是下面的环境,对MyFirst.java进行修改且不追踪,对MyFirst2.java进行修改且添加到暂存区,

文件的内容如下,

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a");
System.out.println("提交后修改");
System.out.println("MyFirst,2020-11-22");
System.out.println("MyFirst,2020-11-22-2");
System.out.println("MyFirst,2020-11-22-3"); } }
package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) {
System.out.println("MyFirst2,2020-11-22");
System.out.println("MyFirst2,2020-11-22-2");
System.out.println("MyFirst2,2020-11-22-3");
}
}

下面执行git reset --mixed HEAD~1/git reset HEAD~1,查看git的状态

可以看到MyFirst.java和MyFirst2.java均未追踪,再看下文件的内容,

package cn.com.my;

public class MyFirst {
public static void main(String[] args) {
System.out.println("a");
System.out.println("提交后修改");
System.out.println("MyFirst,2020-11-22");
System.out.println("MyFirst,2020-11-22-2");
System.out.println("MyFirst,2020-11-22-3"); } }
package cn.com.my;

public class MyFirst2 {
public static void main(String[] args) {
System.out.println("MyFirst2,2020-11-22");
System.out.println("MyFirst2,2020-11-22-2");
System.out.println("MyFirst2,2020-11-22-3");
}
}

可以看到文件的内容和执行git reset HEAD~1前没有改变,git reset HEAD~1命令不会改变文件的内容,但在reset前所做的修改在reset后都会反应在工作区,具体表现未MyFirst2.java在reset前在暂存区,但reset后在工作区。

三、总结

git reset [--hard | --soft | --mixed] HEAD^命令总结如下,

git reset --hard HEAD^  会撤销版本V-1到版本V间的修改,直接回退到版本V-1,无论所做的修改是否被追踪;

git reset --soft HEAD^  在版本V-1到版本V间的修改均被保留,如一个文件已提交到暂存区,在回退后仍在暂存区;如一个文件在工作区,在回退后该文件修改前的内容在暂存区,修改后的内容仍在工作区;这时如果执行git commit -m <file> 命令,在暂存区的都会被commit(包括在后退前追踪的暂存区的内容);

git reset --mixed HEAD^ 在版本V-1到版本V间的修改均被保留,所有文件都在工作区,需重新被追踪;

下面是三张示意图,

有不正之处,欢迎指正,谢谢!

git操作之三:git reset的更多相关文章

  1. AS中Git操作和Git工作流

    查阅并学习安卓中如何使用Git,并扩展学了下Gitflow工作流程,以下是我觉得有用,系统,详细的相关文章. AS中Git操作系列 https://www.jianshu.com/p/0cc226ee ...

  2. git操作之git clean删除一些没有git add的文件

    删除 一些 没有 git add 的 文件: git clean 参数 -n 显示 将要 删除的 文件 和  目录 -f 删除 文件,-df 删除 文件 和 目录

  3. git 操作实践

    git操作: - git是一个用于帮助用户实现版本控制的软件 #首先创建项目 1. cd到项目文件目录 2. 鼠标右键点击 Git Bash Here 3. git init #在项目文件目录生成 . ...

  4. git操作

    svn终结,git时代来临 git是最好的分布式版本控制系统 廖雪峰的git讲的蛮不错,http://www.liaoxuefeng.com/wiki/0013739516305929606dd183 ...

  5. 代码回滚:git reset、git checkout和git revert区别和联系

    git reset.git checkout和git revert是你的Git工具箱中最有用的一些命令.它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于提交,还可以作用于特定文件. 因为 ...

  6. git操作笔记

    首先本文参考廖雪峰的git学习教程,写的非常好,值得学习. http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b80 ...

  7. 关于git 操作

    一. Git 命令初识 在正式介绍Git命令之前,先介绍一下Git 的基本命令和操作,对Git命令有一个总体的认识 示例:从Git 版本库的初始化,通常有两种方式: 1)git clone:这是一种较 ...

  8. Git详解之三 Git分支

    相关文档 — 更多 Git 基础培训.ppt GIT 使用经验.ppt GIT 介绍.pptx GIT 分支管理是一门艺术.docx Eclipse上GIT插件EGIT使用手册.docx git/gi ...

  9. 2015年12月02日 GitHub入门学习(四)Git操作

    序,学习使用Git是一项新技能,你将了解到Git与SubVersion的区别. 一.基本操作 git init 初始化仓库,请实际建立一个目录并初始化仓库,.git目录里存储着管理当前目录内容所需的仓 ...

随机推荐

  1. echo 输出颜色

    shell脚本里使用echo输出颜色       echo命令颜色显示: echo:      -n:  不换行.      -e:让转移符生效. \t(tab) \n (换行) 实例: $ echo ...

  2. printStackTrace()造成的并发瓶颈

    一 背景 在一次活动前的压测中,发现一个服务(平响为250ms左右)存在并发瓶颈,单实例的QPS压力从20升高到40后服务就雪崩了(平响急剧升高). 通过<jstack -F>命令查看线程 ...

  3. Linux 打开core dump功能

    系统打开core dump功能 在终端中输入命令 ulimit -c ,输出的结果为 0,说明默认是关闭 core dump 的,即当程序异常终止时,也不会生成 core dump 文件: 使用命令  ...

  4. day75:luffy:路飞学城项目后端环境搭建&Git相关知识点

    目录 1.Xadmin 1.Xadmin介绍 2.Xadmin安装 3.Xadmin的使用 2.项目环境搭建 1.外部依赖 2.依赖包安装 3.搭建项目 3.Git 4.日志配置 5.异常处理 6.创 ...

  5. golang开发:http请求redirect的问题

    这两天在开发项目的时候遇到了一个问题,请求了一个URL,它会302到另一个地址,本意上只是想检查这个URL是否会做3XX的redirect跳转,结果每次reqeust都会返回最后一跳的结果.后来就看了 ...

  6. B. Two Fairs 解析(思維、DFS、組合)

    Codeforce 1276 B. Two Fairs 解析(思維.DFS.組合) 今天我們來看看CF1276B 題目連結 題目 給一個連通圖,並給兩個點(\(a,b\)),求有多少點對使得:任一路徑 ...

  7. JUC---12深入理解CAS

    一.什么是CAS Compare and Swap, 翻译成比较并交换,是java.util.concurrent.atomic包下的类里面的CompareAndSet()方法:java.util.c ...

  8. 手写Express.js源码

    上一篇文章我们讲了怎么用Node.js原生API来写一个web服务器,虽然代码比较丑,但是基本功能还是有的.但是一般我们不会直接用原生API来写,而是借助框架来做,比如本文要讲的Express.通过上 ...

  9. NB-IOT关键技术分析

    NB-IOT(NarrowBand Internet of Things,窄带IoT)是一种基于蜂窝的窄带物联网技术,支持低功耗设备在广域网的蜂窝数据连接.NB-IOT在物联网应用广泛,许多领域都充分 ...

  10. Java学习的第十一天

    1. 方法递归 2.this()不理解和类型传递不太理解 3.明天学习完第四章