【Git】git submodule updateとは?初心者向けにやさしく使い方を解説

Web開発

はじめに

Gitで複数のプロジェクトを管理していると、同じコードを何度もコピーして再利用するのが面倒だと感じることはないでしょうか。
そこで役立つのが、サブモジュールという仕組みです。
Gitリポジトリの中に、別のGitリポジトリを組み込むことでコードの使い回しがしやすくなります。
ただし、サブモジュールを導入すると「更新のしかたが難しそう」という印象を持つ人も多いかもしれません。

このとき活躍するのが git submodule update というコマンドです。
サブモジュールとして組み込まれた外部リポジトリを最新状態にそろえたい場合や、別の作業環境でクローンしてきた直後に、サブモジュールを手軽に取り込みたい場合にも重宝します。
本記事では、サブモジュールの概要から、具体的にgit submodule updateコマンドを使う際の流れや注意点までを、なるべく初心者の方にもわかりやすく解説します。

この記事を読むとわかること

  • git submodule update の概要と役割
  • サブモジュールをプロジェクトに導入する流れ
  • 実務で役立つ具体的な運用方法と注意点
  • 初心者の方がつまずきやすいポイントの対処法

これらを踏まえて、自分のプロジェクトでサブモジュールを安心して使えるようになることを目指します。

git submoduleとは?

Gitには、リポジトリの中に別のGitリポジトリを埋め込む機能があります。
これをサブモジュールと呼びます。
共通で使われるライブラリや、複数のプロジェクト間で参照したい共通コードがある場合に便利です。

例えば、複数のアプリケーションで同じUIコンポーネントを共有したい場面を考えてみましょう。
それぞれのアプリケーションのリポジトリに同じコードをコピーすると、バグ修正や機能追加のタイミングで全プロジェクトを修正しないといけません。
一方、サブモジュールにすることで、共通のライブラリを一括管理できるため保守が容易になります。

サブモジュールを利用すると、メインリポジトリは「サブモジュールをどのコミットに固定するか」の情報を記録するようになります。
これは、特定のバージョンを保持したまま開発できる点でメリットが大きいです。
ただし、サブモジュール自体にも複数のブランチやタグが存在するため、管理が複雑になる場合があります。

git submodule updateが必要となるシーン

サブモジュールは、メインリポジトリと同様に独立して更新作業が行われます。
例えば、サブモジュールとして組み込んだリポジトリに新しいコミットが追加されたとき、メインリポジトリの中身を最新にしたい場合が出てきます。
こうしたときにgit submodule updateでサブモジュールの内容を反映させます。

実務でよくあるシーンとしては、以下のような状況が挙げられます。

  • チームメンバーがサブモジュール側のコードを更新した
  • 別PCや別環境でリポジトリをクローンし、サブモジュールの内容を取得したい
  • 新しい機能がサブモジュールに追加されたので、それをメインプロジェクトに反映したい

git pull などでメインリポジトリを取得しても、サブモジュール内部の変更は自動的には取り込まれません。
そこで、git submodule updateを使うことで、サブモジュールの実際のファイル内容を最新のコミットにそろえるのです。

git submodule updateの基本的な使い方

git submoduleを扱う場合、大まかな流れは次のようになります。

  1. サブモジュールをメインリポジトリに追加する
  2. サブモジュールを初期化して、関連情報を設定する
  3. サブモジュールを更新して、最新の状態を反映する

ここでは、主に更新部分に焦点を当てますが、初期化の手順もあわせて確認してみましょう。

サブモジュールの初期化と取得

メインリポジトリにサブモジュールを導入した場合、リポジトリをクローンした直後はサブモジュールのファイルが空状態で配置されることがあります。
この状態では、サブモジュール内部にどんなコードが入っているのか、まだ分かりません。
そこで行うのが git submodule initgit submodule update というコマンドです。

git submodule init
git submodule update

git submodule init

サブモジュールの設定ファイルを読み込み、メインリポジトリに含まれるサブモジュールの情報をGitが把握できるようにします。

git submodule update

サブモジュールの実体を取得し、メインリポジトリが指し示すコミットの内容をローカル環境にダウンロードします。

初期化から更新までをあわせて実行したい場合は、以下のように1行でまとめることも可能です。

git submodule update --init

このコマンドを打てば、サブモジュールが初期化されていない場合はinitが走り、そのままupdateまで行います。
環境によっては、一度で済むほうが手間が省けるかもしれませんね。

実際に更新する手順

サブモジュールがすでに導入済みであり、メインリポジトリを取得したあとに「サブモジュールの内容を最新化したい」という場合は、あらためて git submodule update を使います。
単に git pull しただけでは、サブモジュールの実体までは更新されません。

たとえば、チームメンバーがサブモジュール側で新しいコミットをPushしてくれた場合を考えてみましょう。
最新コミットを取り込むには、以下の流れがよく使われます。

1. メインリポジトリのブランチを最新化する:

git pull origin main

2. サブモジュールを更新する:

git submodule update

