web-dev-qa-db-ja.com

gitに移行するときに大きなsvnの履歴をどうするのですか?

編集: などのいくつかの同様の質問とは異なり、GitへのマルチGB SVNリポジトリの移動 または https:// stackoverflow.com/questions/540535/managing-large-binary-files-with-git 私のシナリオには、gitサブモジュールに簡単に変換できるいくつかのサブプロジェクトや、いくつかの非常に大きなバイナリファイルは含まれていませんgit-annexによく適しています。これは単一のリポジトリであり、バイナリは、グラフィックスなどのコンパイル時のアセットであるかのように、同じリビジョンのメインソースコードに緊密に結合されたテストスイートです。

古い中/大(50ユーザー、60kリビジョン、80Gb履歴、2Gb作業コピー)コードリポジトリをsvnから切り替えることを調査しています。ユーザーの数が増えるにつれ、トランクに多くのチャーンがあり、機能が複数のコミットに分散されることが多く、コードのレビューが困難になります。また、分岐せずに不正なコードを「ゲート」する方法はありません。レビューは、トランクにコミットされた後にのみ実行できます。代替案を調査しています。私たちがgitに移動できることを望んでいましたが、いくつか問題があります。

Gitに関する限り、現在のリポジトリの問題はサイズです。そこには多くの古い残骸があり、gitに変換するときに--filter-branchでそれをクリーニングすると、サイズを1桁、約5〜10 GBに削減できます。これはまだ大きすぎます。リポジトリサイズが大きい最大の理由は、テストへの入力となるバイナリドキュメントがたくさんあることです。これらのファイルは.5mbと30mbの間で異なり、何百ものファイルがあります。また、かなり多くの変更があります。私はサブモジュール、git-annexなどを見てきましたが、完全な履歴が必要な多くのファイルの別館があるのと同じように、サブモジュールにテストがあるのは間違っているように感じます。

したがって、gitの分散された性質は、実際にそれを採用することを妨げているものです。分散については特に気にせず、安価な分岐と強力なマージ機能が欲しいだけです。 gitユーザーの99.9%がそうだと私が思うように、私たちは祝福された、裸の中央リポジトリを使用します。

Gitを使用するときに各ユーザーが完全なローカル履歴を保持する必要がある理由が理解できないのですか?ワークフローが分散化されていない場合、そのデータはユーザーのディスクで何をしているのですか?最近のバージョンのgitでは、最近の履歴のみを持つ浅いクローンを使用できることを知っています。私の質問は、これをチーム全体の標準操作モードとして実行することは実行可能ですか? gitを常に浅く構成して、完全な履歴を一元的にのみ持つことができますが、ユーザーのデフォルトの履歴は1000回転しかありませんか?もちろん、1000回転をgitに変換し、考古学のためにsvnリポジトリを保持することもできます。ただし、そのシナリオでは、テストドキュメントに次の数千回の改訂を行った後、同じ問題が再び発生します。

  • 履歴が必要なdo必要な多くのバイナリファイルを含む大きなリポジトリでgitを使用するための良いベストプラクティスは何ですか?ほとんどのベストプラクティスとチュートリアルでは、このケースを回避しているようです。彼らは少数の巨大なバイナリの問題を解決するか、バイナリを完全に削除することを提案します。
  • 浅いクローニングは通常の操作モードとして使用できますか、それとも「ハック」ですか?
  • メインソースリビジョンとサブモジュールリビジョンの間に緊密な依存関係があるコード(コンパイル時のバイナリ依存関係や単体テストスイートなど)にサブモジュールを使用できますか?
  • Gitリポジトリ(オンプレミス)の「大きすぎる」とはどのくらいの大きさですか? 4GBまで下げることができるのであれば、切り替えを避けるべきですか? 2GB?
23
Anders Forsgren

うわー、それは長い質問です(そして複雑な問題です)。やってみようと思います。

Gitを使用するときに各ユーザーが完全なローカル履歴を保持する必要がある理由が理解できないのですか?

