よく整ったコミットの作成には必要不可欠な「git add」でも、よく使うけど、実は実際の仕様をよく分からないままの方も多いのではないでしょうか?この記事では、そのコマンド仕様とオプションを含めて、まとめていきます。
git add コマンドの概要
git add は、作業ツリーにあるファイルの更新内容を、インデックスに反映するための Git コマンドです。インデックスに追加された変更内容は、次の「git commit」を実行した際に、そのコミットに含まれる事になります。
実際の Git 利用に置いては、作業ツリー内のすべてのファイルに発生した変更を、一度にまとめてインデックスに反映してしまう事も多いですが、コマンド実行時に、引数に特定のファイルパスを指定したり、一部のファイルのみをステージして、次回のコミットに含まれる変更内容を整える事ができます。
通常は、文字通りインデックスに「add(追加)」するために使うコマンドではあるものの、作業ツリー内のファイルの「削除」をインデックスに反映することもあります。
「インデックス」の実体
インデックスは実際はバイナリで、通常「.git/index」のファイル名で保存されています。また、インデックスは別の呼び方で「ステージ」と呼ばれています。また、インデックス領域に変更を追加することをステージング(Staging)呼びます。一方で、現場では「add する」などと呼ぶことも多いと思います。
git add コマンドの使い方
変更をインデックスにステージする
もっとも基本的なコマンドが、ファイルを指定することによるインデックスへの追加です。ファイル個別に指定することもできますし、「.(ドット)」利用して現在のディレクトリ配下のすべてのファイルを追加することができます。
// 任意のファイルの変更をステージする
$ git add <file>
// 現在のディレクトリのファイルすべてをステージする
$ git add .
変更を一括でまとめてインデックスにステージする
git add の「一括ステージ」に関するオプションは複数存在するため、しばしば仕様が混乱します。
もっとも範囲が広いのは「-A」オプションですが、「作業ツリーのディレクトリルートで「git add . 」を実行すれば、ほぼ同義となるケースが多いでしょう。入力し易い「.(ドット)」をよく使う方も多いと思います。
// 作業ツリーのファイルすべてをステージする
$ git add .
// Git 管理対象のファイルの変更、削除をすべてステージする。(新規ファイルは無視。)
$ git add -u
$ git add --update
// および作業ツリーのファイルをすべてステージする
// 引数なしで、すべての作業ツリーのファイルを反映。
$ git add --all
$ git add -A
その他の git add の主要なオプション
.gitignore 指定も無視。強制的に追加「-f, --force」
.gitignore に書かれているファイルを「git add <file>」と実行してもgit add する事はできませんが、このfオプションを使えば、強制的にadd する事ができます。
対話式「 -i, --interactive」
インデックス領域を整えるための操作を、対話式に選択しながら、インデックスを調整できます。ちょっとむずかしいので、あまり使う機会はありません・・。
$ git add -i
// 出力
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> 1
変更の塊ごとに、レビューして追加を決める「-p, --patch」
これは便利なオプションです。
通常、git add はステージする変更をファイル単位で指定しますが、-p オプションを利用すれば、ファイル内の変更行の塊( hunk と呼ばれます)を一つ一つレビューしながら、インデックスに追加することができます。この操作は、インタラクティブモードにおける「patch」操作と同様です。
実際の開発ではよくありますが、1つのファイル内に複数の目的の変更を加えてしまった時、このオプションを利用して、必要な変更内容のみを抜き出し、コミットにまとめてしまいます。「1つのコミットは1つ目的の下に作る」を実現するためには、非常の重要なオプションです。
なお、対話の最中に「?」を指示するとコマンドのヘルプが表示されます。
y - stage this hunk // このhunkをステージする
n - do not stage this hunk // このhunk はステージしない
q - quit; do not stage this hunk or any of the remaining ones // これ移行の hunk をステージしない
a - stage this hunk and all later hunks in the file // これ移行すべてをステージ
d - do not stage this hunk or any of the later hunks in the file // このファイルのhunk はこれ移行すべてステージ
g - select a hunk to go to // 指定した hunk に移動
/ - search for a hunk matching the given regex // マッチするhunkを検索
j - leave this hunk undecided, see next undecided hunk // いったんスキップ。次の未解決のhunkを表示
J - leave this hunk undecided, see next hunk // いったんスキップ。次のhunkを表示
k - leave this hunk undecided, see previous undecided hunk // いったんスキップ。前の未解決のhunkに戻る
K - leave this hunk undecided, see previous hunk // いったんスキップ。前のhunkを表示
s - split the current hunk into smaller hunks // hunkを細かく分解する
e - manually edit the current hunk // hunkを手動で編集する
? - print help // ヘルプ表示
追加したファイルを出力する「-v, --verbose」
追加したファイルについて、出力します。「git add .」のように、ディレクトリを指定した場合、どのようなファイルがadd されたかを確認するのに便利です。
あとで、git status する必要がありません。
// 実行の例 $ git add -v . // ファイルが出力される add 'includes/functions.php' add 'includes/class-xxxxx.php' add 'includes/class-yyyy.php' remove 'includes/class-zzzz.php' modify 'includes/posts.php'
git add に関連するコマンド
ステージされたした変更を確認する「git status」
インデックスの作業状態は、git status コマンドで確認します。作業ツリーの変更、インデックスの変更があったファイルをそれぞれ表示してくれます。
// 作業ツリーとインデックスの変更を確認する
$ git status
インデックスの差分を確認する「git diff --cached」
また、どのような変更がステージされているかを詳しく確認したい場合、git diff を利用します。「git diff 」はインデックスからみた作業ツリーの変更を表示し、また「git diff --cached」は、HEADからみたインデックスの変更を表示します。
// インデックス ⇨ 作業ツリー の変更を確認する
$ git diff
// HEAD ⇨ インデックス の変更を表示する
$ git diff --cahced
$ git diff --cached HEAD // 同義
インデックス上の変更をコミットする「git commit」
インデックス上にステージされた変更でコミットを作成する時は、引数なしの git commit を使います。
// インデックス上の変更をコミットする
$ git commit
ステージ済みの変更内容を取り消す「git reset」
git add によりインデックスにステージした変更を、取り消します。ファイルを指定してもファイル単体でリセットしても構いませんし、引数なしでは、HEADの状態に一括で戻す事ができます。
// すべてリセット
$ git reset
$ git reset HEAD // 同義
// ファイル指定してリセット
$ git reset file-to-reset.php
$ git reset HEAD file-to-reset.php // 同義
ファイルパス引数ありの git reset のイメージです。
こちらもぜひご一読下さい。git reset の具体的な動作仕様を詳しくまとめました。
参考情報
git add を理解するには、今回ご紹介したようなgit reset や、git commit の仕様も理解しておくと、コミットの作成を自在にコントロールできるでしょう。こちらに、git commit もまとめています。
git reset の仕様も、以外に理解している方は少ないはずです。
こちらは、Git 公式ドキュメントです。
それでは、快適なGit ライフを。