web-dev-qa-db-ja.com

gitサブツリーを使用する場合

どんな問題git subtree 解決する?その機能をいつ、なぜ使用する必要がありますか?

リポジトリの分離に使用 であると読みました。しかし、なぜ2つの無関係なリポジトリを1つにまとめるのではなく、2つの独立したリポジトリを作成しないのですか?

このGitHubチュートリアルでは Gitサブツリーのマージ方法 について説明しています。

私はhowそれを使用する方法を知っているが、whenケース)およびwhy、およびそれが git submodule 。別のプロジェクトまたはライブラリに依存している場合は、サブモジュールを使用します。

53
Lernkurve

gitのコンテキストで 'subtree'という用語を使用する場合、話していることを明示的に注意する必要があります。ここでは、実際には2つの別個の関連するトピックがあります

git-subtree および git subtree merge strategy

TL; DR

サブツリー関連の両方の概念により、複数のリポジトリを1つで効率的に管理できます。 git-submodule とは対照的に、メタデータのみがルートリポジトリに 。gitmodules の形式で格納され、外部リポジトリを個別に管理する必要があります。

詳細

gitサブツリーマージ戦略は、基本的に、参照したコマンドを使用したより手動の方法です。

git-subtreeは、より自然な構文を容易にするラッパーシェルスクリプトです。これは実際にはまだcontribの一部であり、通常のmanページでgitに完全には統合されていません。代わりに documentation がスクリプトと共に保存されます。

使用情報は次のとおりです。

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' add   -P <prefix> <commit>
'git subtree' add   -P <prefix> <repository> <ref>
'git subtree' pull  -P <prefix> <repository> <ref>
'git subtree' Push  -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]

私は自分のブログ投稿を書くことを計画していたので、サブツリーに関するかなり多くのリソースに出会いました。更新した場合はこの投稿を更新しますが、今のところは、当面の質問に関連する情報をいくつか示します。

あなたが探しているものの多くは このアトラシアンのブログ by Nicola Paolucci 以下の関連セクションにあります:

サブモジュールの代わりにサブツリーを使用する理由

subtreeを使用する方がよいと思われる理由はいくつかあります。

  • シンプルなワークフローの管理は簡単です。
  • gitの古いバージョンがサポートされます(v1.5.2)。
  • サブプロジェクトのコードは、スーパープロジェクトのcloneが完了した直後に利用できます。
  • subtreeでは、リポジトリのユーザーが新しいことを学ぶ必要はありません。依存関係を管理するためにsubtreeを使用しているという事実を無視できます。
  • subtreeは、submodulesのように新しいメタデータファイルを追加しません(つまり、.gitmodule)。
  • モジュールの内容は、依存関係の別のリポジトリコピーを別の場所に持たずに変更できます。

私の意見では、欠点は受け入れられます。

  • 新しいマージ戦略(つまり、subtree)について学ぶ必要があります。
  • サブプロジェクトのupstreamを元に戻すのは少し複雑です。
  • コミットでスーパープロジェクトとサブプロジェクトのコードを混在させない責任はあなたにあります。

私もこれに同意します。一般的な使用法については、記事をご覧になることをお勧めします。

彼がフォローアップ here を書いていることにお気づきかもしれませんが、彼はこのアプローチで残された重要な詳細について言及しています...

git-subtree現在、リモートを含めることができません!

この近視は、おそらくサブツリーを扱うときにリモートを手動で追加することが多いためですが、これもgitには保存されません。著者は、このメタデータをコミットgit-subtreeはすでに生成されています。これが公式のgitメインラインになるまで、コミットメッセージを変更するか、別のコミットに保存することで同様のことができます。

このブログ投稿 も非常に有益です。著者は、彼が呼び出す3番目のサブツリーメソッドgit-streeミックスに。彼は3つのアプローチを比較するのにかなり良い仕事をしているので、この記事は読む価値があります。彼は自分がしていることと好きでないことについて個人的な意見を述べ、なぜ彼が第三のアプローチを作成したのかを説明します。

エクストラ

おわりに

このトピックでは、gitの機能と、フィーチャがマークを逃したときに発生する可能性のあるセグメンテーションの両方を示します。

