git addのあとに編集した分は、通常のgit commitには自動で入らない
作業ツリー・ステージ・HEADを分けて考える。git addはその時点の内容をステージへ反映し、通常のgit commitはステージの内容を記録する。
用語
- 作業ツリー
- チェックアウトされ、手元で編集しているファイル群。
- ステージ
- 次のコミットに記録するために選んだ内容。Gitではインデックスとも呼ぶ。
- HEAD
- 通常は現在チェックアウトしているコミットを示す参照。
図と例
HEADの内容:A → 編集してgit add:ステージはB → 再編集して保存:作業ツリーはC → 追加操作なしのgit commit:Bを記録
操作例:a.txtをAからBへ編集してgit add a.txt。その後BからCへ保存しても追加し直さなければ、引数なしのgit commitに入るのはB。git diffにはB→C、git diff --stagedにはA→Bが出る。Cを含めたいなら、その変更もステージへ反映する。
実際のサービス・製品では
解説
修正とテストをコミットへまとめるときに使う。テストが通った作業ツリーと、記録する差分が一致するかを確認する。関係ない変更が同じファイルにあるなら、git add -pで必要な部分を選べる。
ファイルを保存しただけでは、次のコミットに入る内容は変わらない。作業ツリーは編集中のファイル、ステージ(インデックス)は次のコミット用に選んだ内容、HEADは通常は現在のコミットを指す。git addのあとで同じファイルを直すと、ステージ済みと未ステージの変更が両方ある状態になる。git diffは作業ツリーとステージ、git diff --stagedはステージとHEADの差を見る。git statusと両方の差分を確認して、意図した部分を追加し直す。ここでの説明は引数なしのgit commitが対象で、git commit -aなどはステージへ反映する動作が加わる。
トレードオフ
- ファイル全体をgit addする
- 得るもの:関連する変更をまとめて選べる
- 払うもの:同じファイルに混じった無関係な編集も入る
- git add -pで部分的に選ぶ
- 得るもの:同じファイルの変更を目的ごとに分けられる
- 払うもの:選んだ組み合わせだけでも整合するか確認が必要
さらに学ぶ
チェック
HEADはA。Bへ編集してgit addしたあと、Cへ再編集して保存した。追加操作なしのgit commitが記録する内容は?
- B
- C
- A
解答と解説
B
ステージにあるBが記録される。Cは作業ツリーに保存されただけで、まだステージへ反映されていない。Aは前のコミットの内容であり、今回はBをステージ済み。