|
19 | 19 | $Git::SVN::default_repo_id = 'svn';
|
20 | 20 | $Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
|
21 | 21 | $Git::SVN::Ra::_log_window_size = 100;
|
| 22 | +$Git::SVN::_minimize_url = 'unset'; |
22 | 23 |
|
23 | 24 | $Git::SVN::Log::TZ = $ENV{TZ};
|
24 | 25 | $ENV{TZ} = 'UTC';
|
|
31 | 32 | if ($SVN::Core::VERSION lt '1.1.0') {
|
32 | 33 | fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
|
33 | 34 | }
|
| 35 | +my $can_compress = eval { require Compress::Zlib; 1}; |
34 | 36 | push @Git::SVN::Ra::ISA, 'SVN::Ra';
|
35 | 37 | push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
|
36 | 38 | push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
|
|
40 | 42 | use File::Basename qw/dirname basename/;
|
41 | 43 | use File::Path qw/mkpath/;
|
42 | 44 | use File::Spec;
|
| 45 | +use File::Find; |
43 | 46 | use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
|
44 | 47 | use IPC::Open3;
|
45 | 48 | use Git;
|
|
98 | 101 | 'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
|
99 | 102 | 'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
|
100 | 103 | 'stdlayout|s' => \$_stdlayout,
|
101 |
| - 'minimize-url|m' => \$Git::SVN::_minimize_url, |
| 104 | + 'minimize-url|m!' => \$Git::SVN::_minimize_url, |
102 | 105 | 'no-metadata' => sub { $icv{noMetadata} = 1 },
|
103 | 106 | 'use-svm-props' => sub { $icv{useSvmProps} = 1 },
|
104 | 107 | 'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
|
@@ -217,6 +220,10 @@ BEGIN
|
217 | 220 | "Undo fetches back to the specified SVN revision",
|
218 | 221 | { 'revision|r=s' => \$_revision,
|
219 | 222 | 'parent|p' => \$_fetch_parent } ],
|
| 223 | + 'gc' => [ \&cmd_gc, |
| 224 | + "Compress unhandled.log files in .git/svn and remove " . |
| 225 | + "index files in .git/svn", |
| 226 | + {} ], |
220 | 227 | );
|
221 | 228 |
|
222 | 229 | my $cmd;
|
@@ -393,6 +400,10 @@ sub cmd_init {
|
393 | 400 | init_subdir(@_);
|
394 | 401 | do_git_init_db();
|
395 | 402 |
|
| 403 | + if ($Git::SVN::_minimize_url eq 'unset') { |
| 404 | + $Git::SVN::_minimize_url = 0; |
| 405 | + } |
| 406 | + |
396 | 407 | Git::SVN->init($url);
|
397 | 408 | }
|
398 | 409 |
|
@@ -655,9 +666,22 @@ sub cmd_branch {
|
655 | 666 | }
|
656 | 667 | }
|
657 | 668 | unless (defined $glob) {
|
658 |
| - die "Unknown ", |
659 |
| - $_tag ? "tag" : "branch", |
660 |
| - " destination $_branch_dest\n"; |
| 669 | + my $dest_re = qr/\b\Q$_branch_dest\E\b/; |
| 670 | + foreach my $g (@{$allglobs}) { |
| 671 | + $g->{path}->{left} =~ /$dest_re/ or next; |
| 672 | + if (defined $glob) { |
| 673 | + die "Ambiguous destination: ", |
| 674 | + $_branch_dest, "\nmatches both '", |
| 675 | + $glob->{path}->{left}, "' and '", |
| 676 | + $g->{path}->{left}, "'\n"; |
| 677 | + } |
| 678 | + $glob = $g; |
| 679 | + } |
| 680 | + unless (defined $glob) { |
| 681 | + die "Unknown ", |
| 682 | + $_tag ? "tag" : "branch", |
| 683 | + " destination $_branch_dest\n"; |
| 684 | + } |
661 | 685 | }
|
662 | 686 | }
|
663 | 687 | my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
|
@@ -1107,6 +1131,14 @@ sub cmd_reset {
|
1107 | 1131 | print "r$r = $c ($gs->{ref_id})\n";
|
1108 | 1132 | }
|
1109 | 1133 |
|
| 1134 | +sub cmd_gc { |
| 1135 | + if (!$can_compress) { |
| 1136 | + warn "Compress::Zlib could not be found; unhandled.log " . |
| 1137 | + "files will not be compressed.\n"; |
| 1138 | + } |
| 1139 | + find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn"); |
| 1140 | +} |
| 1141 | + |
1110 | 1142 | ########################### utility functions #########################
|
1111 | 1143 |
|
1112 | 1144 | sub rebase_cmd {
|
@@ -1527,6 +1559,25 @@ sub md5sum {
|
1527 | 1559 | return $md5->hexdigest();
|
1528 | 1560 | }
|
1529 | 1561 |
|
| 1562 | +sub gc_directory { |
| 1563 | + if ($can_compress && -f $_ && basename($_) eq "unhandled.log") { |
| 1564 | + my $out_filename = $_ . ".gz"; |
| 1565 | + open my $in_fh, "<", $_ or die "Unable to open $_: $!\n"; |
| 1566 | + binmode $in_fh; |
| 1567 | + my $gz = Compress::Zlib::gzopen($out_filename, "ab") or |
| 1568 | + die "Unable to open $out_filename: $!\n"; |
| 1569 | + |
| 1570 | + my $res; |
| 1571 | + while ($res = sysread($in_fh, my $str, 1024)) { |
| 1572 | + $gz->gzwrite($str) or |
| 1573 | + die "Unable to write: ".$gz->gzerror()."!\n"; |
| 1574 | + } |
| 1575 | + unlink $_ or die "unlink $File::Find::name: $!\n"; |
| 1576 | + } elsif (-f $_ && basename($_) eq "index") { |
| 1577 | + unlink $_ or die "unlink $_: $!\n"; |
| 1578 | + } |
| 1579 | +} |
| 1580 | + |
1530 | 1581 | package Git::SVN;
|
1531 | 1582 | use strict;
|
1532 | 1583 | use warnings;
|
@@ -3954,7 +4005,7 @@ sub repo_path {
|
3954 | 4005 | sub url_path {
|
3955 | 4006 | my ($self, $path) = @_;
|
3956 | 4007 | if ($self->{url} =~ m#^https?://#) {
|
3957 |
| - $path =~ s/([^~a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; |
| 4008 | + $path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg; |
3958 | 4009 | }
|
3959 | 4010 | $self->{url} . '/' . $self->repo_path($path);
|
3960 | 4011 | }
|
@@ -4780,7 +4831,11 @@ sub minimize_url {
|
4780 | 4831 | my $c = '';
|
4781 | 4832 | do {
|
4782 | 4833 | $url .= "/$c" if length $c;
|
4783 |
| - eval { (ref $self)->new($url)->get_latest_revnum }; |
| 4834 | + eval { |
| 4835 | + my $ra = (ref $self)->new($url); |
| 4836 | + my $latest = $ra->get_latest_revnum; |
| 4837 | + $ra->get_log("", $latest, 0, 1, 0, 1, sub {}); |
| 4838 | + }; |
4784 | 4839 | } while ($@ && ($c = shift @components));
|
4785 | 4840 | $url;
|
4786 | 4841 | }
|
|
0 commit comments