git submoduleについて最低限調べてみた

に公開

1. Git Submoduleの基本概念

1.1 Submoduleとは何か

  • 別のGitリポジトリを現在のリポジトリの一部として組み込む仕組み
  • メインリポジトリとサブモジュールは独立したGitリポジトリ
    下記のようにそれぞれのリポジトリでDBマイグレーションリポジトリを共有リソースとして扱いたい場合などに用いることがある

メインリポジトリがsample-backendでサブモジュールがprisma-migrationの場合

メインリポジトリで、2つのリポジトリのブランチ管理が可能になる



1.2 メインリポジトリとサブモジュールの関係性

  • 重要: メインリポジトリはサブモジュールの「特定のコミット」を記録
  • サブモジュールのブランチ名ではなく、コミットハッシュで管理

prisma-migrationにて新しいブランチを切ると、

sample-backendにて、サブジュールの変更差分が発生する

2 サブモジュールの状態確認方法

# サブモジュールの状態確認
git submodule status

現在メインリポジトリが参照しているサブモジュールのコミットハッシュを確認することができる
()の内容は、参照しているブランチを表す

詳細な差分確認

git diff --submodule
git submodule summary

メインリポジトリが現在参照しているサブモジュールのコミットハッシュと異なるコミットが適用されている場合、下記のように
Submodule サブモジュール名 変更前のコミットハッシュ..変更後のコミットハッシュ:
>コミットメッセージ
と表示される

3. サブモジュールのブランチ操作

3.1 サブモジュールで特定のブランチを使う基本手順

パターン1: 既存サブモジュールのブランチ変更

# サブモジュールディレクトリに移動
cd path/to/submodule

# 目的のブランチにチェックアウト
git checkout feature-branch

# または、リモートブランチを追跡
git checkout -b feature-branch origin/feature-branch

# メインリポジトリに戻って変更をコミット
cd ../..
git add path/to/submodule
git commit -m "Update submodule to feature-branch"

パターン2: サブモジュール追加時にブランチを指定

# サブモジュール追加(特定のブランチを指定)
git submodule add -b feature-branch https://github.com/user/repo.git path/to/submodule
git commit -m "Add submodule with specific branch"

3.2 .gitmodulesでのブランチ追跡設定

[submodule "path/to/submodule"]
    path = path/to/submodule
    url = https://github.com/user/repo.git
    branch = feature-branch

4. 実践的なワークフロー

4.1 開発フローでのサブモジュール管理

メインリポジトリとサブモジュールの開発を並行する場合

  1. サブモジュールでの開発

    cd path/to/submodule
    git checkout -b new-feature
    # 開発作業
    git commit -m "Add new feature"
    git push origin new-feature
    
  2. メインリポジトリでの取り込み

    cd path/to/submodule
    git pull origin new-feature
    cd ../..
    git add path/to/submodule
    git commit -m "Update submodule to include new feature"
    

4.2 チーム開発での注意点

  • サブモジュールの更新は明示的にコミットが必要
  • git pullしてもサブモジュールは自動更新されない
  • git submodule update --remoteでリモートの最新を取得

5 サブモジュールの更新漏れには気をつける

# サブモジュールも含めて更新
git pull --recurse-submodules

# または段階的に
git pull
git submodule update --init --recursive

よく使うコマンド一覧

# サブモジュール追加
git submodule add [-b branch] <url> <path>

# 状態確認
git submodule status
git submodule summary

# 更新
git submodule update --remote [--merge|--rebase]
git submodule foreach 'git pull origin main'

# 初期化
git submodule init
git submodule update --init --recursive

Discussion