パソコン関連
PR

【Git】リポジトリ内に別のリポジトリを組み込む方法【Gitサブモジュール】

えりる
記事内に商品プロモーションを含む場合があります

アプリのコードはGitでバージョン管理しているけど、「このアプリが使うデータやライブラリ」の管理はどうしていますか?

  • 「アプリのデータも、過去の変更を追ったり、誰が何を直したか見たい!」
  • 「アプリのコードとは別に、データやライブラリだけを独立して管理したい!」

そう考えているなら、Gitのサブモジュールという機能がとても役に立ちます。

この記事では、Gitで管理しているアプリのフォルダの中に別のリポジトリを組み込む方法を解説します。

[rotc_mokuji]

サブモジュールとは

Gitのサブモジュールとは、「あなたのメインのプロジェクトの中に、別のGitリポジトリ(別のプロジェクト)を組み込む」 ための機能です。
もっと簡単に言うと、まるで一つの大きな箱の中に、小さな箱をそのまま入れる」 ようなイメージです。

サブモジュールの作成方法

サブモジュールは以下のコマンドで追加することができます。

git submodule add <リポジトリのURL> <ローカルの保存先パス(省略可>

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

メインのリポジトリはサブモジュールの中身のファイル自体を管理しません。
その代わりに、「別のリポジトリの、この時点(特定のコミット)の状態を参照する」 という情報だけを記録します。

メインのプロジェクトとサブモジュールが、お互いに独立してバージョン管理されているので、メインのプロジェクトをgit cloneしただけでは、サブモジュールのフォルダは空っぽです。
サブモジュールの中身を使うためには、git submodule initgit submodule updateといった追加のコマンドを実行して、初めて中身のファイルがダウンロードされる仕組みになっています。たとえば以下のコマンドで行うことができます。

git submodule update --init --recursive

また、メインリポジトリをクローンするときにサブモジュールを含めて一度にクローンしたいときは--recursive オプションをつけてクローンします。

git clone --recursive <リポジトリのURL>

リポジトリ内に別のリポジトリを組み込む

ここでは例として、Gitで管理しているアプリのフォルダの中に、データ管理用の別のGitリポジトリを組み込みます

目標構成

以下の構成を目標にします。メインリポジトリはクローン済みとします。

your-project/
├─ .git/
├─ .gitmodules            # ← submodule 設定が入る
├─ media/
│   └─ data/              # ← ここが別リポジトリ(submodule)
└─ src/ …

.gitignoremedia/ を無視してOK。submodule は「gitlink」として親リポジトリに登録されるため、media/ を無視していても media/json は追跡されます(後述の例外指定は任意)。

サブモジュールを新規に追加する場合

media/data が空の場合の方法を解説します。

サブモジュールとして追加したいリポジトリをGitHub/GitLab 等に先に作っておきます。

次にプロジェクトのルートディレクトリ(your-project/)でサブモジュールをmedia/data に追加します。コマンドは以下の通りです。

git submodule add <リモートリポジトリのURL> media/data

その後上記コマンドで生成された.gitmodulesgitlink をメインリポジトリへコミットします。

git commit -m "Add data submodule at media/data"

既存の JSON ファイルを submodule に移行する場合

次はすでに media/data にファイルがある場合です。

ここでもあらかじめサブモジュール用のリポジトリをGitHub/GitLab 等に先に作っておきましょう。

準備ができたら media/data の中身をいったんどこかに移して空にします。
GUI上で手動で移してもよいですし、
ターミナルで作業をするなら、以下のコマンドをプロジェクトルートディレクトリ(your-project/)で実行します(一例です)。

mkdir -p ~/tmp/data-backup # ホームディレクトリに退避
cp -a media/data/. ~/tmp/data-backup

次にプロジェクトのルートディレクトリ(your-project/)でサブモジュールをmedia/data に追加しましょう。(空の submodule として追加します。)
コマンドは以下の通りです。

git submodule add <リモートリポジトリのURL> media/data

その後上記コマンドで生成された.gitmodulesgitlink をメインリポジトリへコミットします。

git commit -m "Introduce media/data as submodule"

次に退避したファイルを今設定したサブモジュール側へ移動させます。
まず、プロジェクトのルートディレクトリ(your-project/)からサブモジュールのディレクトリへ移動しましょう。

cd media/data

その後退避したファイルをサブモジュールへ移動させます。

cp -a /tmp/data-backup/. .

移動させたらサブモジュール側のリポジトリへCommit/Push しましょう。

git add .
git commit -m "Seed JSON assets from project (initial import)"
git push origin main   # ※ デフォルトブランチ名に合わせる

最後に、メインリポジトリにポインタ更新を反映します。

# 親にポインタ更新を反映
cd ../..
git add media/data
git commit -m "Point submodule to initial data commit"

おまけ: submodule を削除したい場合

追加したサブモジュールを削除するには以下のように行います。

  1. git rm -f media/json を実行
  2. .gitmodules の該当エントリを削除
  3. git commit を実行
  4. .git/config の submodule エントリを掃除(必要なら)
  5. 作業ツリー上の media/json/ を手動削除(必要なら)

まとめ

この記事ではGitのサブモジュールという機能を使用して、Gitで管理しているアプリのフォルダの中に別のリポジトリを組み込む方法を解説しました。

Gitのサブモジュールとは、「あなたのメインのプロジェクトの中に、別のGitリポジトリ(別のプロジェクト)を組み込む」 ための機能で、
アプリ本体と、ライブラリやデータを完全に独立した別のリポジトリとして管理しながら、一つのプロジェクトとして扱うことができます。

えりるさんが気になっている商品紹介コーナー

UGREENの巻き取り式USB-C充電ケーブルです。巻き取り式のケーブルで100WのPD充電できるのが良いポイント。コンパクトなので持ち運びにも室内用、車内用にも便利ですし、100Wいけるので充電器を選べばスマホからノートパソコンまでなんでも充電できます。
ケーブル長さは36/60/82/100cmの4段階調整なので好きな位置で止められないのは注意ですが、ケーブルを束ねたりして管理するのはめんどくさいですし、それから解放されると考えるとえりるさん的にはかなり魅力的ですね(笑)

えりるについて
えりる
えりる
日本のどこかに生息する平成生まれの研究者。とっても理論家と思いきや気分屋さんでもある。基本的にめんどくさがり。修士(工学)を持っている。 Windows, Mac, Linuxの三刀流。
記事URLをコピーしました