バージョン管理リポジトリをどのように整理しますか?


108

まず、これについて知っています。社内のソフトウェアプロジェクト用にSubversionリポジトリをどのように編成しますか? 次に、実際の質問:私のチームはリポジトリを再構築しており、それを整理する方法についてのヒントを探しています。(この場合はSVN)。これが私たちが思いついたものです。1つのリポジトリ、複数のプロジェクト、複数のsvn:externals相互参照があります

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

語彙を明確にするために:ソリューションは単一の製品を意味し、プロジェクトはVisual Studioプロジェクトです(単一の.dllまたは単一の.exeになります)。

これが、リポジトリのレイアウトを計画している方法です。主な問題は、複数のソリューションがあることですが、プロジェクトをソリューション間で共有したいと考えています。これらの共有プロジェクトを独自のソリューションに移動しても意味がないと考え、代わりにsvn:externalsを使用してソリューション間でプロジェクトを共有することにしました。また、リポジトリ内の1か所に共通のツールとサードパーティライブラリのセットを保持し、それらがsvn:externalsを使用して各ソリューションでそれらを参照するようにします。

このレイアウトについてどう思いますか?特にsvn:externalsの使用について。これは理想的なソリューションではありませんが、すべての長所と短所を考慮すると、私たちが考えることができる最高のソリューションです。あなたはどうしますか?


「スラッシュ」の意味ですか?それとも「ゴミ」?
ssc 14

回答:


92

以下の推奨事項(私は何年も持っています)に従うと、次のことができるようになります。

-プロジェクトのルートディレクトリから下の構造を維持する限り、各プロジェクトをソース管理の任意の場所に配置します

-最小限のリスクと最小限の準備で、各プロジェクトを任意のマシンの任意の場所に構築します

-バイナリ依存関係(ローカルの「ライブラリ」および「出力」ディレクトリ)にアクセスできる限り、各プロジェクトを完全にスタンドアロンでビルドします。

-プロジェクトは独立しているため、プロジェクトの任意の組み合わせを構築して使用する

-独立しているため、単一のプロジェクトの複数のコピー/バージョンをビルドして操作する

-生成されたファイルまたはライブラリでソース管理リポジトリが乱雑にならないようにします

