はじめに
Git サブモジュールは、独自のプロジェクト内に外部リポジトリを含めることを可能にする強力な機能です。この機能は、プロジェクトが個別に管理されている外部ライブラリやコンポーネントに依存する場合に特に役立ちます。サブモジュールを使用することで、これらの依存関係を最新の状態に保ち、適切に管理できます。
このチュートリアルでは、リポジトリ内の Git サブモジュールのステータスを確認し、それらに対して行われた変更を理解し、ソースリポジトリと適切に同期させる方法を学びます。
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)
この出力の意味を理解しましょう。
最初の文字は次のいずれかになります。
+: サブモジュールでチェックアウトされたコミットが、メインリポジトリに登録されているものと異なることを示します。 (スペース): サブモジュールが登録されているものと同期していることを示します。-: サブモジュールが初期化されていないことを示します。U: サブモジュールでマージコンフリクトが発生したことを示します。英数字の文字列は、サブモジュールでチェックアウトされている現在のコミットのコミットハッシュです。
パスは、サブモジュールがリポジトリ内のどこにあるかを示しています。
かっこ内のテキストは、タグやブランチ名など、チェックアウトされたコミットに関する追加情報を示しています。
サブモジュールに関するより詳細な情報を得るには、次のコマンドを使用できます。
git submodule
これにより、ステータスコマンドと同様の情報が異なる形式で表示されます。
標準の 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
このコマンドは、変更された各サブモジュールで追加または削除されたコミットの範囲を示します。
サブモジュールでの変更を操作する場合は、次のワークフローを覚えておいてください。
この 2 段階のコミットプロセス(最初にサブモジュールで、次にメインリポジトリで)は、サブモジュールへの変更を適切に追跡するために不可欠です。
このチュートリアルでは、Git サブモジュールのステータスを確認し、更新することに焦点を当てて、Git サブモジュールを操作する方法を学びました。以下が達成した内容です。
Git サブモジュールは、外部リポジトリをプロジェクトに含めるための強力な方法を提供し、依存関係を効率的に管理できます。ステータスの確認方法と更新の管理方法を理解することで、プロジェクトが依存関係と適切に同期された状態を維持できます。
覚えておくべき主なコマンド:
git submodule status - サブモジュールの現在のステータスを確認します。git submodule update --remote - サブモジュールを最新バージョンに更新します。git add <submodule-path> - サブモジュールの参照への変更をステージングします。git diff --submodule - サブモジュールでの詳細な変更を表示します。これらのスキルにより、サブモジュールを介して外部コードを組み込んだ Git リポジトリを効果的に管理できます。