gitに移行するときに大きなsvn履歴についてどうすればよいですか?


23

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

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

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

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

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

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


私はこれについて多くの情報を探しましたが、私の質問に答えるものは見つかりませんでした。リンクされた質問では、workaounrds(サブモジュール、別館など)は私のシナリオよりもはるかにうまく機能します。
アンダースフォースグレン


Perforceは、多くの大きなバイナリファイルに対応するように設計されているため、多くのゲーム開発者が使用しているため、gitよりも優れたオプションです。Plasticscmも一見の価値があります。
イアン

余談ですが、可能であればgitサブモジュールは使用しないでください。ビルドシステムが過度に複雑になるためです(既に複雑です)。
-IgorGanapolsky

回答:


10

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

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

これは、gitの中心的な設計決定です。正確な理由から著者(Linus Torvalds)に尋ねる必要がありますが、私の知る限り、主な理由は速度です。ネットワークアクセスを回避します。

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

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

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

  • それが実用的でない場合は、通常、アーティファクトリポジトリ(Artifactory for Maven&co。など)のバイナリファイルの方が適しています。たぶんそれはあなたのためのオプションです。

私はサブモジュールや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 logなど)をリストするだけでは、大きなファイルの影響を受けません。「git log -S」など、ファイルの内容をスキャンする必要があるものは非常に遅いですが、速度は主にI / Oによって支配されるため、実際にはgitのせいではありません。

いくつかのリビジョンを含む3 GBのリポジトリでは、「git log -S」に約1分かかります。

したがって、理想的ではありませんが、2、3 GBで十分です。おそらく10〜20 GBを超える容量がそれを推進していますが、実行可能かもしれません。試してみる必要があります。


詳細な返信ありがとうございます。私は確かにテスト文書に別館を使用することを検討します。「合理的なパフォーマンス」の基準は、おそらく「svnに近い」です。つまり、操作の速度が大幅に遅い場合、切り替えるには摩擦が大きすぎます。
アンダースフォースグレン

Git LFSは大規模なバイナリファイルストレージにも使用できると思います。
-IgorGanapolsky

@IgorG:はい、Git LFSは代替手段です。他にもあります。指摘してくれてありがとう、投稿を編集した。
sleske

4

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

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

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

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


4
「svnでgitで簡単に分岐できます。通常、マージは同じくらい簡単で、同じ落とし穴があります」、それは本当に物議をかもしている主張です。私の意見では、gitでのマージは通常簡単で、svnでは通常、マージトラッキングの半ば試みが導入された後のバージョンでも悪夢です(はい、このレポだけでなくgitで作業しています)。必要なワークフローは、機能ブランチを作成し、そのブランチ上でコードレビュー/ CIビルドを行うワークフローです。SVNで大規模なフラストレーションなしにそれを行う方法はありません。
アンダースフォースグレン

2
いや、私たちはいつもここでやっています。SVNリポジトリの157のブランチを調べて、削除できるブランチを確認しています。ここでほぼ毎日ブランチ、開発、レビュー、マージを行い、ときどきトラブルに陥りますが、これはトランクから新しいブランチを取り、その変更をマージすることで常に修正されます(したがって、後でトランクに簡単にマージできます) 。ただし、実際には古代の枝にのみ適用されます。かなりのフラストレーションがある場合、それを十分に理解していません。Gitは大規模なフラストレーションももたらします。
gbjbaanb

2
私はそれを経験していません。gitで作業するとき(私が言ったように、より小さなリポジトリで)、機能の分岐、リベース、スカッシュ、マージを行うことは非常に簡単で自然なことです。「名前変更後のツリーの競合」などは非常にまれであり、線形で単純な履歴を(rebase + squashなどを介して)エミュレートできるという事実は非常に重要です。だから:トピックに関する質問を続けるために(大きなリポジトリを持つgit):svnは私が必要とするワークフローをサポートしておらず、gitはサポートしていると仮定しましょう。
アンダースフォースグレン

1
前の会社ではgitを使用していましたが、以前はgitを使用して仕事を失っていた人がいるので、決して完璧なシステムではありません!SVNもそうではありませんが、SVNはgit IMHOよりもあなたの状況にはるかによく適合しており、動作します。トピックで、あなたが望むようにgitを動作させる方法...それが本当に申し訳ありません。
gbjbaanb

7
@gbjbaanb誰かがGitで仕事を失っている場合、彼らはひどく間違ったことをしている。
ラバーダック

2

GCCメーリングリストをご覧ください。GCCの履歴を保持しながら、GCCコンパイラのソースツリーをSVNからGITに移行することについて、現在(2015年8月と9月)議論しています。例えば参照変換機械のリポジトリGitの変換のための受け入れ基準のメールスレッドを。変換に関連するツールと手順への参照があります(見かけほど簡単ではありません。このような大きなコードベースの履歴の変換には36時間と約64GバイトのRAM、IIRCが必要です)


SVNからGitに移行するつもりですか?バージョン管理システムからコンパイラスイートへの移行は少し奇妙に思えます。また、これは回答よりもコメントのように少し読みます。
8ビットツリー

はい。タイプミスでごめんなさい。
バジルスタリンケビッチ

ありがとう。そよ風のような36時間の音は、私たちは...数週間で変換することができます
アンダースForsgren

2

SVNリポジトリ全体をGitに変換すると、複製できない巨大なリポジトリが作成される場合、SubGitを使用して、Subversionリポジトリの特定の部分の小さなGitミラーを作成できます。

たとえば、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リポジトリは適切なサイズである必要があり、開発者はGitを使用して変更をSubversionリポジトリに送信できます。

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

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


1

私は次のようにあなたの状況にアプローチします:

1)SVNリポジトリと同じディレクトリでgitリポジトリを初期化します。やるgit initgit remote add originそのgitのレポを開始します。そうすれば、準備が整うまで、一方から他方への完全な変換を処理せずに、SVNとgitを別々にコミットし続けることができます。

2)https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.htmlで説明されているように、bfgおよびフィルター分岐ツールを積極的に使用してgitリポジトリを縮小しようとします

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

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

お役に立てれば。

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