私はお勧めします(ここに牛肉があります):

  1. 各プロジェクトを定義して、.DLL、.EXE、.JAR(Visual Studioではデフォルト)などの単一の主要成果物を作成します。

  2. 各プロジェクトを単一のルートを持つディレクトリツリーとして構造化します。

  3. IDEに依存せずに、プロジェクトを最初からビルドするルートディレクトリ内の各プロジェクトの自動ビルドスクリプトを作成します(ただし、可能であればIDEでのビルドを妨げないでください)。

  4. Windows上のnAnt for .NETプロジェクト、またはOS、ターゲットプラットフォームなどに基づいた類似のものを検討してください。

  5. 完全にはバージョンによって識別されるすべてのバイナリで、単一のローカルの共有「ライブラリ」ディレクトリからすべてのプロジェクトのビルドスクリプト参照にその外部(サードパーティ)の依存関係を作ります: %DirLibraryRoot%\ComponentA-1.2.3.4.dll%DirLibraryRoot%\ComponentB-5.6.7.8.dll

  6. すべてのプロジェクトのビルド・スクリプトは、単一のローカル共有「出力」ディレクトリに主要成果物を公開してください:%DirOutputRoot%\ProjectA-9.10.11.12.dll%DirOutputRoot%\ProjectB-13.14.15.16.exe

  7. すべてのプロジェクトビルドスクリプトが、「ライブラリ」ディレクトリと「出力」ディレクトリ内の構成可能で完全にバージョン管理された絶対パス(上記を参照)を介して、その依存関係を参照し、他にどこにもないようにします。

  8. プロジェクトに別のプロジェクトまたはそのコンテンツを直接参照させないでください。「出力」ディレクトリ(上記を参照)の主要な成果物への参照のみを許可してください。

  9. すべてのプロジェクトのビルド・スクリプトが設定可能とフルバージョン管理、絶対パスでその必要なビルドツールを参照してください: %DirToolRoot%\ToolA\1.2.3.4%DirToolRoot%\ToolB\5.6.7.8

  10. プロジェクトのルートディレクトリへの絶対パス相対することにより、すべてのプロジェクトのビルドスクリプトリファレンスソースコンテンツを作成します ${project.base.dir}/src${project.base.dir}/tst(構文は、ビルド・ツールによって異なります)。

  11. 常に、絶対的で構成可能なパス(構成可能な変数で指定されたディレクトリをルート)を介してすべてのファイルまたはディレクトリを参照するためのプロジェクトビルドスクリプトが必要です:${project.base.dir}/some/dirsまたは${env.Variable}/other/dir

  12. プロジェクトビルドスクリプトが.\some\dirs\hereやなどの相対パスを..\some\more\dirs使用して参照することは絶対にしないでください。絶対パスを常に使用してください。

  13. プロジェクトビルドスクリプトが、C:\some\dirs\hereまたはなどの構成可能なルートディレクトリを持たない絶対パスを使用してすべてを参照することを許可しないで\\server\share\more\stuff\thereください。

  14. プロジェクトビルドスクリプトによって参照される構成可能なルートディレクトリごとに、それらの参照に使用される環境変数を定義します。

  15. 各マシンを構成するために作成する必要がある環境変数の数を最小限に抑えるようにしてください。

  16. 各マシンで、THATマシンに固有の(場合によってはそのユーザーに固有の)必要な環境変数を定義するシェルスクリプトを作成します。

  17. マシン固有の構成シェルスクリプトをソース管理に置かないでください。代わりに、プロジェクトごとに、プロジェクトのルートディレクトリにあるスクリプトのコピーをテンプレートとしてコミットします。

  18. 各プロジェクトビルドスクリプトに各環境変数を確認するよう要求し、定義されていない場合は意味のあるメッセージを表示して中止します。

  19. 各プロジェクトビルドスクリプトを要求して、その依存ビルドツール実行可能ファイル、外部ライブラリファイル、および依存プロジェクト成果物ファイルのそれぞれをチェックし、これらのファイルが存在しない場合は意味のあるメッセージを表示して中止します。

  20. 生成されたファイルをソース管理にコミットする誘惑に抵抗してください-プロジェクトの成果物、生成されたソース、生成されたドキュメントなどはありません。

  21. IDEを使用する場合は、できる限りのプロジェクト管理ファイルを生成し、それらをソース管理にコミットしないでください(これにはVisual Studioプロジェクトファイルが含まれます)。

  22. すべての外部ライブラリとツールの公式コピーを備えたサーバーを確立し、開発者のワークステーションとビルドマシンにコピー/インストールします。ソース管理リポジトリとともにバックアップします。

  23. 開発ツールがまったくない継続的インテグレーションサーバー(ビルドマシン)を確立します。

  24. Ivy(Antで使用)などの外部ライブラリと成果物を管理するためのツールを検討してください。

  25. Mavenを使用しないでください。最初はあなたを幸せにし、最終的には泣かせます。

これはSubversionに固有のものではなく、OS、ハードウェア、プラットフォーム、言語などを対象とするプロジェクトに一般的なものであることに注意してください。OSとツール固有の構文を少し使用しましたが、説明のみを目的としています-私はあなたがあなたの選択したOSやツールに翻訳することを信じます。

Visual Studioソリューションに関する追加の注意:ソース管理に配置しないでください!このアプローチでは、それらをまったく必要としないか、または(Visual Studioプロジェクトファイルのように)生成できます。ただし、ソリューションファイルを個々の開発者に任せて、適切に作成/使用できるようにするのが最善です(ただし、ソース管理にチェックインされていません)。Rob.sln現在のプロジェクトを参照するファイルをワークステーションに保持しています。プロジェクトはすべてスタンドアロンであるため、プロジェクトを自由に追加/削除できます(つまり、プロジェクトベースの依存関係の参照はありません)。

Subversionエクスターナル(または他のツールで類似)は使用しないでください。これらはアンチパターンであるため、不要です。

