本文演示了下列命令的常見使用方式:
git clean
git checkout
git reset
1. git clean
清除工作區(qū)所有未納入版本管理的目錄、文件党瓮。
git clean -f
:強制清除工作區(qū)根目錄下未納入版本管理的文件。
git clean -d -f
:強制清除未納入版本管理的目錄和文件姜挺,會從根目錄遞歸所有子目錄。
2. git checkout
git checkout <file>
:撤銷工作區(qū)指定文件的修改彼硫。用該文件暫存區(qū)的快照替換(如果該文件是untracked的炊豪,此命令不會處理)。
git checkout HEAD <file>
:撤銷指定文件在工作區(qū)和暫存區(qū)的所有修改拧篮,用版本庫最近一次提交的版本來替換词渤。
以gitsample的README.md文件為例。當前此文件的內容:
# gitsample
This line is the first time modified.
This line is the second time modified.
我們在文件中新加入一行文字串绩,內容變成:
# gitsample
This line is the first time modified.
This line is the second time modified.
demo for checkout file.
此時在Git bash命令行中使用git diff
比較下工作區(qū)和暫存區(qū)文件的差異:
$ git diff
diff --git a/README.md b/README.md
index 8d42e6b..cde90e6 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,6 @@
This line is the first time modified.
-This line is the second time modified.
\ No newline at end of file
+This line is the second time modified.
+
+demo for checkout.
\ No newline at end of file
接下來撤銷工作區(qū)的修改:
$ git checkout README.md
再來查看差異:
$ git diff
工作區(qū)和暫存區(qū)沒有差異了缺虐,README.md文件也變回最初的內容,剛才對工作區(qū)README.md文件的操作成功的被撤回了礁凡。
3. git reset
git reset HEAD [--] <paths>...
:撤銷指定路徑在暫存區(qū)的尚未提交到版本庫的內容高氮。如果指定的路徑從未提交到版本庫,那么就直接將該路徑從暫存區(qū)撤銷顷牌;否則會用該路徑在版本庫中最近一次的提交來覆蓋該路徑的暫存區(qū)剪芍。
git reset --soft [<commit>]
:撤銷版本庫到指定的commit id】呃叮可以用HEAD來代替commit id:HEAD^代表回撤最近一次的提交(和HEAD~1等效)罪裹,HEAD^^表示回撤最近兩次(和HEAD~2等效),以此類推;
git reset --mixed [<commit>]
:撤銷版本庫提交和暫存區(qū)到指定的commit id状共。--mixed是默認參數套耕,git reset --mixed HEAD^
和git reset HEAD^
等效;
git reset --hard [<commit>]
:撤銷版本庫峡继、暫存區(qū)和工作區(qū)到指定的commit id箍铲。注意:此命令會直接撤銷工作區(qū)的修改,這個操作是不可逆的鬓椭!使用之前最好用git status來比較下確認工作區(qū)的修改可以放棄颠猴。
我們先在gitsample倉庫中準備一下數據:
在文件夾內新建一個demo_reset.txt文件;
在文件內增加一行“Rev. 1”保存小染、在Git bash中運行git add .
翘瓮、git commit -m "demo reset Rev. 1"
將文件提交到版本庫;
在文件內增加一行“Rev. 2”保存裤翩、git add .
资盅、git commit -m "demo reset Rev. 2"
將文件提交到版本庫;
在文件內增加一行“Rev. 3”保存踊赠、git add .
呵扛、git commit -m "demo reset Rev. 3"
將文件提交到版本庫。
然后再文件內增加一行文字“Rev. 4”筐带、然后git add .
添加到暫存區(qū)今穿。此時使用git diff demo_reset.txt
查看狀態(tài):
$ git diff demo_reset.txt
從diff信息可以看到工作區(qū)的文件和暫存區(qū)的比較起來沒有不同。此時回撤暫存區(qū)的操作:
$ git reset HEAD demo_reset.txt
然后再執(zhí)行git diff
查看:
$ git diff demo_reset.txt
diff --git a/demo_reset.txt b/demo_reset.txt
index 9820ed9..22aeec4 100644
--- a/demo_reset.txt
+++ b/demo_reset.txt
@@ -1,3 +1,4 @@
Rev. 1
Rev. 2
-Rev. 3
\ No newline at end of file
+Rev. 3
+Rev. 4
\ No newline at end of file
從diff的結果來看暫存區(qū)的內容已經回撤了伦籍,和工作區(qū)的文件已經不一樣了蓝晒。
接下來通過練習看下下git reset --hard [<commit>]
的效果:
$ git reset --hard HEAD^
HEAD is now at 97bd7c9 demo reset Rev. 2
命令的返回信息提示版本庫已經回撤到“demo reset Rev. 2”這一次的提交了,看下git status的結果:
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
工作區(qū)和暫存區(qū)帖鸦、暫存區(qū)和版本庫都是一致的芝薇。說明暫存區(qū)和工作區(qū)的操作也都回撤了。用記事本打開文件會發(fā)現內容也只有Rev. 1和Rev. 2兩行了作儿。
接下來在Git bash中運行$ git reset --soft HEAD^
洛二,然后用git status
看下效果:
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: demo_reset.txt
可以看到,暫存區(qū)的demo_reset.txt有待提交的內容了攻锰。此時暫存區(qū)和工作區(qū)的文件內容都有Rev.1和Rev.2晾嘶,而版本庫已經回撤到Rev. 1這個版本了。如果現在又想將版本庫回到最初的提交(或者過程中的某次提交)口注,應該怎么辦呢变擒?還是使用reset命令,只要直到目的版本的commit id就能夠返回寝志〗堪撸可以通過git log --reflog -3
(只返回最近3次的提交操作)查看commit id:
$ git log --reflog -3 --pretty=oneline
df531846649c39baa68784ee40c907dd58e5c7da demo reset Rev. 3
97bd7c98ec0c0c8944dbd22c0711770564a7a762 demo reset Rev. 2
02e093b6513651c0e6e41d0710280a14e30b1d7c (HEAD -> master) demo reset Rev. 1
可以看到Rev. 3版本的commit id是df531846649c39baa68784ee40c907dd58e5c7da
〔咛恚現在將版本庫的提交返回到這里:
$ git reset --hard df5318
HEAD is now at df53184 demo reset Rev. 3
從返回的結果可以看到,版本庫的最近一次提交已經返回到Rev. 3了毫缆。
4. git commit --amend
有時候我們提交完了才發(fā)現有幾個文件應該一起提交但是忘記添加唯竹,或者有的文件不應該提交,又或者提交的信息寫的有問題苦丁。此時想修正這個問題浸颓,不想將原本應該在一起提交的變成兩次提交,可以使用git commit -amend
命令旺拉。
先要將需要一起提交的文件加入到暫存區(qū)产上,將不應該提交的文件撤回到原先的狀態(tài)。然后在Git bash中運行命令:
git commit --amend
命令運行后會啟動文本編輯器蛾狗,提示修改commit message:
demo reset Rev. 3
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Mon Aug 19 00:04:47 2019 +0800
#
# On branch master
# Your branch is ahead of 'origin/master' by 3 commits.
# (use "git push" to publish your local commits)
#
# Changes to be committed:
# modified: demo_reset.txt
#
將原來的message”demo reset Rev. 3“修改為“demo reset Rev. 3 --amend”晋涣。然后退出文本編輯器。
$ git commit --amend
hint: Waiting for your editor to close the file...
[main 2019-08-18T16:40:46.426Z] update#setState idle
[master ca497af] demo reset Rev. 3 --amend
Date: Mon Aug 19 00:04:47 2019 +0800
1 file changed, 2 insertions(+), 1 deletion(-)
從命令行返回結果可以看到沉桌,提交已經覆蓋谢鹊。我們再用git log --reflog
驗證下:
$ git log --reflog -3 --pretty=oneline
ca497afbba7b6eaefea0d96827875ddae4cb0791 (HEAD -> master) demo reset Rev. 3 --amend
df531846649c39baa68784ee40c907dd58e5c7da demo reset Rev. 3
97bd7c98ec0c0c8944dbd22c0711770564a7a762 demo reset Rev. 2
對比下之前的log:
$ git log --reflog -3 --pretty=oneline
df531846649c39baa68784ee40c907dd58e5c7da demo reset Rev. 3
97bd7c98ec0c0c8944dbd22c0711770564a7a762 demo reset Rev. 2
02e093b6513651c0e6e41d0710280a14e30b1d7c (HEAD -> master) demo reset Rev. 1
可以明顯的看到,git commit --amend
命令運行后留凭,并沒有新增一條提交操作佃扼,而是覆蓋了最近一次的提交:commit id和message都被替換了。
需要注意的是git commit --amend
命令會改變最近一次提交的commit id蔼夜,所以當最近一次的提價已經推送到遠程倉庫之后兼耀,要特別謹慎的使用這個命令,否則容易引起同其它開發(fā)人員的版本沖突挎扰。