git-svn: allow disabling expensive broken symlink checks

Since dbc6c74d08, git-svn has had
an expensive check for broken symlinks that exist in some
repositories.  This leads to a heavy performance hit on
repositories with many empty blobs that are not supposed to be
symlinks.

The workaround is enabled by default; and may be disabled via:

  git config svn.brokenSymlinkWorkaround false

Reported by Markus Heidelberg.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
Eric Wong 2009-01-31 17:31:12 -08:00
Родитель 1b53a076fc
Коммит 4c58a7111d
3 изменённых файлов: 38 добавлений и 0 удалений

Просмотреть файл

@ -499,6 +499,14 @@ svn-remote.<name>.rewriteRoot::
the repository with a public http:// or svn:// URL in the the repository with a public http:// or svn:// URL in the
metadata so users of it will see the public URL. metadata so users of it will see the public URL.
svn.brokenSymlinkWorkaround::
This disables potentially expensive checks to workaround broken symlinks
checked into SVN by broken clients. Set this option to "false" if you
track a SVN repository with many empty blobs that are not symlinks.
This option may be changed while "git-svn" is running and take effect on
the next revision fetched. If unset, git-svn assumes this option to be
"true".
-- --
Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps

Просмотреть файл

@ -3271,10 +3271,18 @@ sub new {
# do_{switch,update} # do_{switch,update}
sub _mark_empty_symlinks { sub _mark_empty_symlinks {
my ($git_svn) = @_; my ($git_svn) = @_;
my $bool = Git::config_bool('svn.brokenSymlinkWorkaround');
return {} if (defined($bool) && ! $bool);
my %ret; my %ret;
my ($rev, $cmt) = $git_svn->last_rev_commit; my ($rev, $cmt) = $git_svn->last_rev_commit;
return {} unless ($rev && $cmt); return {} unless ($rev && $cmt);
# allow the warning to be printed for each revision we fetch to
# ensure the user sees it. The user can also disable the workaround
# on the repository even while git svn is running and the next
# revision fetched will skip this expensive function.
my $printed_warning;
chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`); chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`);
my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt); my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt);
local $/ = "\0"; local $/ = "\0";
@ -3283,6 +3291,18 @@ sub _mark_empty_symlinks {
while (<$ls>) { while (<$ls>) {
chomp; chomp;
s/\A100644 blob $empty_blob\t//o or next; s/\A100644 blob $empty_blob\t//o or next;
unless ($printed_warning) {
print STDERR "Scanning for empty symlinks, ",
"this may take a while if you have ",
"many empty files\n",
"You may disable this with `",
"git config svn.brokenSymlinkWorkaround ",
"false'.\n",
"This may be done in a different ",
"terminal without restarting ",
"git svn\n";
$printed_warning = 1;
}
my $path = $_; my $path = $_;
my (undef, $props) = my (undef, $props) =
$git_svn->ra->get_file($pfx.$path, $rev, undef); $git_svn->ra->get_file($pfx.$path, $rev, undef);

Просмотреть файл

@ -87,4 +87,14 @@ test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar'
test_expect_success 'get "bar" => symlink fix from svn' \ test_expect_success 'get "bar" => symlink fix from svn' \
'(cd x && git svn rebase)' '(cd x && git svn rebase)'
test_expect_success '"bar" becomes a symlink' 'test -L x/bar' test_expect_success '"bar" becomes a symlink' 'test -L x/bar'
test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" y'
test_expect_success 'disable broken symlink workaround' \
'(cd y && git config svn.brokenSymlinkWorkaround false)'
test_expect_success '"bar" is an empty file' 'test -f y/bar && ! test -s y/bar'
test_expect_success 'get "bar" => symlink fix from svn' \
'(cd y && git svn rebase)'
test_expect_success '"bar" does not become a symlink' '! test -L y/bar'
test_done test_done