42

大きな Subversion リポジトリから独自のリポジトリにディレクトリを分割し、そのディレクトリ内のファイルの履歴を保持したいと考えています。

最初はいつものやり方でやってみた

svnadmin dump /path/to/repo > largerepo.dump
cat largerepo.dump | svndumpfilter include my/directory >mydir.dump

しかし、それは機能しません。ディレクトリは何年にもわたって移動およびコピーされており、ファイルはリポジトリの他の部分に移動されたり、そこから移動されたりしているためです。結果はこれらの多くです:

svndumpfilter: Invalid copy source path '/some/old/path'

次に試したのは、それら/some/old/pathが表示されるとおりに含めることです。ファイルとディレクトリの長いリストが含まれた後、svndumpfilter は完了しますが、結果のダンプをインポートしても、現在のディレクトリと同じファイルが生成されません。

では、履歴を保持しながら、そのリポジトリからディレクトリを適切に分割するにはどうすればよいですか?

編集:私は特にtrunk/myproj新しいリポジトリのトランクになりたいと思っています。さらに、新しいリポジトリには他の古いものは含まれていません。分割前に古いリビジョンに更新してファイルを取得/表示する可能性は誰にもありません。

私が試した svndumpfilter ソリューションはまさにそれを達成しますが、パス/ファイルが移動されているため、残念ながら実行できません。関連するmyproj履歴だけでなく、すべての履歴を保持する基本的にクローン+エクストラの削除であるため、ngによるソリューションは受け入れられません。

4

16 に答える 16

17

リポジトリを分割する際にも同様の問題がありました..

svndumpfilter: Invalid copy source path /dir/old_dir

この問題を回避するために私がしたことは、要求されていた、または移動したことを知っている追加の古いディレクトリを含めることでした。私の場合、3 つのディレクトリを別のディレクトリに移動しました。

例えば。フォルダ A、B、C をフォルダ D に移動しました

cat project.dump | svndumpfilter include A B C D > new.dump

これで私の問題は解決したようです。フォルダー D を残りのレポから分離することができました。反対に、DI を除外してもエラーが発生しなかった場合、D を削除しても A、B、C へのリンク/履歴は必要ないため、推測できます。

于 2009-05-22T01:47:21.937 に答える
14

この問題は、svndumpfilter によって含まれるディレクトリ/ファイルの 1 つが、最初に含まれていないツリーのセクションからコピーまたは移動された場合に発生します。

この問題を解決するには、次のスクリプトを使用します: svndumpfilter3

于 2009-07-23T08:32:51.317 に答える
6

私はそれを行うために少なくとも 4 つの異なるアプリケーションを試しましたが、実際に機能したのはsvndumpfilterINを使用する ことだけでした:

cd /usr/local/bin/
sudo wget --no-check-certificate https://raw.github.com/jasperlee108/svndumpfilterIN/master/svndumpfilter.py
sudo chmod +x svndumpfilter.py
# To be sure nothing will happened on the original repo :
cp -au /path/to/repo /tmp/largerepo.repo/
svnadmin dump /path/to/repo > /tmp/largerepo.dump
svndumpfilter.py /tmp/largerepo.dump --repo=/tmp/largerepo.repo --output-dump=/tmp/mydir.dump include my/directory

これが私が試したもので、うまくいきませんでした

于 2014-03-05T10:08:55.737 に答える
3

これは潜在的にあなたを助けるかもしれません: http://svnbook.red-bean.com/en/1.5/svn.reposadmin.maint.html#svn.reposadmin.maint.replicationからの引用

Subversion 1.5 では、svnsync は、リポジトリ全体ではなくサブセットもミラーリングする機能を拡張しました。このようなミラーを設定して維持するプロセスは、リポジトリ全体をミラーリングする場合とまったく同じですが、svnsync init を実行するときにソース リポジトリのルート URL を指定する代わりに、そのリポジトリ内のサブディレクトリの URL を指定する点が異なります。そのミラーへの同期は、そのソース リポジトリ サブディレクトリの下で変更されたビットのみをコピーするようになりました。ただし、このサポートにはいくつかの制限があります。まず、ソース リポジトリの複数のバラバラなサブディレクトリを 1 つのミラー リポジトリにミラーリングすることはできません。代わりに、両方に共通の親ディレクトリをミラーリングする必要があります。次に、フィルタリング ロジックは完全にパスベースです。そのため、ミラーリングしているサブディレクトリの名前が過去のある時点で変更された場合、指定した URL にディレクトリが表示されるため、ミラーにはリビジョンのみが含まれます。同様に、将来、ソース サブディレクトリの名前が変更された場合、同期プロセスは、指定したソース URL が無効になった時点でデータのミラーリングを停止します。

