ホームページ >テクノロジー周辺機器 >IT業界 >Gitのサブモジュールを理解し、作業します

Gitのサブモジュールを理解し、作業します

Joseph Gordon-Levitt
Joseph Gordon-Levittオリジナル
2025-02-10 15:58:09128ブラウズ

Understanding and Working with Submodules in Git

最新のソフトウェアプロジェクトは、主に他のプロジェクトの仕事の結果に依存しています。他の誰かが優れたソリューションを書いていて、コードでホイールを再発明した場合、それは大きな時間の無駄になるでしょう。これが、多くのプロジェクトがライブラリやモジュールなどのサードパーティコードを使用する理由です。

世界で最も人気のあるバージョン制御システムであるGitは、これらの依存関係を管理するエレガントで強力な方法を提供します。 「サブモジュール」の概念を使用すると、サードパーティのライブラリを含めて管理しながら、独自のコードからはっきりと分離します。

この記事では、Gitサブモジュールが非常に便利である理由、正確にそれらが何であるか、どのように機能するかを説明します。

キーポイント

    gitサブモジュールは、プロジェクトでサードパーティライブラリを管理し、メインコードベースから明確に分離するための強力で簡単な方法です。それらは、別の親Gitリポジトリに配置された標準的なgitリポジトリです。
  • プロジェクトにサブモジュールを追加するには、個別のフォルダーの作成を行い、「Git Submodule Add」コマンドを使用して、目的のライブラリのURLを使用します。これにより、リポジトリをサブモジュールとしてプロジェクトにクロームし、メインプロジェクトのリポジトリから分離します。
  • GITサブモジュールを含むプロジェクトをクローニングする場合、サブモジュールは「Git Clone」コマンドの「 - Recurse-Submodules」オプションを使用して自動的に初期化およびクローン化されます。これを行わない場合、サブモジュールフォルダーはクローニング後に空になり、「gitサブモジュールアップデート(Init -Init -Recursive」を入力する必要があります。
  • gitサブモジュールでは、特定のバージョンがブランチではなくチェックアウトされ、メインプロジェクトで使用される正確なコードを完全に制御できます。サブモジュールの更新には、「gitサブモジュールアップデート」を使用し、サブモジュール名が続きます。

コード分離を維持

gitサブモジュールが貴重な構造である理由を明確に説明するために、

サブモジュールを持っていない場合を見てみましょう。オープンソースライブラリなどのサードパーティコードを含める必要がある場合は、簡単な方法を選択できます。GitHubからコードをダウンロードして、プロジェクトのどこかに配置するだけです。この方法は非常に高速ですが、いくつかの理由で間違いなくきれいではありません: サードパーティのコードをプロジェクトに強制的にコピーすることにより、実際に複数のプロジェクトを1つのプロジェクトに混同しています。あなた自身のプロジェクトと他者のプロジェクト(ライブラリ)の間の境界線はぼやけ始めます。 ライブラリコードを更新する必要があるときはいつでも(メンテナーが優れた新機能を提供するか、深刻なバグを修正するため)、ダウンロード、コピー、貼り付けが必要です。これはまもなく退屈なプロセスになります。

  • ソフトウェア開発における「異なるものを分離する」という一般的なルールは不合理ではありません。これは、独自のプロジェクトでサードパーティコードを管理する場合に特に当てはまります。幸いなことに、Gitのサブモジュールの概念は、これらの状況向けに設計されています。
  • もちろん、サブモジュールはそのような問題の唯一の解決策ではありません。また、多くの現代言語やフレームワークが提供するさまざまな「パッケージマネージャー」システムを使用することもできます。これを行うことに何の問題もありません!

    ただし、Gitのサブモジュールアーキテクチャについては、いくつかの利点があります。

      サブモジュールは、使用する言語やフレームワークに関係なく、一貫した信頼性の高いインターフェイスを提供します。複数のテクノロジーを使用している場合、それぞれが独自のパッケージマネージャーと独自のルールとコマンドのセットを持っている場合があります。一方、サブモジュールは常に同じように機能します。
    • おそらく、すべてのコードがパッケージマネージャーを介して利用できるわけではありません。たぶん、2つのプロジェクト間で独自のコードを共有したいだけかもしれません - この場合、サブモジュールは最も簡単なプロセスを提供する場合があります。

    gitサブモジュールの本質 GITのサブモジュールは、実際には標準のGITリポジトリです。派手な革新はありません。私たちが今非常によく知っているのと同じGitリポジトリです。これはサブモジュールの力の一部でもあります。技術的な観点からは非常に「乾燥」し、よくテストされているため、非常に強力で直接的です。

    gitリポジトリを子供モジュールにする唯一のものは、別の

    gitリポジトリの内側にあることです。

    それ以外は、GITサブモジュールはまだ完全に機能的なリポジトリです。「通常の」GIT作業から、ファイルの変更からコミット、引っ張り、プッシュまで、すでに知っているすべてのことを実行できます。サブモジュール内のすべてが可能です。 サブモジュールを追加

    例として古典的な例を取りましょう。プロジェクトにサードパーティのライブラリを追加したいとします。コードを取得する前に、そのようなコンテンツを保存するために別のフォルダーを作成することは理にかなっています:

    これで、整然とした方法でサブモジュールを使用して、一部のサードパーティコードをプロジェクトにインポートする準備が整いました。小さな「タイムゾーンコンバーター」JavaScriptライブラリが必要であると仮定します:

    このコマンドを実行すると、gitはサブモジュールとしてプロジェクトにリポジトリをクローン化します。

    ワーキングコピーフォルダーを見ると、ライブラリファイルが実際にプロジェクトに到着したことがわかります。
<code class="language-bash">$ mkdir lib
$ cd lib</code>

<code class="language-bash">$ git submodule add https://github.com/spencermountain/spacetime.git</code>

「違いは何ですか?」と尋ねるかもしれません。重要な違いは、それらが独自のGitリポジトリ

に含まれていることです!いくつかのファイルをダウンロードするだけで、プロジェクトに投げ込み、残りのプロジェクトのようにそれらをコミットします。彼らは同じGitリポジトリの一部になります。ただし、サブモジュールは、ライブラリファイルがメインプロジェクトのリポジトリに「漏れ」されないことを保証します。
<code>Cloning into 'carparts-website/lib/spacetime'...
remote: Enumerating objects: 7768, done.
remote: Counting objects: 100% (1066/1066), done.
remote: Compressing objects: 100% (445/445), done.
remote: Total 7768 (delta 615), reused 975 (delta 588), pack-reused 6702
Receiving objects: 100% (7768/7768), 4.02 MiB | 7.78 MiB/s, done.
Resolving deltas: 100% (5159/5159), done.</code>

他に何が起こっているのか見てみましょう。新しい.gitmodulesファイルがメインプロジェクトルートフォルダーに作成されました。以下はその内容です:

<code class="language-bash">$ mkdir lib
$ cd lib</code>

この.gitmodulesファイルは、GIT追跡プロジェクトのサブモジュールのいくつかの場所の1つです。もう1つは.git/configです。これは次のように終了します。

<code class="language-bash">$ git submodule add https://github.com/spencermountain/spacetime.git</code>
最後に、Gitは、内部.git/Modulesフォルダーの各サブモジュールの.gitリポジトリのコピーも保持します。

これらはすべて、覚えておく必要のない技術的な詳細です。ただし、GITサブモジュールの内部メンテナンスが非常に複雑であることを理解することは役立つ場合があります。だからこそ、覚えておくべきことが重要です。GITサブモジュールの構成を手動で変更しないでください!動き、削除、または操作したい場合は、自分に好意を与えてください。これを手動で試してはいけません。適切なgitコマンドまたは「タワー」のようなgitデスクトップGUIを使用すると、これらの詳細を処理できます。

サブモジュールを追加した後、メインプロジェクトのステータスを見てみましょう。 Understanding and Working with Submodules in Git

ご覧のとおり、Gitは他の変更と同じ変更としてサブモジュールを追加することを処理します。したがって、他の変更と同じようにこの変更を犯さなければなりません:

<code>Cloning into 'carparts-website/lib/spacetime'...
remote: Enumerating objects: 7768, done.
remote: Counting objects: 100% (1066/1066), done.
remote: Compressing objects: 100% (445/445), done.
remote: Total 7768 (delta 615), reused 975 (delta 588), pack-reused 6702
Receiving objects: 100% (7768/7768), 4.02 MiB | 7.78 MiB/s, done.
Resolving deltas: 100% (5159/5159), done.</code>

gitサブモジュールを含むプロジェクトをクローン

<code>[submodule "lib/spacetime"]
  path = lib/spacetime
  url = https://github.com/spencermountain/spacetime.git</code>
上記の例では、既存のGITリポジトリに新しいサブモジュールを追加しました。しかし、「順番」、

サブモジュールを既に含むリポジトリをクローンするとどうなりますか? コマンドラインで通常のgit clone&lt; remote url&gt;を実行すると、サブモジュールフォルダーは空です。これは、サブモジュールファイルが独立しており、親リポジトリに含まれていないことを鮮明に証明しています。

この場合、親リポジトリをクローニングした後にサブモジュールを入力するために、Gitサブモジュールアップデート(Init -Recursive)を実行できます。より良い方法は、初めてのgitクローンが呼び出されたときに、-recurse-submodulesオプションを直接追加することです。

チェックアウトバージョン

「通常の」gitリポジトリでは、通常、ブランチをチェックします。 Git Checkout&lt; Branch Name&gt;または更新されたgit switch&lt&gt;このブランチで新しいコミットが行われると、ヘッドポインターは自動的にを最新のコミットに移動します。これを理解することが重要です - gitサブモジュールは異なって動作するためです!

サブモジュールでは、常に特定のバージョンをチェックしてください。ブランチではありません!サブモジュールのGit Checkout Mainと同様のコマンドを実行しても、バックグラウンドでは、そのブランチでの現在の最新

コミット

がログに記録されます - ブランチ自体ではありません。

もちろん、この動作は間違いではありません。これを考慮してください。サードパーティライブラリを含める場合、メインプロジェクトで使用する正確なコードを完全に制御する必要があります。これは、ライブラリのメンテナーが新しいバージョンをリリースする場合に最適です...しかし、あなたは必ずしもこの新しいバージョンをプロジェクトで自動的に使用したいとは限りません。これらの新しい変更があなたのプロジェクトを破るかどうかわからないからです!

サブモジュールが使用しているバージョンを見つけたい場合は、メインプロジェクトでこの情報をリクエストできます。

<code class="language-bash">$ mkdir lib
$ cd lib</code>
これにより、LIB/時空サブモジュールによって現在チェックアウトされているバージョンが返されます。また、このバージョンが「6.16.3」と呼ばれるタグであることを知らせることができます。 GITサブモジュールを使用する場合、タグを大幅に使用することが一般的です。

サブモジュールに「6.14.0」とマークされた古いバージョンの

を使用したいとします。まず、メインプロジェクトではなく、サブモジュールのコンテキストでgitコマンドが実行されるようにディレクトリを変更する必要があります。その後、タグ名でGitチェックアウトを単純に実行できます:

メインプロジェクトに戻ってGITサブモジュールのステータスを再度実行すると、チェックアウトが表示されます。
<code class="language-bash">$ git submodule add https://github.com/spencermountain/spacetime.git</code>

出力を表示します:SHA-1ハッシュの前のシンボルは、サブモジュールのバージョンが現在親リポジトリに保存されているバージョンとは異なることを示しています。チェックアウトバージョンを変更したばかりなので、これは正しいように見えます。

<code>Cloning into 'carparts-website/lib/spacetime'...
remote: Enumerating objects: 7768, done.
remote: Counting objects: 100% (1066/1066), done.
remote: Compressing objects: 100% (445/445), done.
remote: Total 7768 (delta 615), reused 975 (delta 588), pack-reused 6702
Receiving objects: 100% (7768/7768), 4.02 MiB | 7.78 MiB/s, done.
Resolving deltas: 100% (5159/5159), done.</code>
メインプロジェクトでgitステータスを呼び出すことで、この事実も通知します。

GITは、移動サブモジュールポインターを他の変更と同じ変更と扱うことがわかります。保存したい場合は、リポジトリにコミットする必要があります。

<code>[submodule "lib/spacetime"]
  path = lib/spacetime
  url = https://github.com/spencermountain/spacetime.git</code>
gitサブモジュールを更新

上記の手順では、サブモジュールポインターを移動しました。私たちは、さまざまなバージョンをチェックし、送信し、チームのリモートリポジトリにプッシュすることを選択した人です。しかし、同僚がサブモジュールバージョンを変更した場合 - サブモジュールの興味深い新しいバージョンがリリースされ、同僚がプロジェクトでそれを使用することを決めたからです(もちろん、徹底的なテストの後...)。
<code>[submodule "lib/spacetime"]
  url = https://github.com/spencermountain/spacetime.git
  active = true</code>

メインプロジェクトで簡単なgitプルを実行しましょう - 頻繁に行う可能性があるため - 共有リモートリポジトリから新しい変更を取得します:

最後から2番目の線は、サブモジュール内の何かが変更されたことを示しています。しかし、よく見てみましょう:

あなたはまだ少数を覚えていると思います。これは、サブモジュールポインターが動いたことを意味します!チームメイトが選択した「公式」バージョンにローカルチェックアウトバージョンを更新するには、更新コマンドを実行できます。

わかりました!サブモジュールは、メインプロジェクトリポジトリに記録されているバージョンにチェックアウトされます!

GITサブモジュールを使用して
<code class="language-bash">$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
  new file:   .gitmodules
  new file:   lib/spacetime</file></code>

Gitサブモジュールを使用して基本的なビルディングブロックをカバーしました。他のワークフローは非常に標準です!

<code class="language-bash">$ git commit -m "Add timezone converter library as a submodule"</code>
たとえば、サブモジュールの新しい変更をチェックすることは、他のGitリポジトリのようなものです。サブモジュールリポジトリでGit Fetchコマンドを実行し、更新を使用する場合は、Git Pull Originのようなものを実行する場合があります。指示。

サブモジュールの変更は、特に自分でライブラリコードを管理する場合(それは第三者からではなく内部ライブラリであるため)。他のgitリポジトリと同じようにサブモジュールを使用できます。変更を加えたり、コミットしたり、プッシュしたりすることができます。
<code class="language-bash">$ git submodule status
   ea703a7d557efd90ccae894db96368d750be93b6 lib/spacetime (6.16.3)</code>

git

の力を取得します

gitには舞台裏の強力な機能があります。ただし、Gitサブモジュールなどの多くの高度なツールはよく知られていません。多くの開発者は、多くの強力な機能を逃しました。これは本当に残念です!

他の高度なGitテクノロジーをより深く掘り下げたい場合は、「Advanced Git Toolkit」を強くお勧めします。ピッキング、さらには分岐戦略。

あなたにもっと良い開発者を願っています!

gitサブモジュールについてよく尋ねる質問

gitサブモジュールとは何ですか? gitサブモジュールは、独自のgitリポジトリへのサブディレクトリとして別のgitリポジトリを含める方法です。これにより、メインプロジェクトのサブプロジェクトとして個別のリポジトリを維持できます。

なぜgitサブモジュールを使用するのですか? gitサブモジュールは、特に開発履歴をメインプロジェクトから分離する場合は、外部リポジトリをプロジェクトに統合するのに役立ちます。これは、依存関係の管理や外部ライブラリを含めるのに非常に有益です。

サブモジュールに関するメインプロジェクトにどのような情報が保存されていますか? メインプロジェクトは、親リポジトリの特別なエントリでURLを保存し、サブモジュールのハッシュをコミットします。これにより、メインプロジェクトをクローン化して、参照されたサブモジュールもクローン化できるようになります。

サブモジュールを含むgitリポジトリをクローンする方法は? サブモジュールを含むリポジトリをクローニングする場合、Gitクローンコマンドの-Recursiveフラグを使用してサブモジュールを自動的に初期化およびクローン化できます。または、gitサブモジュールアップデート(クローニング後にInit)を使用できます。

サブモジュールをネストできますか? はい、Gitはネストされたサブモジュールをサポートしています。つまり、サブモジュールには独自のサブモジュールが含まれています。ただし、ネストされたサブモジュールの管理は複雑になる可能性があり、各サブモジュールが適切に初期化され、更新されるようにする必要があります。

以上がGitのサブモジュールを理解し、作業しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。