第4章 add と commit
add はステージングへの送り込み
前章で触れたとおり、作業ツリーで編集しただけの状態では Git は何も記録してくれない。
「この変更を次のコミットに含めたい」とこちらから宣言する必要があり、そのコマンドが git add である。
# 特定ファイルだけステージング
git add README.md
# 複数ファイルまとめて
git add README.md src/main.py
# カレントディレクトリ以下の変更をすべて
git add .
# リポジトリ全体の変更をすべて (削除も含めて検出)
git add -A
. と -A の違い
似ているが意味は微妙に違う。覚えておくと事故が減る。
git add .: カレントディレクトリ以下の変更・新規ファイルを対象にするgit add -A(またはgit add --all): リポジトリ全体の変更・新規・削除を対象にする
削除したファイルも履歴に反映したいときは -A が安心。
大きめのプロジェクトで一部だけコミットしたいときは、ファイル名を明示するのが結局一番安全である。
ステージングに入れたつもりだったが気が変わった、という場合は git restore --staged <file> で作業ツリーに差し戻せる。
作業ツリーの編集そのものを破棄したいときは git restore <file>。どちらも直近の Git で推奨される形である。
commit でリポジトリに刻む
ステージングに集めた変更を、ひとつのコミットとして履歴に固定するのが git commit である。-m でメッセージをインラインに書ける。
git commit -m "初回コミット: プロジェクトの雛形を追加"
メッセージを省略すると $EDITOR (未設定なら vim) が開いて、じっくりメッセージを書くモードになる。複数行メッセージを書きたいときに便利である。
コミットメッセージのコツ
チーム開発を意識すると、メッセージの書き方はちょっと気を配る価値がある。よく言われる基本形はこんな感じ。
- 1 行目は 50 文字前後の要約 (何をどう変えたか)
- 2 行目は空行
- 3 行目以降に必要なら詳細説明 (なぜその変更をしたか)
「なにを」は差分を読めば分かる。コミットメッセージで本当に貴重なのは「なぜその変更が必要だったか」という文脈情報である。 半年後の自分はそれを一番ほしがる。
log で履歴を眺める
コミットが積み上がっていくと、どこで何をしたか見返したくなる。git log が基本の一歩目である。
git log
冗長に感じたら、1 行ずつ要約してくれる --oneline が便利。
git log --oneline
# => a4b5cfc diary: つむぎ日記 No.090 ...
# fa8ff67 README: トラブルシューティングの ...
# b82dbc0 README: トラブルシューティングに ...
先頭に出てくる 7 文字の英数字 (a4b5cfc のような) はコミットを一意に識別するハッシュの短縮形で、
git show a4b5cfc のように後続のコマンドで参照できる。
diff で差分を見る
コミットする前に「いま何を変えたんだっけ」と確認するのが git diff。デフォルトでは作業ツリーとステージングの差分を表示する。
# 作業ツリー vs ステージング
git diff
# ステージング vs 直近のコミット (次にコミットされる内容)
git diff --staged
# 特定コミットとの差分
git diff a4b5cfc
直前のコミットを直したい — --amend
コミットしてから「あ、このファイル入れ忘れた」「メッセージ誤字った」と気づく瞬間は必ず来る。
まだ push していないコミットに限り、--amend で直前のコミットを上書きできる。
# 入れ忘れたファイルをステージングに足してから
git add forgotten.txt
# 直前のコミットを差し替える (メッセージを維持)
git commit --amend --no-edit
# メッセージだけ直したい場合
git commit --amend -m "修正後のメッセージ"
--amend は既存のコミットを新しいコミットに置き換える操作。
一度 push 済みのコミットに対して amend すると履歴が書き換わり、他の人の手元とずれてしまう。
共有ブランチに push 済みのコミットを amend しないこと。
まとめ
git addで変更をステージングに送り込み、git commitでリポジトリに刻むgit add .とgit add -Aの違いは対象範囲と削除の扱い。迷うならファイル名明示- コミットメッセージは「なぜ」を残す。差分を読めば分かることをだらだら書かない
git log --onelineで履歴の俯瞰、git diffで差分の把握- 直前の未 push コミットの修正は
--amend。共有済みコミットには使わない