初心者でも理解できる!git submodule updateの使い方とサブモジュール管理のコツ
こんにちは、とまだです。
Gitでプロジェクトを管理していて、「他のリポジトリのコードを組み込みたいけど、どうすればいいの?」と悩んだことはありませんか?
実は、Gitにはサブモジュールという仕組みがあって、別のリポジトリを自分のプロジェクトに埋め込むことができるんです。
今回は、サブモジュールを更新するgit submodule update
コマンドを中心に、初心者の方でも理解できるように解説していきます。
サブモジュールとは?図書館の本棚をイメージしよう
サブモジュールを理解するために、図書館をイメージしてみてください。
あなたのプロジェクトが「図書館」だとしたら、サブモジュールは「特別な本棚」のようなものです。
この本棚には、他の図書館から借りてきた本のコレクションが入っています。
あなたのプロジェクト(図書館)
├── 自前の本(通常のファイル)
├── 自前の本(通常のファイル)
└── 特別な本棚(サブモジュール)
└── 他の図書館の本たち
この仕組みの便利な点は、他の図書館の本が更新されたときに、最新版を取り込めることです。
なぜサブモジュールが必要なの?
開発していると、こんな場面に遭遇することがあります。
- 複数のプロジェクトで同じライブラリを使いたい
- 外部のオープンソースプロジェクトを組み込みたい
- チーム内で共通のコンポーネントを管理したい
毎回コードをコピペするのは効率が悪いですし、更新があったときの管理も大変です。
サブモジュールを使えば、元のリポジトリとの連携を保ちながら、必要なコードを組み込めるんです。
git submodule updateの基本的な使い方
それでは、実際にサブモジュールを更新する方法を見ていきましょう。
リポジトリをクローンしたときの初期設定
誰かが作ったプロジェクトをクローンしたとき、サブモジュールのフォルダは空っぽの状態です。
まずは初期化と更新を行います。
# サブモジュールの初期化
git submodule init
# サブモジュールの内容を取得
git submodule update
この2つのコマンドは、まとめて実行することもできます。
# 初期化と更新を同時に実行
git submodule update --init
さらに、サブモジュールの中にサブモジュールがある場合(入れ子構造)は、--recursive
オプションを使います。
# 入れ子のサブモジュールも含めて初期化・更新
git submodule update --init --recursive
サブモジュールを最新の状態に更新する
プロジェクトで作業していて、サブモジュールの最新版を取り込みたいときがあります。
基本的な流れは以下のとおりです。
# 1. メインプロジェクトの最新を取得
git pull origin main
# 2. サブモジュールを更新
git submodule update
ただし、この方法だと、メインプロジェクトが指定している特定のコミットに更新されます。
サブモジュールの最新のコミットを取得したい場合は、--remote
オプションを使います。
# サブモジュールを最新のコミットに更新
git submodule update --remote
よくある疑問と解決方法
Q1: サブモジュールの中身が更新されない
「git pull
したのに、サブモジュールが古いまま...」
これはよくある勘違いです。
git pull
はメインプロジェクトの更新だけで、サブモジュールは自動的に更新されません。
必ずgit submodule update
を実行する必要があります。
Q2: エラーが出て更新できない
よくあるエラーメッセージと対処法を紹介します。
「fatal: reference is not a tree」というエラー
メインプロジェクトが参照しているコミットが、サブモジュールのリポジトリに存在しない場合に発生します。
# サブモジュールのディレクトリに移動
cd path/to/submodule
# 最新の情報を取得
git fetch
# メインプロジェクトに戻る
cd ../..
# 再度更新を試す
git submodule update
Q3: サブモジュールで作業した変更が消えてしまった
サブモジュール内で直接編集していて、git submodule update
を実行すると、変更が上書きされることがあります。
作業前に必ずコミットするか、別ブランチで作業することをおすすめします。
# サブモジュール内での作業例
cd path/to/submodule
git checkout -b my-feature
# 作業・コミット
git push origin my-feature
実践的な運用のコツ
1. チームでの運用ルールを決める
サブモジュールを使う場合、チーム内でルールを決めておくと混乱を避けられます。
- サブモジュールの更新タイミング
- 更新の責任者
- コミットメッセージの書き方
例えば、「サブモジュールの更新は週次で行い、更新内容を明記する」といったルールです。
2. 更新時のコミットメッセージを工夫する
サブモジュールを更新したときは、何を更新したのか分かりやすくコミットメッセージに書きましょう。
# 良い例
git commit -m "Update auth-library submodule to v2.1.0 for OAuth2 support"
# 悪い例
git commit -m "Update submodule"
3. CIでの自動チェック
継続的インテグレーション(CI)を使っている場合は、サブモジュールの取得も含めるように設定します。
# GitHub Actionsの例
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: recursive
トラブルシューティング
サブモジュールが正しく更新されているか確認する
現在のサブモジュールの状態を確認するコマンドです。
# サブモジュールの状態を確認
git submodule status
出力例:
-c5e3ac8... library/auth (v1.2.3)
+d7f4b92... library/ui (v2.0.0-5-gd7f4b92)
e8a2c41... library/utils (v1.0.0)
-
: サブモジュールが初期化されていない+
: 現在のコミットが、記録されているものと異なる
サブモジュールを完全にリセットする
何か問題が起きて、最初からやり直したい場合の手順です。
# サブモジュールのクリーンアップ
git submodule deinit -f path/to/submodule
# サブモジュールのディレクトリを削除
rm -rf .git/modules/path/to/submodule
# 再度初期化と更新
git submodule update --init
まとめ
サブモジュールは最初は複雑に感じるかもしれません。
でも、基本的な使い方を覚えてしまえば、プロジェクトの管理がとても楽になります。
重要なポイントをおさらいすると、このようになります。
git submodule update
でサブモジュールを更新--init
オプションで初期化も同時に実行--remote
オプションで最新のコミットを取得- チームでルールを決めて運用する
サブモジュールを使いこなせるようになると、より効率的なプロジェクト管理ができるようになります。
ぜひ実際に試してみてください!
著者について

とまだ
フルスタックエンジニア
Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。
著者の詳細を見る →