これはgitの中心的な設計決定です。正確な理由で著者(Linus Torvalds)に尋ねる必要がありますが、私が知る限り、主な理由は速度です:すべてをローカル(高速ディスク上またはRAMにキャッシュされている)にすると、履歴の操作がはるかに速くなりますネットワークアクセスを回避する。

リポジトリサイズが大きい最大の理由は、テストへの入力となるバイナリドキュメントがたくさんあることです。これらのファイルは.5mbと30mbの間で異なり、何百ものファイルがあります。また、かなり多くの変更があります。

それが私が最初に考えたい点です。非常に多くの絶え間なく変化するバイナリファイルがソース管理にあることは、私にとって(SVNを使用している場合でも)問題があるようです。別のアプローチを使用できませんか?アイデア:

  • ソースコードとは異なり、3 MBのバイナリファイルはおそらく手書きではありません。何らかのツール/プロセスで生成された場合は、データを保存するのではなく、それをビルドに統合することを検討してください。

  • それが実用的でない場合、バイナリファイルは通常、アーティファクトリポジトリ(MavenなどのArtifactoryなど)で作成する方が適切です。多分それはあなたのためのオプションです。

私はサブモジュール、git-annexなどを見てきましたが、完全な履歴が必要な多くのファイルの別館があるのと同じように、サブモジュールにテストがあるのは間違っているように感じます。

実際、これはgit-annexが完全に適合するように見えます。 git-annexを使用すると、基本的にはファイルの内容をgitリポジトリの外部に格納できます(リポジトリには代わりにプレースホルダーが含まれます)。ファイルのコンテンツはさまざまな方法で保存でき(中央gitリポジトリ、共有ドライブ、クラウドストレージなど)、ローカルに保存するコンテンツを制御できます。

Git-annexの仕組みを誤解していませんか? git-annexは、管理するすべてのファイルの完全な履歴を保存します。ローカルに保存するファイルの内容を選択するだけです。

最後に、あなたの質問について:

履歴が必要な多くのバイナリファイルを含む大きなリポジトリでgitを使用するための良いベストプラクティスは何ですか?

私の経験では、オプションは通常次のとおりです。

  • リポジトリでのバイナリの必要性を回避します(オンデマンドで生成し、他の場所に保存します)
  • git-annex(またはGit LFSなどの同様のソリューション)を使用する
  • 大きなリポジトリでライブする(すべてのgit操作が大きなファイルの影響を受けるわけではありません。高速のコンピューターとドライブを使用している場合は、かなり機能します)

浅いクローニングは通常の操作モードとして使用できますか、それとも「ハック」ですか?

それは可能かもしれません。しかし、これで問題が解決するとは思いません。

  • 履歴のクイック検索など、完全な履歴を持つことから得られるgitの利点を失う
  • aKAIKはマージするために少なくともブランチポイントまでの履歴を持っている必要があるため、マージはトリッキーになる可能性があります。
  • ユーザーは自分のクローンのサイズを小さく保つために定期的に再クローンする必要があります
  • これはgitを使用する一般的ではない方法であるため、多くのツールで問題が発生する可能性があります

Gitリポジトリ(オンプレミス)の「大きすぎる」とはどのくらいの大きさですか? 4GBまで下げることができるのであれば、切り替えを避けるべきですか? 2GB?

それは、リポジトリの構造(いくつか/多くのファイルなど)、実行したいこと、コンピューターの強度、および忍耐力に依存します。

簡単に言うと、私の(新しいが低スペック)ラップトップでは、500 MBのファイルをコミットするのに30〜60秒かかります。履歴をリストするだけ(gitログなど)は大きなファイルの影響を受けません。 「git log -S」のようにファイルの内容をスキャンする必要がありますが、速度は主にI/Oに支配されるため、実際にはgitのせいではありません。

わずかなリビジョンの3 GBリポジトリでは、「git log -S」には約1分かかります。

したがって、理想的ではありませんが、数GBで問題ありません。 10〜20 GBを超えると、おそらくプッシュされますが、実行可能かもしれません-試す必要があります。

10
sleske

ユーザーの数が増えるにつれ、トランクに多くのチャーンがあり、機能が複数のコミットに分散されることが多く、コードのレビューが困難になります。また、分岐せずに不良コードを「ゲート」する方法はありません。レビューは、トランクにコミットした後でのみ実行できます。