こうすることで、メインリポジトリが参照しているコミットにそろえてサブモジュールの内容が手元に展開されます。
サブモジュール自体を「最新ブランチを追いかけたい」という場合は、もうひと工夫が必要です。
その場合は次の「--remoteオプション」などを考慮するとよいでしょう。

よくある疑問

git submodule initとupdateの違い

git submodule init は、サブモジュールを使う準備をするコマンドです。
メインリポジトリ内に設定されているサブモジュールの情報を.git/configなどに登録し、サブモジュールを追跡できる状態にします。

一方、git submodule update は、サブモジュールの実体をローカルに取得・更新するためのコマンドです。
サブモジュールで指定されているコミットの内容を、実際にローカルディスク上に展開します。
イメージとしては「準備(init)した後、実際にファイルを取りに行く(update)」という流れです。

--remoteオプションでできること

サブモジュールを「メインリポジトリが参照している特定のコミット」ではなく、「サブモジュールのリモートブランチにある最新コミット」にあわせて取得したい場合があります。
そういうときに使えるのが、git submodule update --remote です。

git submodule update --remote --merge

上記のように指定すると、サブモジュールのリモートリポジトリにある最新コミットを取得し、現在のブランチへマージする動作が行われます。
ただし、サブモジュールの参照を常に最新にするかどうかは運用ポリシー次第です。
実務上は、特定のバージョンに固定したいケースも多いため、--remoteを使う場合はチーム内でルールを決めておくと混乱が減るでしょう。

実務で活かすポイント

サブモジュールを実務で使う場合、いくつかのポイントを押さえるとスムーズです。
特に、複数人で開発しているとサブモジュールの更新タイミングがわかりにくくなるので、事前に運用ルールを決めておくことが多いです。

1. サブモジュールのバージョン管理ルールを決める

常に最新コミットを追いかけるのか、それとも特定のコミットをメインリポジトリで固定するのかを明確にします。
統一ルールがないと、誰かが間違えて勝手に最新バージョンを指してしまうことがあるかもしれません。

2. サブモジュール更新時のコミットメッセージに注意する

サブモジュールの更新を反映すると、メインリポジトリでも「サブモジュールの参照が変わった」ことをコミットする必要が出てきます。
その際、どのコミットを参照するように変更したのかを分かりやすく記載すると、後で追跡しやすくなります。

3. サブモジュールの開発と利用を分ける

サブモジュールに含まれるコードの開発をメインリポジトリで同時進行すると、混乱しやすいです。
サブモジュールのリポジトリをしっかり分けて管理し、必要に応じて更新版をメインリポジトリに取り込む流れを定着させましょう。

サブモジュールを運用するチームでは、レビューのルールやコミットポリシーなどを決めておくと、作業がスムーズになりやすいです。

注意点とトラブルシューティング

サブモジュールを使ううえでは、いくつかの落とし穴があります。
以下のような点に気をつけることで、トラブルを回避できます。

1. 参照コミットが存在しないエラー

メインリポジトリが指しているサブモジュールのコミットが、リモートで削除されてしまったケースです。
削除したブランチやコミットをどのように扱うか、事前にチームで相談しておくと安心です。

2. 更新漏れ

サブモジュール側で修正が行われたのに、メインリポジトリの参照が古いまま放置される場合があります。
その結果、想定外の古いコードを使い続けてしまうリスクがあります。
定期的にサブモジュールのブランチ状況を確認し、必要があればupdateしておきましょう。

3. サブモジュールのコミット忘れ

サブモジュールの中を修正したのに、サブモジュールのリポジトリにコミットやPushをし忘れてしまうケースもあります。
メインリポジトリから見ると「参照しているコミットは更新されているのに、実際にはファイルがない」という矛盾状態になる可能性があります。

4. サブモジュールをさらにサブモジュールとして含むケース

複雑なプロジェクトではサブモジュールの中に、さらにサブモジュールが含まれることもあります。
更新作業が煩雑になるので、ディレクトリ構造を理解してから慎重に運用してください。

サブモジュールの更新履歴が複雑になると、どのコミットを参照しているのか混乱しやすいです。
ローカルとリモート両方でブランチやタグを明確に整理しましょう。

まとめ

サブモジュールは、共通コードやライブラリを複数のプロジェクトで再利用する際に便利な仕組みです。
しかし、その分だけ管理の手間が増える面もあります。
だからこそ、git submodule update を正しく使いこなすことが大切です。

メインリポジトリが特定のコミットを参照しているのか、あるいは常に最新状態を追いかけたいのか、といったルールをチームで決めるだけでも、運用の混乱を防ぎやすくなります。
サブモジュールの利用シーンをしっかりイメージしながら、実際にコマンドを試してみてください。

初心者の方でも、サブモジュールという概念を少しずつ理解していけば、自分のプロジェクトで便利に活用できるようになるはずです。
最初は戸惑うこともあるかもしれませんが、ぜひ実務の中で使いこなしてみてください。

Gitをマスターしよう

この記事で学んだGitの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。