リポジトリ内の Git サブモジュールのステータスの確認方法

GitBeginner
オンラインで実践に進む

はじめに

Git サブモジュールは、独自のプロジェクト内に外部リポジトリを含めることを可能にする強力な機能です。この機能は、プロジェクトが個別に管理されている外部ライブラリやコンポーネントに依存する場合に特に役立ちます。サブモジュールを使用することで、これらの依存関係を最新の状態に保ち、適切に管理できます。

このチュートリアルでは、リポジトリ内の Git サブモジュールのステータスを確認し、それらに対して行われた変更を理解し、ソースリポジトリと適切に同期させる方法を学びます。

サブモジュールを持つリポジトリの作成

学習のための実践的な環境を構築するために、まずサブモジュールを持つサンプルリポジトリを作成しましょう。

メインリポジトリの設定

まず、サブモジュールを追加する新しいメインリポジトリを作成します。ターミナルを開き、次のコマンドを実行します。

cd ~/project
mkdir main-repo
cd main-repo
git init

次のような出力が表示されるはずです。

Initialized empty Git repository in /home/labex/project/main-repo/.git/

次に、メインリポジトリに簡単なファイルを作成しましょう。

echo "## Main Repository" > README.md
git add README.md
git commit -m "Initial commit"

出力は、最初のコミットが作成されたことを示しているはずです。

[master (root-commit) xxxxxxx] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

サブモジュールの追加

次に、メインリポジトリにサブモジュールを追加しましょう。このチュートリアルでは、小さな公開リポジトリをサブモジュールとして使用します。

git submodule add https://github.com/libgit2/libgit2-backends.git libs/libgit2-backends

このコマンドは、リポジトリをクローンし、libs/libgit2-backends ディレクトリにサブモジュールとして追加します。次のような出力が表示されるはずです。

Cloning into '/home/labex/project/main-repo/libs/libgit2-backends'...
remote: Enumerating objects: xxx, done.
remote: Counting objects: 100% (xxx/xxx), done.
remote: Compressing objects: 100% (xxx/xxx), done.
remote: Total xxx (delta xx), reused xxx (delta xx), pack-reused xxx
Receiving objects: 100% (xxx/xxx), xxx KiB | xxx KiB/s, done.
Resolving deltas: 100% (xxx/xxx), done.

変更の理解

サブモジュールを追加すると、Git はリポジトリ内に .gitmodules ファイルを作成し、サブモジュールの URL とパスを追跡します。このファイルを見てみましょう。

cat .gitmodules

次のような内容が表示されるはずです。

[submodule "libs/libgit2-backends"]
	path = libs/libgit2-backends
	url = https://github.com/libgit2/libgit2-backends.git

また、リポジトリのステータスも確認しましょう。

git status

新しい .gitmodules ファイルとサブモジュールディレクトリの両方が追加されたことを示す出力が表示されるはずです。

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .gitmodules
        new file:   libs/libgit2-backends

これらの変更をコミットして、セットアップを完了しましょう。

git commit -m "Add libgit2-backends submodule"

これで、サブモジュールが正常に設定されたリポジトリができました。

サブモジュールのステータスの確認

サブモジュールを持つリポジトリができたので、サブモジュールのステータスを確認し、出力の意味を理解する方法を学びましょう。

基本的なサブモジュールステータスチェック

Git は、サブモジュールのステータスを確認するための特定のコマンドを提供しています。次のコマンドを実行します。

cd ~/project/main-repo
git submodule status

次のような出力が表示されるはずです。

+abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (v1.0.0-123-gabcdef12)

この出力の意味を理解しましょう。

  1. 最初の文字は次のいずれかになります。

    • +: サブモジュールでチェックアウトされたコミットが、メインリポジトリに登録されているものと異なることを示します。
    • (スペース): サブモジュールが登録されているものと同期していることを示します。
    • -: サブモジュールが初期化されていないことを示します。
    • U: サブモジュールでマージコンフリクトが発生したことを示します。
  2. 英数字の文字列は、サブモジュールでチェックアウトされている現在のコミットのコミットハッシュです。

  3. パスは、サブモジュールがリポジトリ内のどこにあるかを示しています。

  4. かっこ内のテキストは、タグやブランチ名など、チェックアウトされたコミットに関する追加情報を示しています。

