web-dev-qa-db-ja.com

同じビルドシステムを共有する多くのプロジェクトを含むリポジトリを分割するにはどうすればよいですか?

私はここ数年、いくつかの実行可能ファイルとライブラリを構築するリサーチコンパイラスイートに取り組んできました。ビルドシステム(つまりbootstrapper)があり、ビルドするツールを./src/binディレクトリで検索し、./src/lib./src/rtlおよび./src/stdでライブラリ、依存関係の管理(internal依存関係のみ!) (GCCのように)複数のツールの単一のmakefileのように機能します。このため、同じコードベースを共有していますです。これまで、単一のgitリポジトリを使用してきました。

ほとんどのツールとライブラリは自己完結型であるため、ほとんどのツールは相互に依存しないため、リポジトリをいくつかのモジュールに分割したいと思います(循環的な依存関係はまったくなく、いくつかの階層的な依存関係のみです!)。

たとえば、次のような非常に基本的なシステムを備えたcoreモジュールがあります。

./README
./src/bootstrapper.krc
./src/bin/cpp.c
./src/bin/cc.c
./src/lib/cpp/...
./src/lib/cc/...
./src/lib/foo/...
./src/lib/bar/...

これはビルダーを含み、それは自己完結型です。 cppcc、およびlibcpplibcclibfooおよびlibbarライブラリが生成されます。

次に、たとえばRubyモジュールを何らかの方法で分離して、次のようにしたいとします。

./src/bin/rbc.c
./src/lib/rbc/...
./src/std/Ruby/...

rbclibrbcおよびlibstdruby...をビルドし、次にpythonモジュールを作成します。

./src/bin/pyc.c
./src/lib/pyc/...
./src/std/python/...

pyclibpyc、およびlibstdpythonをビルドします。

Rubypythonの両方の仮想モジュールはcoreモジュールに依存しますが、これらは相互にまったく依存していません(これが分割について考えている理由です)私の現在のリポジトリ)。

どちらの方法でこれを達成できますか?モジュールごとに異なるgitブランチを使用することを考えました(ただし、coreモジュールの複数のコピーを保持して最新に保つなど、依存関係に基づいてすべてを自動的にリベースするにはいくつかのフックが必要です)、複数のgitリポジトリ(同じ問題)、そして私が持っているビルドシステムのためにファイルごとの基礎が必要になるので、gitサブモジュールは役に立ちません...

(私はgitを好んでいますが、GitHubで公開したいので、別のSCMに切り替えてもかまいません。)

すべてのツール(bin/example)は、多数のマクロを持つ同じ./include/bin/main.hcoreモジュールの一部になる)に依存しています... ./src/の各フォルダ実際には対応する./include/フォルダもあります(例:./include/std/Ruby/...)。

それが現在あるので、私が上で説明したもののいくらかの写真です:

5
paulotorrens

要件
リポジトリの分割を検討している場合は、次の点を考慮することが重要です。

  1. 新しいスプリットにはそれぞれ独自のトランクがあります。この場合、各製品は単に別のブランチになることはできません。これらの製品にはそれぞれ独自のバージョン(タグ)、独自のdevブランチがあり、したがってそれぞれに独自のトランクが必要になるためです。

  2. 履歴を維持するこれは、リポジトリを分割するときにおそらく最も重要なことです。私たちは過去に相互作用したものの歴史を失うべきではありません。たとえば、ソースから完全なエクスポートを取得して、4つの新しいリポジトリを作成できます。しかし、それはすべての歴史を失うでしょう。したがって、製品レポの各部分には、独立したレポから使用するときに履歴があるはずです。

  3. 機能しているブランチを開くそこに機能ブランチまたはサポートブランチがあり、店舗を閉鎖したい場合は、すべてを巻き取ってトランクに戻す必要があります。ただし、妥当なサイズのプロジェクトの場合、これを実現するのは困難です。むしろ、同じ履歴とスナップショットを持つブランチを新しいリポジトリで利用できるようにして、中断したところから作業を再開できるようにする必要があります。再起動する必要はありません。

しかし、解決策は簡単です:

  1. 最初のステップは、各リポジトリを異なる名前で複製することです。各レポタイプの手順を以下に示します。基本的に4つのクローンで、4つのリポジトリがあり、それぞれが同じ構造(トランク/タグ/ブランチ)、同じ履歴、同じブランチセットを持っています。

  2. これで、プライマリトランクから、対応するリポジトリで不要なすべてのソースコードを削除できます。たとえば、1つのリポジトリですべてのRubyファイルを削除し、Cファイルのみを保持します。他のリポジトリの逆も同様です。したがって、Cファイルから作成されたライブラリと別のリポジトリを持つ1つのリポジトリがあります。 Rubyファイル。

  3. この変更をすべての下位ブランチにマージして、そこからの削除も反映します。

  4. Makefileなどの共通ファイルを変更します。これにより、同じ構造になります。

  5. オプションで、ファイルを「移動」して構造を再編成することもできます。

  6. 新しいリリースに新しい番号シリーズ2.0のタグを付けます(以前は1.xだった場合)。

これに続いて、すべての履歴は4つの製品リポジトリのそれぞれで引き続き利用できます。したがって、重要なことに、収集したスナップショットに戻ることができます。

リポジトリ固有のもの

  1. [〜#〜] svn [〜#〜]SVNの場合、これは非常に簡単です。リポジトリがホストされているメインフォルダーをコピーして貼り付けます。 svnadmin --createコマンドで生成されたもの(作業コピーではありません)。詳細は SVNブックCh 5 を参照してください。クローンを作成すると、他のリポジトリにあるものがすべて含まれます。

  2. Gitリポジトリはデフォルトで分散化されています。したがって、実行するたびに git-clone there it 実際にリポジトリを複製しています。ただし、異なる製品で識別されるためには、他に2つのオプションがあります。 A.フォークとB.ミラーリング。 ミラーリングなしの複製については、このページ を参照してください。もう1つの参照は this SO question です。フォークは別のオプションです。基本については このページ を参照してください。ただし、フォークは完全に同じではありませんクローン/ミラーリングとして。ミラーリングを選択します。

1
Dipan Mehta