私は個人的にgit-submodule私は寄稿者が理解するのがより分かりにくいと思うので。また、プロジェクト内で管理されている依存関係を[〜#〜] all [〜#〜]にしておくことで、簡単に再現可能な環境を実現しようとしています。複数のリポジトリを管理します。 git-submoduleしかし、現在ははるかによく知られているので、それを認識し、あなたの決定を左右する可能性のある視聴者に依存することは明らかに良いことです。

35
Matthew Sanders

まず、あなたの質問は強く意見を述べる回答を得る傾向があり、ここではトピックから外れていると思われるかもしれません。しかし、私はそれが好きではないSOポリシーであり、トピックが少し外側にあるという境界線を押してしまうので、代わりに答えたいと思います。

あなたが指摘したGitHubチュートリアルには、 サブツリーマージ戦略の使用方法 へのリンクがあります。これは、利点/欠点の観点を提供します。

サブツリーのマージとサブモジュールの比較

subtree mergeを使用する利点は、ユーザーからの管理負担が少なくて済むことですリポジトリの。 older(Git v1.5.2より前)clientsとクローンの直後にコードを持っています。

ただし、submodulesを使用する場合は、サブモジュールオブジェクトを転送しないことを選択できます。これは、サブツリーのマージに問題がある可能性があります。

また、他のプロジェクトに変更を加える場合、サブモジュールを使用するだけであれば、変更を送信するのが簡単です

上記に基づく私の視点は次のとおりです。

私はよく、通常のgitユーザーではない人々(=コミッター)と仕事をしています。サブモジュールのマージ戦略の使用方法について教育することは、基本的に不可能です。これには、追加のリモート、マージ、ブランチ、そしてそれをすべて1つのワークフローに組み込むという概念が含まれます。アップストリームからのプルとアップストリームのプッシュは、2段階のプロセスです。ブランチを理解するのは難しいため、これはすべて絶望的です。

サブモジュールの場合、まだ複雑すぎます(sigh)が、理解しやすいです:リポジトリ内の単なるレポ(階層に精通している)で、プッシュを行うことができますそしていつものように引っ張ります。

単純なラッパースクリプトの提供は、サブモジュールワークフローの方が簡単です。

多くのサブリポジトリを持つ大規模なスーパーリポジトリの場合、一部のサブリポジトリのデータをクローンしないことを選択するポイントは、サブモジュールの重要な利点です。これは、作業要件とディスク容量の使用量に基づいて制限できます。

アクセス制御が異なる場合があります。まだこの問題はありませんが、異なるリポジトリが異なるアクセス制御を必要とし、一部のユーザーをいくつかのサブリポジトリから事実上禁止している場合、サブモジュールアプローチでそれを達成するのは簡単だろうかと思います。

個人的には、自分が何を使うべきかは未定です。混乱を共有します:o]

8
cfi

Gitサブツリーが救いであった実際のユースケース:

当社の主な製品は高度なモジュール式であり、別々のリポジトリのいくつかのプロジェクトで開発されています。すべてのモジュールには個別のロードマップがあります。製品全体は、具体的なバージョンのすべてのモジュールで構成されています。

並行して、製品全体の具体的なバージョンが各クライアント用にカスタマイズされます-各モジュールに個別のブランチがあります。一度に複数のプロジェクトでカスタマイズを行う必要がある場合があります(cross-module customization)。

カスタマイズされた製品に個別の製品ライフサイクル(メンテナンス、機能ブランチ)を持たせるために、gitサブツリーを導入しました。すべてのカスタマイズされたモジュールに対して1つのgit-subtreeリポジトリがあります。カスタマイズは、すべての元のリポジトリからカスタマイズブランチへの「gitサブツリープッシュバック」です。

このように、多くのリポジトリと多くのブランチを管理することは避けます。 git-subtreeは生産性を数倍向上させました!

[〜#〜] update [〜#〜]

コメントに投稿されたソリューションの詳細:

新しいリポジトリを作成しました。次に、クライアントブランチを持つ各プロジェクトを、サブツリーとしてその新しいリポジトリに追加しました。元のリポジトリに対するマスターの変更を定期的にクライアントブランチにプッシュするジェンキンスの仕事がありました。機能とメンテナンスのブランチを備えた典型的なgitフローを使用して、「クライアントリポジトリ」で作業しました。

「クライアント」レポジトリには、この特定のクライアントにも適合したスクリプトも構築されていました。

ただし、提示されたソリューションには落とし穴があります。

製品の主要なコア開発から遠ざかるにつれて、その特定のクライアントの可能なアップグレードはますます困難になりました。私たちの場合、サブツリーの前のプロジェクトの状態はすでにメインパスの方法であったため、サブツリーは少なくともデフォルトのgitフローを導入する順序と可能性を導入しました。

3
Marek Jagielski

基本的に、Git-subtreeはGit-submoduleアプローチの代替手段です。多くの欠点があります。むしろ、git-submodulesを使用する際は非常に注意する必要があります。たとえば、「1つの」レポがあり、「1」の内部にサブモジュールを使用して「2」と呼ばれる別のレポを追加した場合。あなたが世話をする必要があるもの:

  • 「2」で何かを変更するとき、トップレベルのディレクトリ(つまり「1」)にいる場合は、コミットして「2」内にプッシュする必要があります。変更は強調表示されません。

  • 不明なユーザーが「1」レポを複製しようとすると、「1」を複製した後、そのユーザーはサブモジュールを更新して「2」レポを取得する必要があります

これらのポイントの一部を理解するために、このビデオをご覧になることをお勧めします。 https://www.youtube.com/watch?v=UQvXst5I41I&t=576s

  • このような問題を克服するために、サブツリーアプローチが考案されました。 git-subtreeの基本を取得するには、次のビューをご覧ください。 https://www.youtube.com/watch?v=t3Qhon7burE&t=772s

  • サブツリーのアプローチはサブモジュールと比較してより信頼性が高く実用的であることがわかります:)(これらのことを言うのは非常に初心者です)

乾杯!

2
SH'

上記の答えに追加するために、サブツリーを使用することの追加の欠点は、サブモジュールと比較したレポサイズです。

実世界のメトリックはありませんが、モジュールでプッシュが行われるたびに、そのモジュールが使用されているすべての場所で、親モジュールで同じ変更のコピーが取得されます(その後、それらのリポジトリで更新されます)。

したがって、コードベースが大幅にモジュール化されている場合、それはすぐに追加されます。

ただし、ストレージの価格が常に下がっていることを考えると、それは重要な要因ではないかもしれません。

1
Paul Phillips