4、撤消修改
我們編輯Hello.txt文件,添加一行新的內(nèi)容后保存,這時(shí)我們發(fā)現(xiàn)最后一行的內(nèi)容添加有誤,我們需要?jiǎng)h除它。這時(shí)我們可以選擇手工刪除剛才添加的最后一行,把文件恢復(fù),我們也可以使用git status先查看狀態(tài):
Hello world
first modify
second modify
three modify
four modify
[root@node1 git-test]# echo "five modify" >>Hello.txt
[root@node1 git-test]# cat Hello.txt
Hello world
first modify
second modify
three modify
four modify
five modify
[root@node1 git-test]# 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: Hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
你可能會(huì)發(fā)現(xiàn),Git告訴你,git checkout –file可以刪除工作區(qū)的修改:
[root@node1 git-test]# git checkout -- Hello.txt
[root@node1 git-test]# git status
On branch master
nothing to commit, working tree clean
You have new mail in /var/spool/mail/root
[root@node1 git-test]# cat Hello.txt
Hello world
first modify
second modify
three modify
four modify
我們再看另一種情況,
[root@node1 git-test]# echo "five modify" >>Hello.txt
[root@node1 git-test]# git add Hello.txt
[root@node1 git-test]# git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Hello.txt
[root@node1 git-test]# echo "six modify" >>Hello.txt
[root@node1 git-test]# git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Hello.txt
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: Hello.txt
[root@node1 git-test]# git checkout -- Hello.txt
[root@node1 git-test]# git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Hello.txt
[root@node1 git-test]# cat Hello.txt
Hello world
first modify
second modify
three modify
four modify
five modify
最后我們總結(jié)一下:
一種是readme.txt自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫一模一樣的狀態(tài);
一種是readme.txt已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)。
總之,就是讓這個(gè)文件回到最近一次git commit或git add時(shí)的狀態(tài)。最后要注意git checkout –file命令中的--,這個(gè)很重要,如果沒有—這個(gè)命令就是另外的作用了。我們在后面具體會(huì)何用。
現(xiàn)在我們把所有的修改都已經(jīng)提交到了暫存區(qū),還沒有commit,這個(gè)時(shí)候我們發(fā)現(xiàn)剛才的修改有錯(cuò)誤,那么我們可以使用git reset HEAD file把暫存區(qū)的修改撤銷掉,重新放回工作區(qū):
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Hello.txt
You have new mail in /var/spool/mail/root
[root@node1 git-test]# git reset HEAD Hello.txt
Unstaged changes after reset:
M Hello.txt
[root@node1 git-test]# 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: Hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
[root@node1 git-test]#
我們將所有的修改都commit,這個(gè)時(shí)候如果發(fā)現(xiàn)錯(cuò)誤,想回退到剛才提交之前的版本該怎么處理?
首先我們通過git log命令查看我們的提交歷史:
6cfd50cb9f0edec3fc59dd59845b4c6e3b5ec22a git reset HEAD test
8d9eb9afd8c38821cc84ffe47fe2261386f48a4f aaa
6597abf6bb3617c2cbaad12cf1749d9771464ecd git mv test
2b1583efcc6e18d0f80946f88d416b140b01367a delete Hello.txt
9ccca93a00bd91a4883595b2f44a416ffb5ede9e mv test
3a2db18768b228b3af6fa878e36544d15e35cfa4 rm test finish
a80c6a946c0968edcbe3b9826629112b147a84e2 rm test
4794019de33bc2bfcea823ded27f80e98230e114 jump git add submit
b79795b531900217191da0db8b36ee220c074ad4 tree submit
a306d944c27e569f8003a82f7e251159cb61db33 second submit
5e874cc11b31065c65d4fd4ed7e6a275dca524d5 first submit
我們使用git reset –hard b7979回到第三次提交的版本:
[root@node1 git-test]# git reset --hard b79795
[root@node1 git-test]# git log --pretty=oneline
b79795b531900217191da0db8b36ee220c074ad4 tree submit
a306d944c27e569f8003a82f7e251159cb61db33 second submit
5e874cc11b31065c65d4fd4ed7e6a275dca524d5 first submit
[root@node1 git-test]# cat README
My first git test project
first modify
second modify
three modify
我們可以使用git reset –hard commit-id返回指定的版本,但是返回后git log里面就只有當(dāng)前提交之前的提交記錄。
Git的版本回退速度非常快,因?yàn)镚it在內(nèi)部有個(gè)指向當(dāng)前版本的HEAD指針,當(dāng)你回退版本的時(shí)候,Git僅僅是把HEAD從指向當(dāng)前的版本改為指向你要回退的版本,然后順便把工作區(qū)的文件更新。
小結(jié):
場景1:當(dāng)你改亂了工作區(qū)某個(gè)文件的內(nèi)容,想直接丟棄工作區(qū)的修改時(shí),用命令git checkout -- file。
場景2:當(dāng)你不但改亂了工作區(qū)某個(gè)文件的內(nèi)容,還添加到了暫存區(qū)時(shí),想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操作。
場景3:已經(jīng)提交了不合適的修改到版本庫時(shí),想要撤銷本次提交,使用git reset --hard commit-id回到指定的版本,不過前提是沒有推送到遠(yuǎn)程庫。