zoukankan      html  css  js  c++  java
  • git操作之三:git reset

    在上篇文章中介绍了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间的修改均被保留,所有文件都在工作区,需重新被追踪;

    下面是三张示意图,

     

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

  • 相关阅读:
    imagemagick 批量旋转图片 转为横版式
    visual studio 2008 编译 filezilla
    BackgroundWorker 类
    序列化
    打工才是最愚蠢的投资
    常用汇编指令缩写(方便记忆)
    PIC中档单片机汇编指令详解(1)
    Win8之自动登录
    PIC单片机汇编指令
    好文转载—程序员的禅修之路
  • 原文地址:https://www.cnblogs.com/teach/p/14008485.html
Copyright © 2011-2022 走看看