もちろん、問題は名前変更前の履歴を失うことです...

于 2009-01-21T16:46:23.987 に答える
3

私はこの問題に遭遇し、最終的に svndumpfilter2 を使用しました。

具体的には、次のコマンドです。

sudo svnadmin dump /home/setup/svn/repos/main_repl | sudo ./svndumpfilter2.py /home/setup/svn/repos/main_repl Development QA compliance > ~/main_repl_dump.trim

前述のメモリ不足エラーが発生しましたが、VM で svn を実行していたため、メモリを 2G まで増やしました。これが万人向けのオプションではないことは承知していますが、512M よりもはるかに高速に実行されることに気付きました。(2Gはおそらく必要ありませんでした)。

現在、リビジョン 18,631 を処理しています。

誰かが不思議に思うかもしれませんが、レポの一部を分割する必要があったのは、レポの別のパスにあるファイルの実装に配布するためのタグ/コピーを作成していたためです。なんらかの理由で、このプロセスにより、レポが巨大な割合に膨れ上がっていました。(現在17Gです。)

Debian Lenny 5.0.4 の SVN バージョン 1.5.6 のレプリケーション リポジトリでこれを行っています。

于 2010-03-30T19:50:01.447 に答える
3

プロジェクトを既存の結合リポジトリ (Google Code) から独自のリポジトリに正常に移行しました。ここの投稿はとても役に立ちました。

これが最終的に私のために働いたものです...

  1. hereの指示に従って、svnsync を使用して Google Code リポジトリのローカル ミラーを作成しました。
  2. svnadmin dump to foo-dumpfile
  3. cat dumpfile | ./svndumpfilter3 --untangle mymirrorrepo trunk/foo > foo-dumpfile
  4. svnadmin create foorepo
  5. svnadmin load foorepo --ignore-uuid < foo-dumpfile

ステップ 3の--untangleオプションは、svndumpfilter と svndumpfilter2 を困惑させたパスの問題をすべて解決することができました。

最初に、ステップ 5 でエラーが発生しました。

<<< Started new transaction, based on original revision 2
svnadmin: File not found: transaction '1-1', path 'trunk/foo'

しかし、Charles Calvert のブログのこの投稿では、ロードを行う前に foorepo にトランク ディレクトリを作成するだけでよいと説明されています。

于 2011-03-22T00:35:45.867 に答える
2

これは非常に複雑な状況でのワイルドでクレイジーな刺し傷ですが、 git-svn / [tailor] [3]を使用してSVNリポジトリをgitにインポートし、git-splitを使用してディレクトリを分割し、次にエクスポートして戻すのはどうでしょうか。 git-svnを使用したsvn ?

于 2010-03-22T13:48:36.590 に答える
2

この質問に対する回答も探しています(自分で対処する必要があります)。Alex の回答に基づいて 、svndumpfilter2 の問題のいくつかを修正すると主張するhttp://furius.ca/pubcode/pub/conf/common/bin/svndumpfilter3.htmlを見つけました。部分的な解決だと思います。

いいもの:

純粋な Python で Subversion の svndumpfilter を書き直したものです。これにより、ファイル/ディレクトリの除外セットと含まれているセットの間の移動/コピー操作を追加に変換することで解決できます。このオプションを使用すると、元のファイルが特定のリポジトリからフェッチされます。

懸念:

重要

一部の人々は、このスクリプトのバグを報告しており、大きなリポジトリに空のファイルが作成されるというものです。自分のリポジトリで行わなければならなかった分割ではうまく機能しましたが、他の人のリポジトリで発生する問題を修正する時間がありません

于 2010-03-22T13:41:13.307 に答える
1

特定のコマンドは次のとおりです。リポジトリが http(s):// サーバーでホストされていると仮定しますが、同じコマンドが svn:// または file:// に対して機能します。

svnadmin dump /path/to/repository > dumpfile  
svnadmin create /path/to/new_repository 
svnadmin load /path/to/new_repository < dumpfile 
svn co https://localhost/svn/new_repository_url new_repository_checkout 
cd new_repository_checkout 
svn move https://localhost/svn/new_repository_url/trunk  https://localhost/svn/new_repository_url/branches/head -m "Moving HEAD to branches" 
svn move https://localhost/svn/new_repository_url/branches/head/whatever https://localhost/svn/new_repository_url/trunk -m "Creating new trunk" 
svn update 
cd branches 
svn remove head
svn commit

