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つの異なるユースケースに使用できます:

  1. 独立した履歴を維持しながら別のプロジェクトを使用。サブモジュールを使用すると、両方のプロジェクトの履歴を分離したまま、あなた独自の作業ツリー内に別のプロジェクトの作業ツリーを含めることができます。また、サブモジュールは任意のバージョンに固定できるため、別のプロジェクトは、スーパープロジェクトに影響を与えることなく独立して開発でき、スーパープロジェクトプロジェクトが必要とした場合にのみ別プロジェクトを新しいバージョンに固定できます。

  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 are grep and checkout. Some commands take enums, such as fetch and push, 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

サブモジュールがアクティブと見なされるには、

  1. if submodule.<name>.activetrue に設定されている

    or

  2. if サブモジュールのパスが submodule.active のパススペックと一致する

    or

  3. 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>.activefalse に設定されている場合、またはサブモジュールのパスが 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