為什么要先 git add 才能 git commit


1. git 的 add ,是一個容易引起疑問的命令。在 subversion 中的 svn add 動作是將某個文件加入版本控制,而 git add的意義完全不同。

同時, git diff --cached 是比較 stage 的文件的差異的,也是一個不直觀的命令。

github 2008年的blog中,也提到,容易引起混淆:



things like making use of the term ‘stage’ for things that happen in the index (such as using ‘git diff —staged’ instead of ‘git diff —cached’) is being worked on. I’m excited that staging files may soon be done via ‘git stage’ rather-than/in-addition-to ‘git add’. This is nice for new users who often have a hard time seeing why you have to keep ‘git add’ing to stage your changes.

事實上,在 git 的后續版本中,就做了兩個修改:
git stage 作為 git add 的一個同義詞
git diff --staged 作為 git diff --cached 的相同命令
為了容易理解,推薦大家使用 git stage 和 git diff --staged 這兩個命令,而git add 和 git diff --cached 這兩個命令,僅僅為了保持和以前的兼容做保留。

2. 增加 stage 的帶來的好處是什么?
主要有兩個好處,一個是分批、分階段遞交,一個是進行快照,便於回退
2.1 分批遞交,降低commit的顆粒度
比如,你修改了 a.py, b.py, c.py, d.py,其中 a.py 和 c.py 是一個功能相關修改,b.py,d.py屬於另外一個功能相關修改。那么你就可以采用:
git stage a.py c.py
git commit -m "function 1"
git stage b.py d.py
git commit -m "function 2"

2.2 分階段遞交
比如,你修改了文件 hello.py,修改了一些以后,做了 git stage heello.py動作,相當於對當前的hello.py 做了一個快照, 然后又做了一些修改,這時候,如果直接采用 git commit 遞交,則只會對第一次的快照進行遞交,當前內容還保存在 working 工作區。

當前的最新修改,則需要再做一次 git stage ,才能遞交。

這中間細微的差別,請參見:


由於git這個特性,需要注意到是,每次遞交之前,需要確認是否已經將相關的修改都stage 了,否則可能僅僅遞交了部分不完整的修改。
比如你修改了部分內容,進行了 stage,后來你又做了一些修改,然后就遞交,這時,后面的修改,並沒有遞交。

2.3 文件快照,便於回退
做了部分修改以后,進行 git stage,然后任何時刻,都可以回退到stage時的狀態:

git checkout -- hello.py

3. git diff , git diff --staged 和 git diff HEAD的差別

當一個文件做了stage,然后又做了一些修改,則:

git diff 顯示當前工作區的文件和stage區文件的差異

git diff --staged 顯示stage區和HEAD的文件的差異

git diff HEAD 顯示工作區和上次遞交文件的差異

具體參見 git help diff 的EXAMPLES部分。

使用 git status 可以看到,一個文件可能同時存在兩種差異。具體參見:


4. reset 和 checkout的區別
當文件加入了 stage 區以后,如果要從stage刪除,則使用 reset,此時工作區的文件不做任何修改,比如:
git reset hello.py
這個命令就是 git stage hello.py 的反操作。

當文件加入了 stage 區以后,后來又做了一些修改,這時發現后面的修改有問題,想回退到stage的狀態,使用 checkout 命令:
git checkout hello.py

5. 可以使用 git commit -a 命令,跳過 git stage 這個命令,直接遞交

6. 最佳實踐:
做了階段性修改,但是還不能做一次遞交,這時先 git stage 一下
如果有問題,可以隨時 checkout 回退
遞交之前,使用 git status,git diff HEAD 仔細查看是否需要的遞交
git commit -a ,保證遞交了所有內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM