4

私は次のように標準レイアウトでいくつかの異なるプロジェクトを持つSubversionサーバーを持っています:

ProjectA/
    trunk/
    branches/
    tags/
ProjectB/
    trunk/
        FolderOfBinaries/
        SourceFolderA/
        SourceFolderB/
        SourceFolderC/
    branches/
    tags/
        v1.0/
        v1.1/
        v2.0/
ProjectC/
    trunk/
    branches/
    tags/

ProjectBはGitに移行されますが、標準のクローンでは移行されません。プロジェクトを2つのGitリポジトリに分割したいと思います。1つは比較的頻繁に変更される大きなバイナリでいっぱいのフォルダ用で、もう1つは他のすべてのリポジトリ用です。リポジトリのクローンを完全に作成しました。これは数GBですが、binariesフォルダーはおそらくその90%であり、実行git gcには長い時間がかかります。小さな高速リポジトリを用意して、開発者が必要とする場合は、binariesフォルダをサブモジュールとして追加したいと思います。

これまでに2つの潜在的なオプションを見つけました。まず、git branch-filterGit Bookに示されているように、履歴からバイナリのフォルダーを削除するために使用できます。svndumpfilter次に、現在のSubversionリポジトリを2つに分割し、次にgit svn cloneそれぞれを個別に分割するために使用できます。

私の質問は、すべての履歴、特にブランチとタグはどうなるのかということです。2つのタグ間でバイナリが変更されていない場合でも、プロジェクト内のすべてのタグでバイナリのフォルダがどのように表示されるかを知りたいです。それは可能ですか?

編集:バイナリのフォルダはビルドアーティファクト(* .class、*。o、*。dllなど)でいっぱいではないので、それを取り除いて外部にすることはできません。バージョン管理が必要なサードパーティプログラムから出力されるバイナリがたくさんあります(OpenOfficeドキュメント、Photoshopファイルなどを考えてください)。

4

3 に答える 3

1

svndumpfilter最初にProjectBを2つのリポジトリに分割することをお勧めします。その後、を使用git svn cloneして新しいSVNリポジトリをGITリポジトリに変換できます。--includeパターンがsvndumpfilterトランク、ブランチ、およびタグフォルダーを検討する場合、分割されたリポジトリーの完全な履歴が保持されます。FolderOfBinariesしたがって、新しいバイナリリポジトリのすべての履歴を確認できます。

を使用してGITリポジトリを作成するgit svn cloneと、branchesフォルダのコンテンツがGITブランチに変換され、tagsフォルダのコンテンツがGITタグに変換されます。

于 2012-07-08T17:41:20.927 に答える
1

svndumpfilterを見てください。使い方はとても簡単です。Subversionリポジトリダンプを実行してから、フィルタを使用して、必要なものまたは不要なものを指定します。

現在のリポジトリのダンプを実行してから、svndumpfilterを2回実行します(Gitリポジトリごとに1回)。あなたはそれらを連鎖させることができます。Gitリポジトリごとに2回実行するだけです。

$ svndumpfilter include ProjectB < svn_repo_dump | svndumpfilter exclude ProjectB/trunk/folderofbinaries > svn_repos_no_binaries

一つだけ言及したいのですが、ビルドされたバイナリオブジェクトをリポジトリに保存しないでください。Subversionでは、ダンプとフィルターなしで削除することは不可能であり、リビジョンを消去する機能を備えたバージョン管理システムでも、それを行うには多くの時間と労力がかかります。それは大きなメンテナンスの頭痛の種です。

そして何のために?バイナリをバージョン管理システムに保存しても、実際には役に立ちません。バイナリを比較することはできません。履歴は役に立ちません。また、開発者以外の人がバイナリにアクセスするのは困難です。

代わりに、リリースリポジトリを使用して、バイナリをそこに保存します。Mavenを使用していなくても、Javaを使用していなくても、ArtifactoryやNexusなどのMavenリポジトリを使用できます。

于 2012-07-08T21:55:05.200 に答える
1

まあ、私はこれをなんとかすることができました、しかしそれはそれほど簡単ではありませんでした。より良い方法があるかもしれませんが、私が解決できる方法はありません。私は次のことをしました:

  1. 現在のリポジトリのダンプを作成します。svnadmin dump /opt/repo > full_dump

  2. ダンプをフィルタリングして、バイナリフォルダーを削除しますsvndumpfilter exclude *folderofbinaries* --pattern --renumber-revs --drop-empty-revs < full_dump > filtered_dumpfolderofbinaries過去に誰かが実際にバイナリをタグ(!)に直接チェックインしていたため、パターンを作成する必要がありました。そのため、次のステップはフォルダーがないために失敗していました。

  3. フィルタリングされたダンプを使用してローカルSVNリポジトリを作成します。 mkdir repo-filtered; svnadmin create repo-filtered; svnadmin load repo-filtered < filtered_dump

  4. 完全なリポジトリとフィルタリングされたリポジトリの両方を別のフォルダーに複製します(私はsvn2gitを使用しました)。フィルタリングされたリポジトリには、バイナリは含まれません。完全なリポジトリで、binariesフォルダーのみがタグAとBの間で変更された場合、新しいフィルター処理されたGitリポジトリでは、2つのタグが同じコミットを指します。これはまさに私が望んでいたことです。

  5. 完全なGitリポジトリで、Gitを使用してbinariesフォルダーを除くすべてを削除します。

バイナリフォルダーを分離するためにGitを使用しなければならなかった理由は、使用するだけでタグを維持する方法がわからなかったためですsvndumpfilter(特に、バイナリをタグに直接コミットした場合)。変換後、フィルタリングされたリポジトリと同じ動作が得られます。2つのタグ間でバイナリが変更されていない場合、両方とも同じコミットを指します。

最終ステップのコマンドは次のとおりです。

git checkout master
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter folderofbinaries -- --all
git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --prune=now

この質問から得たものです。

これで、元の4.4GBのSVNダンプファイルから80MBのソースリポジトリと1.5GBのバイナリリポジトリができました。元のSVNリポジトリの正確な状態を再現するには、binariesフォルダーをソースリポジトリのGitサブモジュールとして追加し、マンモスを1つも持たずに、それぞれに同じタグをチェックアウトします(これがすべてのタグ情報を保持する必要がある理由です)。動作が遅いGitリポジトリ。

于 2012-07-11T20:26:54.877 に答える