7

同じことについて多くの質問があることは承知していますが、さらに情報が必要です。SVN リポジトリを git に移行する可能性を調査しており、リポジトリに最適なアプローチ (モノリス トランク、サブモジュール、サブツリーなど) を理解しようとしています。

プロジェクトと SVN リポジトリに関する情報を次に示します。

  • プロジェクトは、パッケージ化された Java Web アプリケーションです。
  • モジュラーアプリケーションです。各モジュールは別々のチームによって開発され、jar としてパッケージ化されます。
  • 戦争はこの瓶にかかっています。

基本的に、構造は次のようになります。

repo
|-application(war)
|-module1 (for example, ui stuff)
|--module1Submodule1
|--module1Submodule2
|-module2 (for example, database access stuff)
|-...

各モジュールには独自のタグとブランチがあります。

すべてのブランチ、タグなどを含むローカル マシン上の svn リポジトリのサイズは次のとおりです。

  • 250 万以上のファイル
  • 20Gb 以上のスペース
  • 311615 リビジョンがあります
  • ファイルはほとんどがソース コードであり、大きなバイナリ オブジェクトはありません

典型的なユースケース:

  • チーム全体で 200 人以上の開発と QA
  • さまざまなチームがそれぞれのモジュール/サブモジュールにコミットします。(モノリス git リポジトリに問題がある可能性があります。git はプッシュの前にすべての変更をプルする必要があるため、svn は古い変更についてのみ警告します)
  • 分岐モジュール
  • 支店申請

将来のユースケース:

  • ゲリット
  • 開発者がコミットし、コミットがレビューされ、コミットに対してテストが実行されます。緑色の場合、コミットは「マスター」ブランチへのマージが承認されます

質問は次のとおりです。

  1. そのようなレポを git にとって大きなものと見なすことはできますか (大きなレポに対して git のスケーリングがうまくいかないことに注意する投稿がたくさんあることを意味しますが、「大きい」とは何ですか?)
  2. 各アプローチの長所と短所は何ですか:
    • モノリス リポジトリ (svn として git だけ、アンチ パターン?)
    • サブモジュール
    • サブツリー (モジュールのすべての変更は、サブツリー リポジトリでコミットしてから、集約されたサブツリー リポジトリに変更をプルする必要があるというのは正しいですか?)
    • モジュールごとに個別のリポジトリ
    • 他の..
  3. それぞれのSVNの履歴を保存できますか?
  4. できるだけ多くのリンクが必要です(「大規模なリポジトリでは遅い」という公式リンクは見つかりませんでした)

前もって感謝します!

4

3 に答える 3

7

歴史

git svn: http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Gitを使用して、前述のすべてのアプローチの履歴を保存 できます。以前のコミットに戻すことも可能です。

ただし、履歴を保持せず、svn リポジトリを約 6 か月間フリーズしたままにしておくという提案がありましたが、すべての履歴は git リポジトリで変更されます。私たちのプロジェクトには歴史が不可欠なので、そのようなアドバイスには同意しません。誰もそのような解決策を受け入れないに違いない。

ジャイアントトランクアプローチ

  • 1 つのサブディレクトリのみで作業する予定がある場合でも、大きなツリー全体を複製する必要があります (主な使用例)
  • 一部の git コマンドは遅くなります (例: ツリー全体をチェックする必要があるため、git ステータス)
  • リポジトリの特定の部分に対してのみビルドをトリガーするように jenkins を調整する場合でも (これは、jenkins git プラグインの「include」プロパティを使用して実行できます)。ビルドを実行するには、すべてのリポジトリをプルする必要があります。小さなモジュールを構築する場合でも、「クリーンな」チェックアウトには多くの時間がかかるため、これがすべての作業に影響を与えることはほとんどありません。

懸念事項: チーム全体で 200 人以上の開発者と QA を抱えているため、最終的に変更をプッシュするのは非常に難しいと思います。

  • 変更は、gerrit でレビューが承認され、テストに合格した後にのみマスター ブランチにプッシュされるため、プル - プッシュ - 失敗 - プル - プッシュの連続的なフローはありません。
  • ただし、コミットが gerrit にプッシュされた後にマスター ブランチが変更された場合、gerrit はマージを拒否する可能性があり、「リベース」ボタンをクリックしてテストを再実行する必要があります。
  • c/c++ には Java のような依存関係管理がないため、Linux カーネルにはモノリス リポジトリがあります。

クイズ

このアプローチを使用した移行の手順、その費用、および総費用はどのようなものですか?

  • git svn クローン SVN_URL REPO_NAME
  • ジェンキンスのもの