Gitに移行してもこれらの問題は解決されません。これらはツールの使用方法の問題であり、同じ方法でgitを使用しても問題は残ります。

Svnでもgitと同じように簡単に分岐でき、マージは一般的に同じくらい簡単で、同じ落とし穴があります。 Gitはカーネルソースコードを使用するように設計されているため、大きなバイナリや大規模な履歴を使用している場合など、すべてのケースに当てはまるとは限らないいくつかの仮定を行いました。 DVCSの背後にある意図は、すべてのユーザーが効果的に単独で作業し、その後は共同作業を行うことです。つまり、ユーザーは独自のリポジトリ(コピー)を持ち、好きなように作業してから、変更を他のユーザーにプッシュします。 Linuxカーネル開発で使用されるフェデレーテッドシステムはこれに最適です。変更をチェーンの次の人にプッシュし、コードベースとマージしてから、次の人にプッシュして、Linusがリリースに入れます。ほとんどのチームはgitを同様に使用しますが、多くの場合、サーバー側の「ゴールド」リポジトリである上流の1人しかいないため、gitは切断されたCVCSに似ています。

最初にワークフローを変更することを検討します。gitへの移行は、より優れた作業方法が得られたときにのみ行います。ファイルまたはディレクトリの名前を変更しない場合は、SVNで分岐とマージを実装してください。マージは非常にうまくいきます。

4
gbjbaanb

SVNリポジトリ全体をGitに変換すると、クローンを作成できない巨大なリポジトリになる場合は、Subversionリポジトリの特定の部分に小さなGitミラーを作成するために SubGit を使用してみてください。

たとえば、SVNリポジトリの一部のサブディレクトリをインポートして同期することができますhttp://domain/repos/trunk/project/src

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

SubGitの使用の詳細については、その ドキュメント を参照してください。

そのディレクトリのGitミラーを作成したらすぐに、Gitリポジトリを使用して、SVNリポジトリにすぐに反映される新しい変更を送信できます。変換されたGitリポジトリのサイズを大幅に縮小するSVNリポジトリの特定の部分のみを同期し、ブランチを作成し、それらをマージして、Git側からのワークフローを使用できるためです。

または、SVNリポジトリ全体をインポートして、大きなファイルを同期から除外することもできます。

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

結果のGitリポジトリは適切なサイズである必要があり、開発者は変更をSubversionリポジトリに送信するためにGitを使用できます。

Subversionサーバーを実行し続け、SVNリポジトリと一緒にGitを使用する準備ができている場合は、このソリューションがうまく機能することに注意してください。

免責事項:私はSubGit開発者の1人です。 SubGitは、多くの無料オプションが利用可能な商用ソフトウェアです。

2
vadishev

GCCメーリングリストを調べてください。 GCCの履歴を維持しながら、 [〜#〜] gcc [〜#〜] コンパイラのソースツリーをSVNからGITに移行することについて(2015年8月&9月)議論します。たとえば、 変換機構のリポジトリgit変換の承認基準 メールスレッド;変換に関連するツールと手順への参照があります(見た目ほど簡単ではありません。このような大きなコードベース履歴の変換には36時間と約64GバイトのRAM、IIRCが必要です)。

私は次の方法であなたの状況に取り組みました:

1)SVNリポジトリと同じディレクトリでgitリポジトリを初期化します。行う git initおよびgit remote add Originそのgitリポジトリを開始します。そうすることで、準備が整うまで、SVNとgitを別々にコミットし続けることができます。

2)bfgおよびfilter-branchツールを積極的に使用して縮小してみますここで説明するように、gitリポジトリ: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3)git-annex、Git LFS、または外部ストレージサーバーのみを使用して、大きなバイナリ(ビルド時にシェルスクリプトを使用してファイルを転送)を作成します。

4)git repoでのマージ/ブランチ戦略に満足し、git repoのサイズに満足したら、svnからgitへの完全な移行を行うことができます。

お役に立てれば。

1
IgorGanapolsky