詳細なサブモジュール情報

サブモジュールに関するより詳細な情報を得るには、次のコマンドを使用できます。

git submodule

これにより、ステータスコマンドと同様の情報が異なる形式で表示されます。

Git Status を使用してサブモジュールの変更を確認する

標準の git status コマンドを使用して、サブモジュール内の変更を確認することもできます。

git status

サブモジュールに変更がない場合、出力にはそれに関する言及は表示されません。ただし、サブモジュールのチェックアウトされたコミットまたはサブモジュール内のファイルに変更がある場合、git status はこの情報を表示します。

サブモジュールコンテンツの検査

サブモジュールの内容を調べてみましょう。

cd ~/project/main-repo
ls -la libs/libgit2-backends/

libgit2-backends リポジトリのファイルが表示されます。サブモジュールは、基本的にメインリポジトリ内の完全な Git リポジトリであることに注意してください。.git ディレクトリの存在を確認することで、これを検証できます。

ls -la libs/libgit2-backends/.git

.git ディレクトリが直接表示されるのではなく、メインリポジトリの .git/modules ディレクトリに保存されている実際の Git リポジトリデータを指すファイルが表示される場合があります。これが、Git がサブモジュールを管理する方法です。

サブモジュール参照の理解

メインリポジトリは、サブモジュールリポジトリ内の特定のコミットへの参照を保存します。この参照は、リポジトリをクローンしたり、サブモジュールを更新したりするときに、Git がどのバージョンのサブモジュールをチェックアウトする必要があるかを知るために使用するものです。

メインリポジトリが参照しているコミットを見てみましょう。

cd ~/project/main-repo
git ls-files --stage libs/libgit2-backends

出力には、メインリポジトリが追跡しているサブモジュールの特定のコミットであるコミットハッシュが表示されます。

サブモジュールの更新

サブモジュールを扱う際の一般的なタスクの 1 つは、リモートリポジトリとの同期を保つことです。サブモジュールを更新する方法を学びましょう。

サブモジュールの初期化と更新

サブモジュールを含むリポジトリをクローンしたばかりの場合は、それらを初期化して更新する必要があります。既存のリポジトリでは、このプロセスを次のようにデモンストレーションできます。

cd ~/project/main-repo
git submodule init
git submodule update

init コマンドは、サブモジュールの設定を初期化し、update コマンドはデータをフェッチし、メインリポジトリで指定されたコミットをチェックアウトします。

これらのコマンドを組み合わせることもできます。

git submodule update --init

サブモジュールを最新のリモートバージョンに更新する

サブモジュールをリモートリポジトリの最新のコミットに更新する場合は、次のように使用できます。

cd ~/project/main-repo
git submodule update --remote libs/libgit2-backends

このコマンドは、リモートリポジトリから最新の変更をフェッチし、サブモジュールを更新します。Git が変更をフェッチしていることを示す出力が表示されるはずです。

このコマンドを実行した後、サブモジュールのステータスを確認しましょう。

git submodule status

出力の先頭にプラス記号(+)が表示され、サブモジュールのチェックアウトされたコミットがメインリポジトリに記録されているものと異なることを示していることに気付くでしょう。

+abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (origin/HEAD)

メインリポジトリへの変更を確認するには、次を実行します。

git status

サブモジュールが変更されたことを示す出力が表示されるはずです。

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   libs/libgit2-backends (new commits)

更新されたサブモジュール参照のコミット

更新されたサブモジュールの状態をメインリポジトリに記録するには、変更を追加してコミットする必要があります。

git add libs/libgit2-backends
git commit -m "Update libgit2-backends submodule to latest version"

出力は、新しいサブモジュール参照が正常にコミットされたことを示しているはずです。

更新されたステータスの確認

更新されたサブモジュール参照をコミットした後、もう一度ステータスを確認しましょう。

git submodule status

出力の先頭にプラス記号が表示されなくなり、サブモジュールがメインリポジトリに記録されているものと同期していることを示しているはずです。

 abcdef1234567890abcdef1234567890abcdef12 libs/libgit2-backends (origin/HEAD)

