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

下面是三張示意圖,

 

 

 

 

 

 

 

有不正之處,歡迎指正,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM