新學git,對git的reset操作總是怕狼怕虎的,這樣是不對的,對於任何新鮮事物都要大膽去嘗試。看幾篇博客,看幾頁圖書然後死記概念,永遠也不能完全理解其中的道理。廢話不多說,直接上貨。
先看實例
mkdir git-reset
cd git-reset
git init
開始做幾次提交
echo "Hello, git rest" > readme.txt
git add .
git commit -m 'first commit'
echo "new line" >> readme.txt
git add .
git commit -m 'second commit'
echo "third line" >> readme.txt
git add .
git commit -m 'third commit'
看下提交log
git log --graph --oneline
1. 33be59b third commit
2. ab56d39 second commit
3. c773001 first commit
當前提交的readme
cat readme.txt
Hello, git reset
a new line
the third line
- 首先來看第一種reset模式, mixed,即其默認的模式。結果如下。
git reset HEAD^
Unstaged changes after reset:
M readme.txt
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
git log --graph --oneline
* ab56d39 second commit
* c773001 first commit
看出什麼了嗎,git將提交回滾到了second commit, 同時清空了暫存區(也稱stage或index,下文用stage代替暫存區),但是工作區仍然保留,所以git status時,顯示時當前工作區相對於second commit的變動。使用這種模式不用害怕吧,他並不會清除你的工作區,你在third commit做的任何操作都不會消失。
2. 看另一種方式,soft模式
git reset --soft HEAD^
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
看到了吧,採用這種模式,git不回清除你的stage區,因此,git status時就顯示了stage區相對於second commit的變化。此時工作區是clean 的,而stage區則有變化。
3. 第三種方式 hard
git reset --hard HEAD^
HEAD is now at ab56d39 second commit
git st
On branch master
nothing to commit, working directory clean
cat readme.txt
Hello, git reset
a new line
這時工作區,stage區都是乾淨的,然而readme.txt則殘忍的回到了第二次提交是的狀態。這說明了啥,採用這種模式,git回用second commit 的內容覆蓋stage區和工作區,因此所有的內容都回到了second commit的狀態。
實例做完了,開始總結吧
git reset –soft 不會改變stage區,僅僅將commit回退到了指定的提交
git reset –mixed 不回改變工作區,但是會用指定的commit覆蓋stage 區,之前所有暫存的內容都變爲爲暫存的狀態
git reset –hard 使用指定的commit的內容覆蓋stage區和工作區。
總有後悔藥,git reset 是git給我們的commit層級的回滾方式。