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

    下面是三张示意图,

     

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

  • 相关阅读:
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    72. Edit Distance
    583. Delete Operation for Two Strings
    582. Kill Process
    indexDB基本用法
    浏览器的渲染原理
    js实现txt/excel文件下载
    git 常用命令
    nginx进入 配置目录时
  • 原文地址:https://www.cnblogs.com/teach/p/14008485.html
Copyright © 2011-2022 走看看