Git-管理和撤銷修改
一、管理修改
為什麼說Git管理的是修改,而不是檔案呢?我們還是做實驗。第一步,對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.
第二步,新增到暫存區:
➜ testcase git:(master) ✗ git add readme.txt ➜ testcase git:(master) ✗ git status On branch master Changes to be committed: (use"git reset HEAD <file>..." to unstage) modified: readme.txt
第三步,再修改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.
第四步,提交:
➜ testcase git:(master) ✗ git commit -m "git tracks changes" [master 170fed5] git tracks changes 1 file changed, 1 insertion(+)
第五步,檢視狀態:
➜ testcase git:(master) ✗ 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 add
-> 第二次修改 -> git commit
Git管理的是修改,當你用git add
命令後,在工作區的第一次修改被放入暫存區,準備提交。但是,在工作區的第二次修改並沒有放入暫存區,所以,git commit
只負責把暫存區的修改提交了,也就是第一次的修改被提交了,第二次的修改不會被提交。
第六步,提交後,用git diff HEAD -- readme.txt
命令可以檢視工作區和版本庫裡面最新版本的區別:
diff --git a/readme.txt b/readme.txt index 76d770f..a9c5755 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ 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. +Git tracks changes of files.
HEAD指向的是版本庫中的當前版本,而file指的是當前工作區中的檔案。
“+”代表工作區新增加的內容,“-”代表版本庫新增加的內容。
可見,第二次修改確實沒有被提交。
那怎麼提交第二次修改呢?可以繼續git add
再git commit
,也可以彆著急提交第一次修改,先git add
第二次修改,再git commit
,就相當於把兩次修改合併後一塊提交了:
第一次修改 -> git add
-> 第二次修改 -> git add
-> git commit
二、撤銷修改
第一步,對readme.txt檔案進行修改:
➜ testcase git:(master) ✗ 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.
在準備提交前,猛然發現了stupid boss
可能會丟掉這個月的獎金!
既然錯誤發現得很及時,就可以很容易地糾正它。可以刪掉最後一行,手動把檔案恢復到上一個版本的狀態。
第二步,先不手動刪掉最後一行,用git status
檢視一下:
➜ testcase git:(master) ✗ 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會告訴你,git checkout -- file
可以丟棄工作區的修改。
第三步:
➜ testcase git:(master) ✗ git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是,把readme.txt
檔案在工作區的修改全部撤銷,這裡有兩種情況:
一種是readme.txt
自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是readme.txt
已經新增到暫存區後,又作了修改,現在,撤銷修改就回到新增到暫存區後的狀態。
總之,就是讓這個檔案回到最近一次git commit
或git add
時的狀態。
現在,看看readme.txt
的檔案內容:
➜ testcase git:(master) 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.
從輸出結果,可以看出檔案內容復原了。
-------------------------------
另外一種情況,不旦寫了些錯誤的內容,還git add
到暫存區了:
➜ testcase git:(master) ✗ 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. A stupid boss.
➜ testcase git:(master) ✗ git add readme.txt
在commit
之前,發現了這個問題。用git status
檢視一下,修改只是新增到了暫存區,還沒有提交:
➜ testcase git:(master) ✗ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: readme.txt
Git同樣告訴我們,用命令git reset HEAD <file>
可以把暫存區的修改撤銷掉(unstage),重新放回工作區:
➜ testcase git:(master) ✗ git reset head readme.txt
Unstaged changes after reset:
M readme.txt
git reset
命令既可以回退版本,也可以把暫存區的修改回退到工作區。當我們用HEAD
時,表示最新的版本。
再用git status
檢視一下,現在暫存區是乾淨的,工作區有修改:
➜ testcase git:(master) ✗ 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")
還記得如何丟棄工作區的修改嗎?
➜ testcase git:(master) ✗ git checkout -- readme.txt
➜ testcase git:(master) git status
On branch master
nothing to commit, working directory clean
➜ testcase git:(master)
小結:
小結
場景1:當你改亂了工作區某個檔案的內容,想直接丟棄工作區的修改時,用命令git checkout -- file
。
場景2:當你不但改亂了工作區某個檔案的內容,還新增到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD <file>
,就回到了場景1,第二步按場景1操作。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠端庫。