それは git プロジェクトに別のリポジトリの特定コミットを示すポイントを埋め込むものです。
理屈の上では、「どのディレクトリに対して、どのリポジトリが関連付けられており、コミットオブジェクトのハッシュはこれです」っていう情報が管理されているだけのシンプルなもの。
以下のような構成のプロジェクトを簡単に管理できます。
root_project/
├── external_project
│ ├── library1(独立した git リポジトリ)
│ │ ├── lib
│ │ └── src
│ ├── library2(独立した git リポジトリ)
│ │ ├── lib
│ │ └── src
│ ├── library3(独立した git リポジトリ)
│ │ ├── lib
│ │ └── src
│ └── library4(独立した git リポジトリ)
│ ├── lib
│ └── src
└── main_project
├── lib
└── src
まずはリファレンスと関連する議論
http://qiita.com/sotarok/items/0d525e568a6088f6f6bb
http://tech.a-listers.jp/2013/05/17/alternatives-to-git-submodule-git-subtree/
ドキュメントは git submodule --help / man git-submodule
まず最初に確認するのはドキュメントの見方です。
$ man git-submodule
git submodule add で別の git リポジトリを追加できる
$ git submodule add "git:../library1.git" library1
これやった直後は .gitmodules
ってファイルができるだけだと思ってOK。
$ cat .gitmodules
[submodule "library1"]
path = library1
url = git:../library1.git
追加した後は、git submodule update --init
してあげること。(git submodule init
が必要というのが細かくハマりました。慣れればわかるんだけど…)
git submodule update --init --recursive で再帰的に更新する
サブモジュールもサブモジュールを持っている場合もあります。チェックアウト後とか pull 後、またはローバックした際に更新する際、再帰的に git submodule update したい場合があります。そんな時は update サブコマンドに --recursive
オプションを指定します。
# git pull -f
# git submodule update --init --recursive
Submodule path 'library1': checked out '587efa1a0328b5f5664eff2947ec6cb9f0cb8150'
Submodule path 'sublibrary': checked out 'e8245c89795619370537bfa149091e4dd1894ae7'
サブモジュールの示すリビジョンを変更する
サブモジュール内に入って git checkout
して、その後外側で git add
します。
理屈は簡単だけど、意外にめんどくさい。