git commit
git commit
コマンドはプロジェクトで現在ステージされている変更のスナップショットをキャプチャします。コミット済みのスナップショットはプロジェクトの "安全" なバージョンだと考えることができます。Git では明示的に指示されない限りこれらのスナップショットを変更することはありません。git commit
を実行する前に、git add
を使ってコミットに保存されるプロジェクトに変更をプロモート、または「ステージ」します。git commit
と git add
の 2 つは最も使用頻度が高いコマンドです。
Git コミットと SVN コミット
どちらにも「コミット」が付いていながら、git commit
と svn commit
はまったくの別物です。svn を使ったことのある Git 初心者にとっては「コミット」という単語が混乱の元になります。ではそれぞれの違いを詳しく見ていくことが重要です。git commit
と svn commit
を比較するということは、集中型アプリケーションモデル (svn) と分散型アプリケーションモデル (Git) を比較するということです。SVN では、コミットによってローカルの SVN クライアントからリモートの集中型共有 SVN リポジトリに変更がプッシュされます。Git ではリポジトリが分散されており、スナップショットはローカルリポジトリにコミットされるため、他の Git リポジトリを操作する必要はまったくありません。Git のコミットはその後、任意のリモートリポジトリにプッシュすることができます。
仕組み
より俯瞰的に見ると、Git はタイムライン管理ユーティリティだと捉えることもできます。コミットは Git プロジェクトのタイムラインの中核を成す構成要素です。コミットは Git プロジェクトのタイムライン上のスナップショットまたはマイルストーンだと考えることもできます。git commit
コマンドでコミットを作成して、その時点のプロジェクトの状態をキャプチャします。Git スナップショットは常にローカルリポジトリにコミットされます。これが SVN とは根本的に異なる点です。SVN では作業コピーが中央のリポジトリにコミットされます。対照的に、Git では準備が整うまで中央のリポジトリを操作する必要はありません。ステージングエリアが作業ディレクトリとプロジェクト履歴のバッファーになっており、各開発者のローカルリポジトリが作業結果と中央のリポジトリのバッファーになっているのです。
このことは Git ユーザーの開発基本モデルに大きな変化を生じます。Git を利用する開発者は、変更を直接中央リポジトリにコミットするのではなく、ローカルリポジトリにコミットを蓄積することができます。これには、フィーチャーを小規模なコミットに分割することが可能、関連性の強いコミットをグループ化したまま維持可能、中央リポジトリに公開する前にローカルリポジトリの整理が可能など、SVN 型のコラボレーションと比較して数多くの利点があります。これにより、開発者は独立した環境で作業することができるようになり、他のユーザーとマージできる適切な区切りまで作業が到達するまで他との統合を先延ばしにすることができます。チームにとっては頻繁に更新して小さなユニットにしておくのが得策であるため、独立した環境と統合の先延ばしにはそれぞれ固有のメリットがあります。Git のチームコラボレーションに関するベストプラクティスの詳細については、チームが Git workflow を構築する方法を参照してください。
差分ではなくスナップショットを保存
SVN と Git の間には実践的な相違がありますが、加えて基本構造もまったく異なる設計思想に基づいています。SVN ではファイルの差分を追跡するのに対し、Git のバージョン管理モデルはスナップショットに基づいています。例えば、SVN のコミットはリポジトリに存在する元のファイルとの差分で構成されます。それに対し、Git ではコミットのたびにそれぞれのファイルの内容すべてを記録します。
これにより、あるリビジョンのファイルを再現する際に差分データから「組み立てる」必要がなく、それぞれのファイルのあらゆるリビジョンが Git の内部データベースから即時取得できるため、Git におけるほとんどの操作は SVN と比較してはるかに高速に動作します。
Git で採用されているスナップショットモデルは、ブランチツールやマージツールからコラボレーションワークフローにいたるまで、そのバージョン管理モデルのあらゆる面に広範な影響を及ぼしています。
よく使われるオプション
git commit
ステージされたスナップショットをコミットするコマンドです。このコマンドを実行するとテキストエディターが起動され、コミットメッセージの入力を求められます。メッセージの入力後、ファイルを保存してエディターを終了するとコミットが実行されます。
git commit -a
作業ディレクトリにおけるすべての変更のスナップショットをコミットします。これには追跡対象ファイル (過去に git add
コマンドによって履歴に追加されたことのあるファイル) の修正のみが含まれます。
git commit -m "commit message"
渡されたコミットメッセージを使ってコミットを即座に作成するショートカットコマンドです。デフォルトでは、git commit
はローカルで設定されたテキストエディターを起動して、コミットメッセージの入力が求められます。-m
オプションを渡すと、テキストエディターは起動せずにインラインメッセージを表示します。
git commit -am "commit message"
-a
オプションと -m
を組み合わせたパワーユーザー用のショートカットコマンドです。この組み合わせではステージされたすべての変更のコミットを作成し、インラインコミットメッセージを取得します。
git commit --amend
このオプションを使うことで、コミットコマンドに新たな機能が加わります。このオプションを渡すと、直前のコミットが修正されます。新しいコミットを作成する代わりに、ステージした変更が直前のコミットに追加されます。このコマンドではシステムで設定されたテキストエディターが起動して、直前に指定したコミットメッセージを変更するよう求められます。
例
コミットを使って変更を保存する
以下の例では、現在のブランチにある hello.py
という名称のファイルの内容を編集し、それをプロジェクト履歴にコミットする準備が整っていると仮定します。最初に git add
コマンドを使用してそのファイルをステージし、次にステージされたスナップショットをコミットします。
git add hello.py
このコマンドは hello.py
を Git ステージングエリアに追加します。git status
コマンドを使うとこの操作の結果を調べることができます。
git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) new file: hello.py
緑の出力「new file: hello.py
」は、後続のコミットで hello.py
が保存されたことを示しています。コミットを作成するには次を実行します。
git commit
このコマンドを実行するとテキストエディター (git config
コマンドを使用して任意のエディターを指定できます) が起動され、コミットされる内容の一覧を表示すると共にコミットログメッセージの入力を求められます:
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # #modified: hello.py
Git ではコミットメッセージの形式に関して制約はありませんが、1 行目にコミットの全体的説明を 50 字以内で記述し、2行目は空白行とし、3行目以降に変更内容の詳細を記述するのが標準的な形式です。以下はその例です:
Change the message displayed by hello.py
- Update the sayHello() function to output the user's name - Change the sayGoodbye() function to a friendlier message
メールと同じように、コミットメッセージの先頭行をタイトルとして使うのが一般的です。ログメッセージの残りの部分は本文で、コミットのチェンジセットを説明するために使用します。多くの開発者はコミットメッセージで現在形を使うのを好みます。これによって、メッセージがリポジトリの操作のようになるため、履歴の書き換え操作の多くがより直感的になります。
コミットの更新 (修正) 方法
上の hello.py
のサンプルを引き続き使って、hello.py
をさらに更新して以下を実行しましょう。
git add hello.py git commit --amend
このコマンドでも設定済みのテキストエディターが開きます。ただ、今回は前に入力したコミットメッセージがあらかじめ入力されています。つまり、新しいコミットを作成するのではなく、前回のものを編集するのです。
概要
git commit
コマンドは Git の中核を成す機能の 1 つです。後続のコミットにステージする変更を選ぶには事前に git add
コマンドを使っておく必要があります。その後、git commit
を使って Git プロジェクト履歴のタイムラインに沿ってステージされた変更のスナップショットを作成します。git add
の詳しい使い方については、関連するページを参照してください。git status
コマンドはステージングエリアと保留中のコミットの状態を調べるのに使うことができます。
SVN と Git のコミットモデルには大きな違いがありますが、どちらも同じ用語を使っているため混同されることがよくあります。SVN で個人履歴を使っていた状態から Git を使い始めた場合、Git ではコミットのコストが低くて頻繁に使われることを覚えておくと良いでしょう。SVN のコミットはコストがかかり、リモートリクエストが発生しますが、Git のコミットはローカルで実行されて、効率的なアルゴリズムを採用しています。