git reset hardsoftmixed區別

根據–soft –mixed –hard,會對working tree和index和HEAD進行重置:

git reset ——mixed:此為預設方式,不帶任何引數的git reset,即時這種方式,它回退到某個版本, 只保留原始碼,回退commit和index資訊

git reset ——soft:回退到某個版本, 只回退了commit的資訊,不會恢復到index file一級。如果還要提交,直接commit即可

git reset ——hard:徹底回退到某個版本,本地的原始碼也會變為上一個版本的內容,此命令 慎用!

git reset 命令是git中最常用的命令,但也是最危險,最容易被誤用的命令。

一、master 分支

我們知道git在初始化時,會為我們預設建立一個master分支,那這個master到底是什麼呢?其實它在。git目錄下對應了一個引用檔案——-。git/refs/heads/master檔案,而該檔案的內容便是該分支中最新的一次提交的ID:

1

2

3

4

5

6

7

8

9

10

11

12

$ cat 。git /refs/heads/master

22f8aae534916e1174711f138573acfbb47e489c

$ git cat - file -t 22f8aae

commit

$ git log ——oneline

22f8aae git ignore file added。

4e79a0b Rename third to third。txt

46ae7e3 remove branch_first。txt file from master branch

55d1e70 branch first file

545a382 Merge commit ‘35bbd32’

當我們用以上檢視master檔案內容時,發現它果然記錄了最新一次的提交。瞭解了這個前提,那我們來分析下git reset到底做了什麼?

回到頂部

二、reset命令

以上面的例子為基礎我們來探討reset命令的魔力,首先我們來執行一個reset命令,reset到上一次提交

1

2

3

4

5

6

7

8

9

$ git reset ——hard HEAD^

HEAD is now at 4e79a0b Rename third to third。txt

Quadrangle@QUADRANGLE-PC /d/GitRepo/GitOne (master)

$ git log ——oneline

4e79a0b Rename third to third。txt

46ae7e3 remove branch_first。txt file from master branch

55d1e70 branch first file

545a382 Merge commit ‘35bbd32’

HEAD^的意思就是最新一次提交的父提交,reset後,我們看一下提交日誌,發現最新一次提交沒了。到底git做了什麼呢?我們還能找回最新的一次提交嗎?

回答上面兩個問題,就用到上面就到的master引用檔案了,這是我們再看一下這個檔案的內容有什麼變化?

1

2

$ cat 。git /refs/heads/master

4e79a0ba92f1ae63dc661e29343fa0c369ca480d

發現了吧,裡面記錄了reset後的最後一次提交。這時或許我們有所覺察了。先不急著下結論,我們看怎麼回到最新的提交呢?其實reset後,git沒有刪除最新提交的相關資訊,包括目錄樹,因此只要我們記住提交ID,便可以重新reset回來:

1

2

3

4

5

6

7

8

9

$ git reset ——hard 22f8aae

HEAD is now at 22f8aae git ignore file added。

$ git log ——oneline

22f8aae git ignore file added。

4e79a0b Rename third to third。txt

46ae7e3 remove branch_first。txt file from master branch

55d1e70 branch first file

545a382 Merge commit ‘35bbd32’

這樣檢視log,發現最新提交又回來了。但是如果我們忘了最新提交ID 怎麼辦呢?好辦,reflog命令可以最總引用變更的記錄:

1

2

3

4

5

6

Quadrangle@QUADRANGLE-PC /d/GitRepo/GitOne (master)

$ git reflog

22f8aae HEAD@{0}: reset: moving to 22f8aae

4e79a0b HEAD@{1}: reset: moving to HEAD^

22f8aae HEAD@{2}: reset: moving to 22f8aae

4e79a0b HEAD@{3}: reset: moving to HEAD^

我們可以找到前面任意操作的記錄,並且可以reset到任意提交。

回到頂部

三、揭秘

之前我們看到了reset後master檔案的內容發生了變化,其實這就是reset命令的本質,但結合不同的引數,會有額外的工作:如——hard ——soft ——mixed等,他們決定了是否重置暫存區或工作區。

我們來看下面圖片

git reset hard/soft/mixed區別

其實reset命令有兩種用法:

git reset [-q] [commit] [——]

git reset [——soft | ——mixed | ——hard | ——merge | ——keep] [-q] [

第一種用法是不會重置引用的,即不會修改master檔案。只是用某一次提交的檔案提交暫存區的檔案

第二種用法不使用 則會重置引用,並且引數不同決定是否覆蓋暫存區和工作區:

——hard引數會執行途中1,2,3 全部動作,即暫存區,工作區全部用指定提交版本的目錄樹替換掉

——soft 引數只執行1, 不進行暫存區和工作區的覆蓋

——mixed或不使用引數,執行1,2覆蓋暫存區,但不覆蓋工作區