共有ライブラリを分岐するためのリポジトリレイアウト(またはフック)(および健全性を維持)
-
05-07-2019 - |
質問
subversionを使用しています(質問は多くのバージョン管理システムに適用できますが、subversionは私が本当に気にするものです。)
リポジトリレイアウトは次のようになります。
(レイアウトA)
Web
branches
tags
trunk
Libraries
Foo
branches
tags
trunk
Bar
branches
tags
trunk
WindowsClient
branches
tags
trunk
DB
branches
tags
trunk
問題は、バージョニングの単位が開発の単位と等しくないことです-ビルド可能なアーティファクトを取得するために複数のチェックアウトを行う必要があり、分岐するときに複数のコンポーネントを分岐する必要があります場所。)
これは、代わりに次のような構造に移動できることを意味します。
(レイアウトB)
Web
branches
tags
trunk
main
libs
Foo
Bar
DB
WindowsClient
branches
tags
trunk
main
libs
Foo
Baz
DB
しかし、共有ライブラリのコピーが重複しています。 svn:externalsを使用して共有ライブラリをマッピングすることもできますが、それは単なる幻想です-含まれているプロジェクトが分岐しても分岐しません。
最後のオプションはこれです:
(レイアウトC)
branches
tags
trunk
Web
Libraries
Foo
Bar
WindowsClient
DB
これにより、ライブラリが含まれるプロジェクトとともに確実に分岐されますが、分岐の単位が全世界であるという犠牲が伴います。 (これはまた、チェックアウトの単位が全世界であることを意味し、これも煩わしいです。)
必要なのは、次のことができるリポジトリレイアウト(Layout D)です。
- プロジェクトとその依存ライブラリを一度にブランチ
- プロジェクト間でライブラリを共有する
一度のチェックアウトでプロジェクトとそのライブラリをチェックアウトできればいいのですが、それは上記ほど重要ではありません。
質問は次のとおりです:
レイアウトDはありますか、それは何で、どのように使用しますか
編集:これらのプロパティを提供する基本的なレイアウトがないように見えるので、そこに到達するための何らかのフック関数に非常に興味があります。 TortoiseSVN(Windows GUI)クライアントで動作する場合は特に便利です。これが私たちが使用しているものだからです。
解決
オプションCに進み、次のようにチェックアウトします:
svn co -N ...../branches/mybranch workingcopy
cd workingcopy
svn update Web Libraries
今、svn操作(通常の" svn update
"を含む)を行うと、 Web
と Libraries
ディレクトリ。
疎ディレクトリも参照してください。
他のヒント
「このワークフローのリポジトリをどのようにレイアウトするのか?」という質問に対する良い答えはありません。ソフトウェアがそれを実際にサポートしていないからです。レイアウトBに進み、ライブラリコードを分岐し、必要に応じて関連する svn:external
をその分岐に切り替えるか、分岐がオフトランクバージョンを参照する必要がある場合はすぐに切り替えることをお勧めしますライブラリの。
Gitがこれをより適切に処理することを提案するつもりでしたが、大したことではありません。そのサブモジュールは外部とは少し異なるリポジトリを参照し、リポジトリの各コピーは「ブランチ」であるため、わずかに改善される可能性があります。
共有ライブラリを使用してマップすることができます svn:externals、しかしそれはただ 錯覚-それらは分岐しません 含まれているプロジェクトの場合。
実際には、同じリポジトリ内にあり、相対的な外部構文を使用した場合、それらは分岐します。 (編集:この方法で動作すると確信していましたが、その動作を再現することはできないようです。間違えたに違いありません、申し訳ありません!) ^ \ mylib \ trunk
。このような外部参照は、通常の(コピーされた)フォルダーに変更されます。この動作を抑制するには、-ignore-externals
を svn copy
に明示的に渡す必要があります。そうしないと、レイアウトBのようなコピーになってしまいます。
外部が常に自動的に分岐するとは限らないという事実は、問題になる必要はありません。 svn:externals <で構築されたレイアウトBを使用します。 / code>
(コピーではなく)、プロジェクトを分岐し(-ignore-externals
を使用)、分岐後、 svn:externals
が正しいライブラリブランチ。
特定のリビジョンを指すように外部を設定することができます(厳密な制御に適しています。lbraryの新しいリビジョンにいつアップグレードするかを決定します)。またはHEADを追跡するだけです(継続的な統合に適しています。ビルドサーバーのセットアップ)。
これを解決したのは、複数のプロジェクトで使用される共有外部ライブラリの場合です。共有ライブラリは、独自のトランク/ブランチ/タグを使用して独自のリポジトリに入ります。
次に、ビルドサーバーを構築し、統合ビルド、マイルストーン、およびリリースを公開します。バイナリアーティファクトは共有場所にコピーされ、バージョン固有のディレクトリに保存されます(これらはバックアップされます)。
依存プロジェクトのビルドスクリプトの一部(通常、標準ビルドの一部としてではなく、初期化/更新としてオンデマンドで実行)は、新しいバージョンをチェックし、バイナリを取得します。これには、依存プロジェクト間で共有アーティファクトの一貫したバージョン管理という利点があり、すべての依存プロジェクトが同じバージョンを共有できるため、ビルド時間が短縮されます。
バージョン管理を支援するために、現在、一時的な依存関係などをサポートする Apache Ivy を使用しています依存関係の依存関係の取得)およびバージョンの制約(たとえば、このプロジェクトではFooバージョン1.2。*のみを使用する必要があります)。
問題を引き起こしているのは、これらのライブラリに対するあなたのアプローチであることをお勧めします。ライブラリを独自のプロジェクトとして考え始める場合、これを変更できます。単体テスト、xmlリーダー、dbアクセスなどに使用するサードパーティライブラリと同様に、独自の存在理由、独自のデザイン、独自のリリースサイクルがあると考えてください。
もちろん、プロジェクトの機能がライブラリの新しい機能を必要とする場合があります。ライブラリ機能の実装とライブラリ関数の使用は、2つの独立したタスクです。1つのビジネスタスクでも、2つの開発タスクです。ライブラリがチェックアウトされ、変更され、リリースされ、プロジェクトをチェックアウトし、プロジェクトでライブラリの新しいリリースを使用するため、2つのアクティビティを密接にリンクする必要はありません。
ライブラリを独自のトランクに分離することは良いことだと強く感じています。単一のトランクの下で複数の独立したリリース可能なプロジェクトを見ていると、我慢できません。それは貧弱なデザインであり、開発の残骸によって隅に追いやられました。しかし、それらを分離するには、各プロジェクトを個別にリリースできる必要があります-私にとって、それは複数のプロジェクトを持つことですという意味。しかし、それは難しいことではありません:
最初に、プロジェクトは外部を使用して、ライブラリの特定のリリースバージョンを参照します。プロジェクトがライブラリを参照する唯一の方法です。これを行うと、すべてのプロジェクトが以前のバージョンを参照するため、開発者はライブラリを使用しているプロジェクトを壊さずにライブラリの新しいバージョンを作成できます。プロジェクトは、ライブラリの新しいバージョンをいつ導入するかを制御できます。開発者は、新しいバージョンでコードをテストする作業をいつ行いたいか、および新しいライブラリのビルドの問題をいつ修正するかを選択できます。紹介します。
このようなライブラリのバージョンを明示的に変更すると、プロジェクトに「このバージョンのライブラリX」を使用しているというエントリが表示されます。これにより、物事がいつ機能し、いつ物事が変化したかに関するプロジェクトの歴史の感覚。
もちろん、これは理論上はすべて素晴らしいことですが、実際には、開発者はライブラリの不安定なバージョンや未完成のバージョンを参照する必要がある場合があります。それは大丈夫です-開発者は常に、タグや開発ブランチの代わりにライブラリトランクを指すように作業コピーを切り替えて、そこからコードを使用できます(必要に応じて、そこを介して作業することもできます)。スイッチは単なるローカル編集であるため、コミットされたコードには影響しません。プロジェクト開発が不安定なブランチ上にある場合、ブランチを再統合する準備ができるまで外部参照を変更することにより、スイッチをより永続的にすることを決定できますが、これは明確な理由なしに通常行われることではありません。
そして最後に、プロジェクトのブランチとタグ付けは、メインプロジェクトのブランチまたはタグを作成する簡単なケースになります-それだけです。ライブラリの分岐について心配する必要はありません-彼らは自分自身の世話をします。ライブラリを変更するプロセスは、プロジェクトがトランク、開発ブランチ、またはメンテナンスリリースのいずれであっても変わりません。また、ライブラリ自体に、メインプロジェクトから完全に独立した開発ブランチ、および複数のサポートされているバージョンなど、必要な複雑なレベルまでサポートすることができます。
トランクまたは開発ブランチでエクスターナルを使用することにより、必要な構造でワークスペースを構築する単一のチェックアウトを行うことができます。すべてのライブラリはメインルートの下にあるため、ビルドで衝突することなく、複数のバージョンの複数のチェックアウトを行うことができます。
このシステムは非常にうまく機能し、ジョブを移動した後t
これは良い解決策がない難しい問題です; ハイエンドの解決策は&#8220; ソフトウェア製品ライン&#8221;管理システム(例: pure :: variants )。しかし、私たちのほとんどは、ソースコード管理システムにその一致を費やすことができません。
したがって、 LayoutA を使用します&#8211;各ライブラリは個別にバージョン管理されます。ただし、&#8220; トランク&#8221; &#8220; ブランチ&#8221;ブランチであり、すべてのブランチを上部から同じ距離に配置するのが好きです。
次のステップはビルドシステムにかなり依存します。ここではVisual Studioを想定しています。
- 各製品ブランチツリーのルート
- 使用する各ライブラリのブランチの名前を含む環境変数を定義するbatファイルを作成します
- Visual Studioプロジェクトファイルを編集して、これらの環境変数を使用してライブラリを参照します
- Visual Studioを起動する前に、Visual Studioコマンドプロンプトからバッチファイルを実行します
バッチファイルを使用するのではなく、カスタムMSBuildファイルを作成することもできます。または、ライブラリのバージョンを変更したときにすべてのプロジェクトファイルを編集するツールを作成します。
共有ライブラリが1つまたは2つしかなく、それらが一度に1つの製品に対してのみ変更される場合。現在作業中のプロジェクトに新しいメソッドを追加します。プロジェクトごとにライブラリの異なるブランチを作成することを検討し、SVN 1.5マージタッキングを使用して、何が起こっているかを追跡します。 (変更が安定したら、トラックにマージし、必要に応じてトラックから各プロジェクトブランチにマージします)
(ライブラリが数百ある場合、各ライブラリの魔女バージョンはお互いに必要です。これは非常に複雑になります!)
私はsvn:externalが好きではありません。ローカルPCのファイルシステムから何が起こっているのか明確ではないからです。ただし、svn:externalは実行可能なソリューションです。
同様の問題を経験したことがありますが、あなたの痛みを知っています。階層コンポーネントを持つリポジトリで依存関係を管理するのは難しい問題です。
私たちのプロジェクトには、さまざまなコンポーネント(その多くが共有されています)で構成されるいくつかの製品(顧客に出荷するものは何でも)がありました。レイアウトAによく似た独自の tags / branches / trunk
三部作を持つ各コンポーネントがありました(これは、推奨される方法です)。
svn:externals
を使用して、各製品が依存コンポーネント(およびサブコンポーネントなど)を指定する方法を提供しましたが、最初は適切に機能しました。しかし、最終的には、分岐時に起こること、ある製品が特定のリビジョンで依存性を固定する必要がある場合、構成管理のために外部を通じてタグを伝播する方法(実際に同じツリーを再構築できる)などの問題に遭遇しました! 、 等々。したがって、 svn:externals
はいくつかの問題を解決しますが、他の問題を導入します。
これを管理するためのスクリプトをいくつか書きましたが、それでも少し複雑でした。幸いなことに、Python-Subversionバインディングを使用して、プロパティを操作するPythonアプリを作成できるため、依存コンポーネントを介してタグを伝播するなどのことができます。
ピストンと呼ばれる、依存モジュールのこの問題に対処するように設計されたプロジェクトがあります。これは、まさにこの種の問題に対する非常に優れた汎用ツールのように見えます。実稼働環境には展開しませんでしたが、当時は必要なことのほとんどを実行できるように見えました。そして、それは確かに、外部から提供されるよりも柔軟なソリューションのように思えます(それでも非常に手作業のプロセスです)。
一番下の行:レイアウトAに固執し、ピストンを使用して依存関係を管理し、ライブラリのすべての適切なバージョンが作業ディレクトリにアセンブルされるようにします。