1. 程式人生 > >Git-管理和撤銷修改

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 addgit 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 commitgit 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:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠端庫。