http://git-scm.com/book/en/Git-Tools-Submodulesから編集
このシナリオでは、共通の問題が発生します。つまり、各プロジェクトを個別のプロジェクトとして扱いながら、一方を他方から使用できるようにしたいということです。ライブラリを含めることの問題は、ライブラリをカスタマイズするのが難しく、多くの場合、すべてのクライアントがそのライブラリを利用できるようにする必要があるため、ライブラリを展開するのがより難しいことです。コードを独自のプロジェクトにベンダー化する際の問題は、上流の変更が利用可能になったときに、行ったカスタム変更をマージするのが難しいことです。Git は、サブモジュールを使用してこの問題に対処します。サブモジュールを使用すると、Git リポジトリを別の Git リポジトリのサブディレクトリとして保持できます。これにより、別のリポジトリをプロジェクトに複製し、コミットを分離しておくことができます。
最初にすべきことは、外部リポジトリをサブディレクトリにクローンすることです。次のコマンドを使用して、外部プロジェクトをサブモジュールとして追加します。
git submodule add
そのサブディレクトリに移動し、変更を加え、独自の書き込み可能なリモート リポジトリを追加して変更をプッシュし、元のリポジトリから取得してマージすることができます。サブモジュールを追加した直後に git status を実行すると、次の 2 つのことがわかります。
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: .gitmodules
# new file: <name_of_cloned_repo>
#
まず、.gitmodules ファイルに注目してください。これは、プロジェクトの URL とプロジェクトをプルしたローカル サブディレクトリとの間のマッピングを格納する構成ファイルです。
$ cat .gitmodules
[submodule "rack"]
path = rack
url = git://github.com/chneukirchen/rack.git
は作業ディレクトリのサブディレクトリですが、Git はそれをサブモジュールと見なし、そのディレクトリにいない場合はその内容を追跡しません。代わりに、Git はそれをそのリポジトリからの特定のコミットとして記録します。そのサブディレクトリに変更を加えてコミットすると、スーパープロジェクトはそこの HEAD が変更されたことを認識し、現在作業中の正確なコミットを記録します。そうすれば、他の人がこのプロジェクトを複製するときに、環境を正確に再作成できます。
これはサブモジュールの重要なポイントです。サブモジュールが現在のコミットとまったく同じように記録します。マスターまたはその他のシンボリック参照でサブモジュールを記録することはできません。
ディレクトリを別のプロジェクトとして扱い、そのサブプロジェクトの最新のコミットへのポインターを使用して、スーパープロジェクトを時々更新できます。すべての Git コマンドは、2 つのディレクトリで独立して動作します...