サブモジュール更新オプションの理解

git submodule update コマンドには、更新の実行方法を制御するいくつかのオプションがあります。

  • --remote: リモート追跡ブランチの最新のコミットに更新します。
  • --merge: 現在のブランチがリモートより遅れている場合に、変更をマージします。
  • --rebase: 現在のブランチがリモートより遅れている場合に、変更をリベースします。
  • --recursive: ネストされたサブモジュールも更新します。

ほとんどの基本的なユースケースでは、git submodule update --remote で十分です。

サブモジュールの変更の操作

サブモジュール内で変更を操作する必要がある場合があります。このステップでは、サブモジュール内で変更を行い、管理する方法を学びます。

サブモジュールへの移動

サブモジュールを操作するには、そのディレクトリに移動する必要があります。

cd ~/project/main-repo/libs/libgit2-backends

ここから、標準の Git コマンドを使用して、サブモジュールリポジトリに関する情報を表示できます。

git status
git log -3 --oneline

git status コマンドは、サブモジュールリポジトリの現在の状態を示し、git log は最近のコミットを示します。

サブモジュールでの変更

サブモジュール内のファイルに簡単な変更を加えましょう。まず、新しいファイルを作成します。

echo "## My notes on libgit2-backends" > NOTES.md

次に、変更のステータスを確認しましょう。

git status

未追跡ファイルがあることを示す出力が表示されるはずです。

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        NOTES.md

この変更をサブモジュールに追加してコミットしましょう。

git add NOTES.md
git commit -m "Add notes file"

サブモジュール内でのコミットを確認する出力が表示されるはずです。

メインリポジトリからのステータスの確認

次に、メインリポジトリに戻ってステータスを確認しましょう。

cd ~/project/main-repo
git status

サブモジュールが変更されたことを示す出力が表示されるはずです。

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   libs/libgit2-backends (new commits)

メインリポジトリでのサブモジュール変更のコミット

メインリポジトリでサブモジュールの新しい状態を記録するには、変更を追加してコミットする必要があります。

git add libs/libgit2-backends
git commit -m "Update libgit2-backends with notes file"

出力は、新しいサブモジュール参照が正常にコミットされたことを示しているはずです。

サブモジュールの詳細な変更の表示

サブモジュールでの変更に関するより詳細な情報を表示するには、次を使用できます。

git diff --submodule

このコマンドは、変更された各サブモジュールで追加または削除されたコミットの範囲を示します。

サブモジュール変更の操作のまとめ

サブモジュールでの変更を操作する場合は、次のワークフローを覚えておいてください。

  1. サブモジュールディレクトリに移動します。
  2. サブモジュール内で変更を行い、コミットします。
  3. メインリポジトリに戻ります。
  4. 更新されたサブモジュール参照を追加してコミットします。

この 2 段階のコミットプロセス(最初にサブモジュールで、次にメインリポジトリで)は、サブモジュールへの変更を適切に追跡するために不可欠です。

まとめ

このチュートリアルでは、Git サブモジュールのステータスを確認し、更新することに焦点を当てて、Git サブモジュールを操作する方法を学びました。以下が達成した内容です。

  1. メインリポジトリを作成し、サブモジュールを追加しました。
  2. さまざまな Git コマンドを使用して、サブモジュールのステータスを確認する方法を学びました。
  3. サブモジュールをリモートリポジトリから最新バージョンに更新しました。
  4. サブモジュール内で変更を行い、それらの変更をメインリポジトリで適切に追跡しました。

Git サブモジュールは、外部リポジトリをプロジェクトに含めるための強力な方法を提供し、依存関係を効率的に管理できます。ステータスの確認方法と更新の管理方法を理解することで、プロジェクトが依存関係と適切に同期された状態を維持できます。

覚えておくべき主なコマンド:

  • git submodule status - サブモジュールの現在のステータスを確認します。
  • git submodule update --remote - サブモジュールを最新バージョンに更新します。
  • git add <submodule-path> - サブモジュールの参照への変更をステージングします。
  • git diff --submodule - サブモジュールでの詳細な変更を表示します。

これらのスキルにより、サブモジュールを介して外部コードを組み込んだ Git リポジトリを効果的に管理できます。