継続的インテグレーションを実装する場合、またはリリースプロセスを自動化するだけの場合でも、そのためのスクリプトを作成します。プロジェクト名(リポジトリにリストされている)とタグ名のパラメーターを受け取り、構成可能なルートディレクトリ内に一時ディレクトリを作成し、指定されたプロジェクト名とタグ名のソースをチェックアウトする(その一時ディレクトリへのSubversionの場合は適切なURL)、テストを実行して成果物をパッケージ化するクリーンビルドを実行します。このシェルスクリプトはどのプロジェクトでも機能し、「ビルドツール」プロジェクトの一部としてソース管理にチェックインする必要があります。継続的インテグレーションサーバーは、プロジェクトを構築するための基盤としてこのスクリプトを使用できます。また、スクリプトを提供することもできます(ただし、独自のスクリプトが必要な場合もあります)。

@VonC:互換性のないバージョンのAntで無意識に実行したため、ビルドスクリプトが壊れたときに焼き付けられた後は、「ant-abcdjar」ではなく「ant.jar」を常に使用したくない。これは、Ant 1.6.5と1.7.0の間で特に一般的です。一般化すると、プラットフォーム(Java ABCD)やビルドツール(Ant EFGH)など、使用されているすべてのコンポーネントの特定のバージョンを常に知りたいと思っています。そうしないと、最終的にバグが発生し、最初の大きな問題は、さまざまなコンポーネントのどのバージョンが関係しているかを追跡することになります。単にその問題を前もって解決するほうがよいです。


6
批判するべき多くのポイント...これは普遍的なレシピではないと言うのに十分です!特にポイント5と6は、プロジェクトが大きく、サードパーティの数が重要である場合、非常に間違っています。「ant1.5.4.jar」ではなく「ant.jar」または製品myProductを常に使用したい場合1.3.exeではなく.exe
VonC

5
それでも、あなたが作成している他の多くのポイントに対して+1は有効であり、トピックに関する幅広い経験に対して非常によく話します。
VonC 2008年

3
私はあなたの批判を聞いて、それと対話してみたいです-それぞれのポイントはすべて、大規模プロジェクトでの悪い経験を解決することに基づいています。たとえば、Xxx.jarとYyy.exeによって表されるバージョンの問題に対処します。特に、参照されているコピーが文字通り12個ある場合に対処します。
ロブウィリアムズ

2
@Rob-「外部パターンのアンチパターン」のテーマについて詳しく教えてください。:私はここで問題としてそれを提起してきたstackoverflow.com/questions/338824/...
ケン

3
@マキ:あなたは正しいでしょう、もし#12が#13によってバランスされていなかったら。各プロジェクト内のファイルまたはディレクトリへのすべての参照は、Antの$ {basedir} /sub/dir/file.txtなどの構成可能なルートディレクトリ変数で始まる絶対パスを介して行う必要があります。
ロブウィリアムズ


3

投稿内容とほぼ同じになるように設定しました。一般的な形式を使用します。

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

私はあなたの例ほど完全ではないと思いますが、それは私たちにとってはうまく機能し、物事を別々に保つことができます。私は各ユーザーが「スラッシュ」フォルダーを持っているという考えも好きです-現在、これらのタイプのプロジェクトはソース管理に終わらないので、常にそうするべきだと感じていました。


3
バージョンごとに変わらないドキュメント用に別のディレクトリがあることに驚いています...そのような製品に取り組む喜びがありませんでした!:)
ARKBAN 2008年

1

すべてが1つのリポジトリにあるのはなぜですか?プロジェクトごとに個別のリポジトリを用意しないのはなぜですか(「ソリューション」を意味します)。

まあ、少なくとも私はone-project-per-repository-approachに慣れています。リポジトリ構造は私には複雑すぎるようです。

また、この1つの大きなリポジトリにいくつのプロジェクトを入れる予定ですか?2?3?10?100?