これで、古いリポジトリから必要な部分が新しいリポジトリのトランクとして得られるはずです。

于 2009-01-11T19:56:02.527 に答える
0

Subdivisionは、svn リポジトリを分割するために設計された GUI ツールです。

サブディビジョンはリポジトリを分析し、ファイルがリポジトリ全体でコピーおよび移動されるときにファイルの履歴を計算します。この情報を使用すると、選択内容がインテリジェントに拡張され、「無効なコピー ソース パス」エラーがすべて回避されます。

リポジトリの分割に加えて、サブディビジョンを使用して、リポジトリからファイルを削除したり、ファイルやフォルダーを新しいリポジトリに抽出したりできます。

小さなリポジトリの場合、サブディビジョンは無料です。

于 2016-02-03T22:07:45.510 に答える
0

これはかなり古いものですが、「--skip-missing-merge-sources」を追加すると何か役に立ちますか? ありそうな...

于 2009-04-27T21:02:18.897 に答える
0

ng. による回答に基づいていますが、空のリビジョンをフィルタリングして削除しています。

ステップ 1.ダンプおよびフィルタリング:

svnadmin dump /path/to/repository > fulldumpfile
svndumpfilter include trunk/the/part/you/want --drop-empty-revs --renumber-revs < fulldumpfile > dumpfile

ステップ 2.新しいレポを作成します。(これは Tortoise SVN などでも実行できることに注意してください)

svnadmin create /path/to/new_repo

チェックアウトできるようにするために必要なもの (許可など) を追加することを忘れないでください。

ステップ 3.ベース フォルダーをチェックアウトして追加します (Tortoise SVN などでも実行できます) 。

svn checkout http://localhost/new_repo /some/checkout/path/newrepo
cd /some/checkout/path/newrepo
# to be able to create "trunk/the/part/you/want" you will need to add parent dir:
mkdir -p trunk/the/part/you
svn add trunk
svn commit -m "old base"

手順 4.フィルター処理されたダンプを読み込む

svnadmin load /path/to/new_repo < dumpfile

ステップ 5.古いルートを新しいルートに移動します (Tortoise SVN などでも実行できます) 。

cd /some/checkout/path/newrepo
svn update
svn move trunk/the/part/you/want/* trunk/
svn move tags/the/part/you/want/* tags/
svn move branches/the/part/you/want/* branches/
svn commit -m "re-structure base"

これで、古いリポジトリから必要な部分が新しいリポジトリのトランクとして得られるはずです。

于 2014-05-09T14:31:52.167 に答える
0

svndumpfilter と修正方法に関する詳細情報 - http://blog.rlucas.net/uncategorized/some-gotchas-with-using-svndumpfilter/

または、svndumpfilter2 と呼ばれるようになった svndumpfilter 置換スクリプトを試すこともできます - http://cogo.wordpress.com/2009/03/10/problems-with-svndumpfilter/

私はそのスクリプトを試していませんでした.レポのバックアップを作成してテストするのに時間が必要です(Windowsで再生するバックアップダンプがあり、Linuxスクリプトです)。

于 2010-01-21T15:01:47.290 に答える
0

履歴全体が必要ない場合は、エラーの直後から取得できます。エラーがリビジョン 412 にあった場合は、次のコマンドを使用してすぐにエラーを拾うことができます。

svnadmin dump /path/to/repo -r 413:HEAD > largerepo.dump

これも完璧な解決策ではないかもしれませんが、あなたの場合は十分かもしれません。

これをすべて 1 つのステップで行うこともできます。

svnadmin dump /path/to/repo -r 413:HEAD | svndumpfilter include my/directory > mydir.dump
于 2009-05-06T21:32:48.747 に答える
0

この問題に遭遇し、すべての無効なソース パスが解決されるまでダンプを再試行する小さなスクリプトを作成しました。

#!/usr/bin/env ruby

require 'open3'
include Open3

paths = [ "/your/path" ]
command = ""

new_path = "xx"
while (! new_path.nil?)
lines = nil
popen3(" svndumpfilter include #{paths.join(' ')} > svn.result.dump < svn.original.dump") do |i, o, err|
  i.close
  puts "Processing, please wait ..."
  lines = err.readlines
end

 new_path = nil
 lines.each do |line|
  if line =~ /Invalid copy source path '(.*)'/
    new_path = $1
  end
 end
 puts "Adding #{new_path}"
 paths << new_path
end
于 2010-05-07T23:14:04.653 に答える