git-svn: allow disabling expensive broken symlink checks
Since dbc6c74d0858d77e61e092a48d467e725211f8e9, 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>
Eric Wong committed
Jan 31, 2009 at 17:31 UTC
4c58a7111d9fb4f62ca041fc73e8aec0a2f9c800
3 files changed
+38
Documentation/git-svn.txt
+8
@@ -499,6 +499,14 @@ svn-remote.<name>.rewriteRoot::
499
the repository with a public http:// or svn:// URL in the
500
metadata so users of it will see the public URL.
501
502
+svn.brokenSymlinkWorkaround::
503
+This disables potentially expensive checks to workaround broken symlinks
504
+checked into SVN by broken clients. Set this option to "false" if you
505
+track a SVN repository with many empty blobs that are not symlinks.
506
+This option may be changed while "git-svn" is running and take effect on
507
+the next revision fetched. If unset, git-svn assumes this option to be
508
+"true".
509
+
510
--
511
512
Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps
git-svn.perl
+20
@@ -3271,10 +3271,18 @@ sub new {
3271
# do_{switch,update}
3272
sub _mark_empty_symlinks {
3273
my ($git_svn) = @_;
3274
+ my $bool = Git::config_bool('svn.brokenSymlinkWorkaround');
3275
+ return {} if (defined($bool) && ! $bool);
3276
+
3277
my %ret;
3278
my ($rev, $cmt) = $git_svn->last_rev_commit;
3279
return {} unless ($rev && $cmt);
3280
3281
+ # allow the warning to be printed for each revision we fetch to
3282
+ # ensure the user sees it. The user can also disable the workaround
3283
+ # on the repository even while git svn is running and the next
3284
+ # revision fetched will skip this expensive function.
3285
+ my $printed_warning;
3286
chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`);
3287
my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt);
3288
local $/ = "\0";
@@ -3283,6 +3291,18 @@ sub _mark_empty_symlinks {
3291
while (<$ls>) {
3292
chomp;
3293
s/\A100644 blob $empty_blob\t//o or next;
3294
+ unless ($printed_warning) {
3295
+ print STDERR "Scanning for empty symlinks, ",
3296
+ "this may take a while if you have ",
3297
+ "many empty files\n",
3298
+ "You may disable this with `",
3299
+ "git config svn.brokenSymlinkWorkaround ",
3300
+ "false'.\n",
3301
+ "This may be done in a different ",
3302
+ "terminal without restarting ",
3303
+ "git svn\n";
3304
+ $printed_warning = 1;
3305
+ }
3306
my $path = $_;
3307
my (undef, $props) =
3308
$git_svn->ra->get_file($pfx.$path, $rev, undef);
t/t9131-git-svn-empty-symlink.sh
+10
@@ -87,4 +87,14 @@ test_expect_success '"bar" is an empty file' 'test -f x/bar && ! test -s x/bar'
87
test_expect_success 'get "bar" => symlink fix from svn' \
88
'(cd x && git svn rebase)'
89
test_expect_success '"bar" becomes a symlink' 'test -L x/bar'
90
+
91
+
92
+test_expect_success 'clone using git svn' 'git svn clone -r1 "$svnrepo" y'
93
+test_expect_success 'disable broken symlink workaround' \
94
+ '(cd y && git config svn.brokenSymlinkWorkaround false)'
95
+test_expect_success '"bar" is an empty file' 'test -f y/bar && ! test -s y/bar'
96
+test_expect_success 'get "bar" => symlink fix from svn' \
97
+ '(cd y && git svn rebase)'
98
+test_expect_success '"bar" does not become a symlink' '! test -L y/bar'
99
+
100
test_done