また、1つのプロジェクトの開発をキャンセルした場合はどうしますか?リポジトリツリーから削除するだけで、将来見つけにくくなります。またはそれを永遠に横にしたままにしますか?あるいは、あるプロジェクトを別のサーバーにまとめて移動したい場合はどうでしょうか?

そして、これらすべてのバージョン番号の混乱はどうですか?1つのプロジェクトのバージョン番号は2、10、11のようになり、もう1つは1、3、4、5、6、7、8、9、12のようになります

ばかげているかもしれませんが、リポジトリごとに1つのプロジェクトが好きです。


1. 1つのリポジトリは会社のポリシーであり、それを変更することはできません。2.約12のソリューションがあります。3.バージョン番号でリビジョンを意味しますか?それは私たちの問題ではありません。
Krzysztof Kozmic

優れたプロジェクト構造は、特に1つまたは複数のリポジトリに関して、リポジトリ構造の他の部分に気づかないはずです。詳細な回答をご覧ください。
ロブウィリアムズ、

1
セキュリティを実装する場合など、多くの(ほとんどの)ソース管理ツールに複数のリポジトリがあると、非常にコストがかかる可能性があることに注意してください。
ロブウィリアムズ、

0

提案された構造の主な欠点は、共有プロジェクトが追加された最初のソリューションでのみバージョン管理されることだと思います(svn:externalsが私が想像しているよりも洗練されていない限り)。たとえば、Solution2の最初のリリースのブランチを作成すると、Project1はSolution1に存在するため、ブランチされません。後でそのブランチからビルドする必要がある場合(QFEリリース)、ブランチの時点のProject1のバージョンではなく、Project1の最新バージョンを使用します。

このため、共有プロジェクトを1つまたは複数の共有ソリューション(つまり、構造内の最上位のディレクトリ)に配置しソリューションのリリースごとにそれらを分岐することをお勧めします。


あなたはある程度正しいです。ただし、必要に応じて参照を更新できます。また、共有プロジェクトを独自のソリューションに組み込んでも、あまり意味がありません。どこでもsvn:externalsよりも良い解決策を見つけたいです。
Krzysztof Kozmic

「必要に応じて参照を更新する」とはどういう意味ですか?Solution1を分岐せずにProject1を分岐する方法(Solution2を分岐するときはいつでも望ましいように見える)はわかりません。
C.ドラゴン76

特にVisual Studioソリューションをソース管理に含めないようにするには、私の詳細な回答を参照してください。
ロブウィリアムズ

0

相対パスの問題に追加するには:

問題かどうかはわかりません。
「Solution1」という名前のディレクトリの下のSolution1 / trunkをチェックアウトしてください。Solution2も同様です。実際にブランチを表す「ディレクトリ」の目的は、ワークスペースにインポートすると表示されなくなることです。したがって、「Solution1」(実際には「Solution1 / trunk」)と「Solution2」(Solution2 / trunk)の間の相対パスが可能です。


これは非常に簡単に壊れます。詳細な回答をご覧ください。
ロブウィリアムズ、

0

RE:相対パスと共有ファイルの問題-

これはsvn固有のようですが、それは問題ではありません。他の1人がすでに別のリポジトリについて言及していましたが、他の任意のプロジェクトを参照している別のプロジェクトがある場合、それはおそらく私が考えることができる最良の解決策です。共有ファイルがない場合は、OPソリューション(および他の多くのソリューション)が正常に動作します。

私たちはまだこれを解決しており、3つの異なる作業(異なるクライアント)があり、存在しないバージョン管理または不十分なバージョン管理のセットアップを引き継いだため、今すぐ解決する必要があります。


プロジェクトに他のプロジェクトを参照させると、依存関係が指数関数的に増大し、参照が非常に壊れやすくなるため、メンテナンスに悪夢が生まれます。詳細な回答をご覧ください。
ロブウィリアムズ、

0

レイアウトは似ていますが、トランク、ブランチ、タグは一番上にあります。つまり、/ trunk / main、/ trunk / utils、/ branches / release /などです。

多くの翻訳ツールが基本的な教科書SVNレイアウトで最もよく機能したため、他のバージョン管理システムを試してみたいときに、これは本当に便利になりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.