SYNOPSIS
.gitmodules, $GIT_DIR/config
git submodule
git <command> --recurse-submodules
DESCRIPTION
サブモジュール(submodule)は、別のリポジトリ内に埋め込まれたリポジトリです。サブモジュールにはサブモジュール独自の履歴があります。 それが埋め込まれているリポジトリはスーパープロジェクト(superproject)と呼ばれます。
ファイルシステムでは、サブモジュールは通常(常にではありませんが。以下のFORMSを参照)、(i)スーパープロジェクトの $GIT_DIR/modules/
ディレクトリの下にあるGitディレクトリや、(ii)スーパープロジェクトの作業ディレクトリ内の作業ディレクトリや、(i)の指すサブモジュールの作業ディレクトリのルートにある .git
ファイルで構成されます。
サブモジュールのGitディレクトリが $GIT_DIR/modules/foo/
にあり、作業ディレクトリが path/to/bar/
にあるとすると、スーパープロジェクトは、ツリーの path/to/bar
にある gitlink
エントリと、submodule.foo.path
=
path/to/bar
形式の .gitmodules
ファイル(linkgit: gitmodules[5] を参照)のエントリを介してサブモジュールを追跡します。
gitlink
エントリには、スーパープロジェクトがサブモジュールの作業ディレクトリにあると予想するコミットのオブジェクト名が含まれています。
.gitmodules
ファイルのセクション submodule.foo.
* は、Gitの磁器レイヤーに追加のヒントを提供します。 たとえば、 submodule.foo.url
設定は、サブモジュールを取得する場所を指定します。
サブモジュールは、少なくとも2つの異なるユースケースに使用できます:
-
独立した履歴を維持しながら別のプロジェクトを使用。サブモジュールを使用すると、両方のプロジェクトの履歴を分離したまま、あなた独自の作業ツリー内に別のプロジェクトの作業ツリーを含めることができます。また、サブモジュールは任意のバージョンに固定できるため、別のプロジェクトは、スーパープロジェクトに影響を与えることなく独立して開発でき、スーパープロジェクトプロジェクトが必要とした場合にのみ別プロジェクトを新しいバージョンに固定できます。
-
(論理的に単一の)プロジェクトを複数のリポジトリに分割し、それらを結び付けます。これを使用して、Gitの実装の現在の制限を克服し、よりきめ細かいアクセスを実現できます:
- Gitリポジトリのサイズ
-
現在の形式では、 Gitは、ツリー間のデルタ計算によって圧縮されていないコンテンツを含む大規模なリポジトリではスケールアップが十分にできません。 たとえば、あなたはサブモジュールを使用して大きなバイナリアセットを保持し、 これらのリポジトリを浅く複製して、 ローカルに大きな履歴がないようにすることができます。
- 転送サイズ
-
現在の形式では、Gitは作業ツリー全体が存在する必要があります。 部分的なツリーをフェッチまたはクローンで転送することはできません。 あなたが作業しているプロジェクトが、 スーパープロジェクトのサブモジュールとして結合された複数のリポジトリで構成されている場合は、 関心のないリポジトリの作業ツリーをフェッチすることを回避できます。
- アクセス制御
-
サブモジュールへのユーザーアクセスを制限することにより、 さまざまなユーザーの読み取り/書き込みポリシーを実装できます。
The configuration of submodules
サブモジュール操作は、以下のメカニズムを使用して構成(configure)できます(優先順位の高い順です):
-
The command line for those commands that support taking submodules as part of their pathspecs. Most commands have a boolean flag
--recurse-submodules
which specifies whether to recurse into submodules. Examples aregrep
andcheckout
. Some commands take enums, such asfetch
andpush
, where you can specify how submodules are affected. -
サブモジュール内の構成。 これには、サブモジュール内の
$GIT_DIR/config
だけでなく、サブモジュール内のコマンドの動作を指定する.gitattributes
または.gitignore
ファイルなどのツリー内の設定も含まれます。たとえば、スーパープロジェクトで
git
status
--ignore-submodules=none
を実行すると、サブモジュールの.gitignore
ファイルの効果が確認できます。これは、サブモジュールの.gitignore
ファイルに注意を払いながらサブモジュールでstatus
を実行することにより、サブモジュールの作業ディレクトリから情報を収集します。サブモジュールの
$GIT_DIR/config
ファイルは、スーパープロジェクトでgit
push
--recurse-submodules=check
を実行すると機能します。これは、サブモジュールにリモートに公開されていない変更があるかどうかをチェックするためです。リモートは、通常どおりサブモジュールの$GIT_DIR/config
ファイルで構成されます。 -
スーパープロジェクトの構成ファイル
$GIT_DIR/config
。Gitはアクティブなサブモジュールのみ再帰します(以下の「ACTIVE SUBMODULES」セクションを参照)。サブモジュールがまだ初期化されていない場合、サブモジュール内の構成(configuration)はまだ存在しないため、たとえば、サブモジュールを取得する場所はここで構成されます。
-
スーパープロジェクト内の
.gitmodules
ファイル。プロジェクトは通常、このファイルを使用して、サブモジュールの名前とパスの間に必要なマッピングについて、上流のリポジトリコレクションのデフォルトを提案します。このファイルは主に、スーパープロジェクト内のサブモジュールの名前とパスの間のマッピングとして機能し、サブモジュールのGitディレクトリを見つけることができます。
サブモジュールが初期化されていない場合、これはサブモジュール構成が見つかる唯一の場所です。 これは、サブモジュールを取得する場所を指定するための最後のフォールバックとして機能します。
FORMS
サブモジュールは以下の形式をとることができます:
DESCRIPTIONで説明されている、Gitディレクトリと、作業ディレクトリと、 gitlink
と、 `.gitmodules`エントリ、を含む基本形式。
「古い形式」のサブモジュール: .git
ディレクトリが埋め込まれた作業ディレクトリと、スーパープロジェクトの gitlink
および .gitmodules
エントリの追跡。 これは通常、古いバージョンのGitを使用して生成されたリポジトリにあります。
+ これらの古い形式のリポジトリを手動で構築することは可能です。
+
非初期化(deinitialized)または削除されると(以下を参照)、サブモジュールのGitディレクトリはスーパープロジェクトの $GIT_DIR/modules/
<name>/
に自動的に移動されます。
非初期化された(deinitialized)サブモジュール: gitlink
と .gitmodules
エントリがありますが、サブモジュールの作業ディレクトリはありません。サブモジュールのGitディレクトリは、Gitディレクトリを初期化解除した後も保持されているため、そこにある可能性があります。 代わりに、作業ディレクトリであるはずのディレクトリが空になります。
+
サブモジュールは、 git
submodule
deinit
を実行することで非初期化(deinitialized)できます。このコマンドは、作業ディレクトリを空にするだけでなく、スーパープロジェクトの $GIT_DIR/config
ファイルのみを変更するため、スーパープロジェクトの履歴は影響を受けません。 これは、 git
submodule
init
を使用して元に戻すことができます。
Deleted submodule: A submodule can be deleted by running git
rm
<submodule-path> && git
commit
. This can be undone using git
revert
.
+
削除すると、スーパープロジェクトの追跡データが削除されます。これは、 gitlink
エントリと .gitmodules
ファイルのセクションの両方です。サブモジュールの作業ディレクトリはファイルシステムから削除されますが、Gitディレクトリは、別のリポジトリからフェッチすることなく過去のコミットをチェックアウトできるようにするために保持されます。
+
サブモジュールを完全に削除するには、手動で $GIT_DIR/modules/
<name>/
を削除します。
ACTIVE SUBMODULES
サブモジュールがアクティブと見なされるには、
-
if
submodule.
<name>.active
がtrue
に設定されているor
-
if サブモジュールのパスが
submodule.active
のパススペックと一致するor
-
if
submodule.
<name>.url
が設定されている
これらは上記の順序で評価されます。
例:
[submodule "foo"]
active = false
url = https://example.org/foo
[submodule "bar"]
active = true
url = https://example.org/bar
[submodule "baz"]
url = https://example.org/baz
In the above config only the submodules bar and baz are active, bar due to (1) and baz due to (3). foo is inactive because (1) takes precedence over (3)
上記(1)と(2)でサブモジュールがアクティブでないことを指定している場合は、(3)は歴史的遺物であり、無視されることに注意してください。 つまり、 submodule.
<name>.active
が false
に設定されている場合、またはサブモジュールのパスが submodule.active
のパススペックで除外されている場合、URLは存在するかどうかは関係ありません。これを以下の例に示します。
[submodule "foo"]
active = true
url = https://example.org/foo
[submodule "bar"]
url = https://example.org/bar
[submodule "baz"]
url = https://example.org/baz
[submodule "bob"]
ignore = true
[submodule]
active = b*
active = :(exclude) baz
ここでは、 baz を除くすべてのサブモジュール(foo、bar、bob)がアクティブになっています。 foo はそれ自体のアクティブフラグによるものであり、他のすべては submodule active パススペック によるものです。これは、 .url フィールドの存在に関係なく、baz を除く b
で始まるすべてのサブモジュールもアクティブであることを指定します。
Workflow for a third party library
# サブモジュールの追加
git submodule add <URL> <path>
# Occasionally update the submodule to a new version:
git -C <path> checkout <new-version>
git add <path>
git commit -m "update submodule to new version"
# スーパープロジェクト内でサブモジュールのリストを表示します
git submodule status
# サブモジュールの削除については、「FORMS」を参照してください
Workflow for an artificially split repo
# 関連するコマンドの再帰(recursion)を有効にし、
# 対象のコマンドがデフォルトでサブモジュールで再帰処理するようにします
git config --global submodule.recurse true
# 他のほとんどのコマンドとは異なり、
# cloneには独自の再帰フラグが必要です:
git clone --recurse <URL> <directory>
cd <directory>
# (ソース)コードを知る為に取得する
git grep foo
git ls-files --recurse-submodules
Note
|
git ls-files もまた、それ独自の --recurse-submodules フラグが必要です。 |
# 新しいコードを得る
git fetch
git pull --rebase
# 作業ツリーの変更
git checkout
git reset
Implementation details
When cloning or pulling a repository containing submodules the submodules will not be checked out by default; you can instruct clone
to recurse into submodules. The init
and update
subcommands of git
submodule
will maintain submodules checked out and at an appropriate revision in your working tree. Alternatively you can set submodule.recurse
to have checkout
recurse into submodules (note that submodule.recurse
also affects other Git commands, see git-config(1) for a complete list).
SEE ALSO
GIT
Part of the git(1) suite