コードゲーティングをどのようにサポートできますか? VCS / ツールの観点から、どのような変更が必要ですか? ここで、完全な CI の実行に 15 分かかるとします。

  • Jenkins では、プロジェクトの特定の部分の変更をフィルター処理するために、scm トリガーに「include」フィルターが必要です。それほど難しくはありませんが、セットアップと検証には多少の努力が必要です。「ビルド前にワークスペースをワイプ」ビルドの場合、リポジトリ全体を常に複製する必要があります。チェックアウトが非常に遅くなるため、コミットから「テストによる承認」までの全体的な時間が長くなる可能性があります。

効率的な開発者ワークフローとは?

  • 開発者はローカル/リモート機能ブランチを使用します
  • 変更を gerrit にプッシュする
  • Gerrit はテストに対して変更を検証します
  • 変更は master ブランチにマージされます

サブモジュール

ここで説明されているほとんどの警告http://git-scm.com/book/en/Git-Tools-Submodulesとここhttp://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use -git-サブモジュール/

主な問題は、2回コミットする必要があることです

  • サブモジュール自体へ
  • リポジトリを集約する - サブモジュールを更新する 意味がありません。アーティファクト リポジトリを介して依存関係が管理されている場合、リポジトリの集約が必要になるのはなぜですか?

実際には、さまざまなプロジェクトで再利用できるライブラリがあるが、将来参照を更新する機能を備えたライブラリの特定のタグに依存したい場合のために作成されたサブモジュール。ただし、各コミットにタグを付けるつもりはなく (各コミットの後にのみリリースする)、war で依存関係のバージョンを (リリースされたものに) 変更することは、サブモジュールのアプローチを維持するよりも簡単です。Java の依存関係管理により、作業が簡単になります。

サブモジュール ヘッドを指すことは推奨されておらず、サブモジュールで問題が発生するため、このアプローチはスナップショットへの行き止まりです。繰り返しになりますが、Java 依存関係管理がすべてを行ってくれるので、これは必要ありません。

クイズ このアプローチを使用した移行の手順、そのコスト、および総コストは何ですか?

  • 各モジュールの git svn clone SVN_URL REPO_NAME
  • 集約 git リポジトリを作成する
  • モジュールリポジトリをサブモジュールとして集約リポジトリに追加します

コードゲーティングをどのようにサポートできますか? VCS / ツールの観点から、どのような変更が必要ですか? ここで、完全な CI の実行に 15 分かかるとします。

  • Gerrit はサブモジュールへのマージとコミットの両方をサポートしているので、問題ないはずです。
  • Jenkins のもの - サブモジュールの変更とレポの変更の集約でトリガーします (うーん! 2 つの場所で意味がありません!)

効率的な開発者ワークフローとは? (ゲリット処理は省略)

  • 開発者はサブモジュールにコミットします
  • 彼のコミットのタグを作る
  • 開発者はレポの集約に入る
  • サブモジュールへのcd、タグのチェックアウト
  • 変更されたサブモジュール ハッシュを使用して集約リポジトリをコミットする

または

  • 開発者はサブモジュールを変更します
  • 変更を失わないように変更をサブモジュールにプッシュします
  • 変更されたサブモジュール ハッシュを使用して集約リポジトリをコミットする

ご覧のとおり、開発者のワークフローは面倒で (常に 2 つの場所を更新する必要があります)、私たちのニーズには合いません。

サブツリー

主な問題は、2回コミットする必要があることです マージされたサブディレクトリをツリー化するには 変更を元のリポジトリにプッシュします

サブツリーはサブモジュールのより優れた代替手段であり、より堅牢であり、サブモジュールのソースコードを参照するだけでなく、集約リポジトリにマージします。このような集約レポを維持することはより簡単になりますが、サブツリーの問題はサブモジュールの問題と同じであり、二重コミットを行うことはまったく役に立ちません。元のモジュール リポジトリに変更をコミットする必要はなく、リポジトリを集約してコミットできます。リポジトリ間の不整合が発生する可能性があります...

違いはここでよく説明されています: http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/

クイズ このアプローチを使用した移行の手順、そのコスト、および総コストは何ですか?

  • 各モジュールの git svn clone SVN_URL REPO_NAME
  • 集約レポを作成する
  • モジュールごとにサブツリーのマージを実行する

