自然,你是不會犯錯的。不過現(xiàn)在是凌晨兩點,你正在趕一份工作報告,你在 readme.txt 中添加了一行:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN.
在你準備提交前,一杯咖啡起了作用,你猛然發(fā)現(xiàn)了“stupid boss”可能會讓你丟掉這個月的獎金!
既然錯誤發(fā)現(xiàn)得很及時,就可以很容易地糾正它。你可以刪掉最后一行,手動把文件恢復(fù)到上一個版本的狀態(tài)。如果用git status
查看一下:
$ 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")
你可以發(fā)現(xiàn),Git 會告訴你,git checkout -- file
可以丟棄工作區(qū)的修改:
$ git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是,把 readme.txt 文件在工作區(qū)的修改全部撤銷,這里有兩種情況:
一種是 readme.txt 自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫一模一樣的狀態(tài);
總之,就是讓這個文件回到最近一次git commit
或git add
時的狀態(tài)。
現(xiàn)在,看看 readme.txt 的文件內(nèi)容:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
文件內(nèi)容果然復(fù)原了。
git checkout -- file
命令中的--很重要,沒有--,就變成了“創(chuàng)建一個新分支”的命令,我們在后面的分支管理中會再次遇到git checkout
命令。
http://wiki.jikexueyuan.com/project/git-tutorial/images/discard-changes-of-working-dir.gif" alt="" />
現(xiàn)在假定是凌晨 3 點,你不但寫了一些胡話,還git add
到暫存區(qū)了:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN.
$ git add readme.txt
慶幸的是,在 commit 之前,你發(fā)現(xiàn)了這個問題。用git status
查看一下,修改只是添加到了暫存區(qū),還沒有提交:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
Git 同樣告訴我們,用命令git reset HEAD file
可以把暫存區(qū)的修改撤銷掉(unstage),重新放回工作區(qū):
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
git reset 命令既可以回退版本,也可以把暫存區(qū)的修改回退到工作區(qū)。當我們用 HEAD 時,表示最新的版本。
再用git status
查看一下,現(xiàn)在暫存區(qū)是干凈的,工作區(qū)有修改:
$ 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")
還記得如何丟棄工作區(qū)的修改嗎?
$ git checkout -- readme.txt
$ git status
# On branch master
nothing to commit (working directory clean)
整個世界終于清靜了!
http://wiki.jikexueyuan.com/project/git-tutorial/images/discard-changes-of-staged.gif" alt="" />
現(xiàn)在,假設(shè)你不但改錯了東西,還從暫存區(qū)提交到了版本庫,怎么辦呢?還記得版本回退一節(jié)嗎?可以回退到上一個版本。不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠程。還記得 Git 是分布式版本控制系統(tǒng)嗎?我們后面會講到遠程版本庫,一旦你把“stupid boss”提交推送到遠程版本庫,你就真的慘了……
又到了小結(jié)時間。
場景1:當你改亂了工作區(qū)某個文件的內(nèi)容,想直接丟棄工作區(qū)的修改時,用命令git checkout -- file
。
場景2:當你不但改亂了工作區(qū)某個文件的內(nèi)容,還添加到了暫存區(qū)時,想丟棄修改,分兩步,第一步用命令git reset HEAD file
,就回到了場景 1,第二步按場景 1 操作。
場景3:已經(jīng)提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節(jié),不過前提是沒有推送到遠程庫。