4、撤消修改
我們編輯Hello.txt文件,添加一行新的內容后保存,這時我們發現最后一行的內容添加有誤,我們需要刪除它。這時我們可以選擇手工刪除剛才添加的最后一行,把文件恢復,我們也可以使用git status先查看狀態:
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")
你可能會發現,Git告訴你,git checkout –file可以刪除工作區的修改:
[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
最后我們總結一下:
一種是readme.txt自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是readme.txt已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態。最后要注意git checkout –file命令中的--,這個很重要,如果沒有—這個命令就是另外的作用了。我們在后面具體會何用。
現在我們把所有的修改都已經提交到了暫存區,還沒有commit,這個時候我們發現剛才的修改有錯誤,那么我們可以使用git reset HEAD file把暫存區的修改撤銷掉,重新放回工作區:
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,這個時候如果發現錯誤,想回退到剛才提交之前的版本該怎么處理?
首先我們通過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里面就只有當前提交之前的提交記錄。
Git的版本回退速度非常快,因為Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從指向當前的版本改為指向你要回退的版本,然后順便把工作區的文件更新。
小結:
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。
場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操作。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,使用git reset --hard commit-id回到指定的版本,不過前提是沒有推送到遠程庫。