コードゲーティングをどのようにサポートできますか? VCS / ツールの観点から、どのような変更が必要ですか? ここで、完全な CI の実行に 15 分かかるとします。

  • Gerrit はサブツリーのマージをあまりサポートしていないようです ( https://www.google.com/#q=Gerrit+subtrees )
  • しかし、試してみるまで確信が持てません
  • ジェンキンスのもの。サブツリーのレポと集計レポの変更でトリガーします (うーん、2 つの場所で意味がありません!)

効率的な開発者ワークフローとは? (ゲリット処理は省略)

  • 開発者はサブツリーで何かを変更します (集約リポジトリ内)
  • 開発者はリポジトリの集約をコミットします
  • 開発者は変更を元のリポジトリにプッシュすることを忘れません (意味がありません!)
  • 開発者は、1 回のコミットでサブツリーの変更と集計リポジトリの変更を混在させないことを忘れない

サブモジュールと同様に、コード/変更が存在する場所 (レポ) が 2 つあっても意味がありません。私たちの場合ではありません。

別のリポジトリ

個別のリポジトリが最善の解決策のように見え、元の git の意図に従います。レポの粒度はさまざまです。最も細かいケースは、maven リリース グループごとにリポジトリを作成することですが、リポジトリが多すぎる可能性があります。また、1 つの特定の svn コミットが複数のモジュールまたはリリース グループに影響を与える頻度を考慮する必要があります。見ると、そのコミットは通常 3 ~ 4 のリリース グループに影響し、このグループはレポを形成する必要があります。

また、少なくともAPIモジュールを実装モジュールから分離する価値があると思います。

クイズ このアプローチを使用した移行の手順、そのコスト、および総コストは何ですか?

  • git svn clone SVN_URL REPO_NAME 多かれ少なかれ細かいモジュール数ごとに

コードゲーティングをどのようにサポートできますか? VCS / ツールの観点から、どのような変更が必要ですか? ここで、完全な CI の実行に 15 分かかるとします。

  • Jenkins はレポごとに個別にトリガーされます。「含める」フィルターはありません。チェックアウト、ビルド、デプロイするだけです。

効率的な開発者ワークフローとは?

  • 開発者は、リポジトリごとにローカル/リモート機能ブランチを使用します
  • 変更を gerrit にプッシュする
  • Gerrit はテストに対して変更を検証します
  • 変更は master ブランチにマージされます
于 2013-11-19T07:50:20.250 に答える
1

私はあなたに小さな答えを与えるつもりです。それは単純で、多くのことが望まれるかもしれませんが、それも役立つかもしれません.

  1. 歴史を忘れてください。いつ必要になりますか?参照用に常に古い svn を取得しており、数か月後にはその必要性も減少します。これは常に実用的であるとは限りませんが、古いコードに対する実際のニーズが何であるかを慎重に検討してください。

  2. ブランチを広く使用します。

  3. さまざまなモジュールに異なる git リポジトリを使用します。

  4. git で何をするかを決めるときは、svn モデルを忘れてください。

ところで、履歴が必要な場合-$ git svn clone http://svn/repo/here/trunk

于 2013-11-13T23:03:44.593 に答える
1

また、履歴を SVN から Git に移動する必要はないと思います。本当に履歴を保存する必要がある場合は、古い SVN リポジトリを読み取り専用モードにしておいてください。IME、SVN は Git とは大きく異なるため、履歴を変換すると、実際には誤解を招く履歴が生成される可能性があります。

独立したビルド プロセスを持つものごとに個別の git リポジトリを使用します。それは、モジュール レベルであるか、多かれ少なかれ細かい粒度である可能性があります。次に、本当に必要な場合は、これらのリポジトリを、ディレクトリ構造とサブモジュールのみを持つ「スーパー」リポジトリと一緒に「つなぎ合わせる」ことができます。

フックと構成を使用して、マスターおよびその他の共有ブランチへの強制プッシュを防止します。これはめったに実行する必要がなく、回復プロセスの一部としてのみ実行する必要があるため、開発者ではなく管理者が実行する必要があります。ただし、開発者が自分自身または他のユーザーとコミットおよびブランチを共有するために使用できるブランチの既知の「名前空間」を提供し、それらのブランチを簡単に強制プッシュできるようにします。

開発者による多くのプライベート ブランチ作成を奨励​​しますが、共有ブランチの作成 (ブランチ) および削除 (マージ) の明確で管理されたプロセスを用意します。Merge vs. rebase vs. rebase --squash は、コミットを開発者ブランチから共有ブランチに移動するための未解決の問題ですが、チームとして決定を下し、全員が 1 つのスタイルを使用します。(私はマージを好みますが、他のものも受け入れられます。) Gerrit などをできるだけ早く実装して、コードが共有ブランチに表示される前にレビューされ、開発者から共有ブランチへのコミットの移動が自動化されるようにします (ポリシーをプロセスに変換します)。 )。

HTH

于 2013-11-15T20:08:06.857 に答える