Skip to content

Commit

Permalink
Merge git://git.bogomips.org/git-svn
Browse files Browse the repository at this point in the history
* git://git.bogomips.org/git-svn:
  git svn: make minimize URL more reliable over http(s)
  git svn: avoid escaping '/' when renaming/copying files
  t9142: stop httpd after the test
  git svn: the branch command no longer needs the full path
  git svn: revert default behavior for --minimize-url
  git svn: add gc command
  • Loading branch information
Junio C Hamano committed Jul 26, 2009
2 parents 71c020c + 5f8b2cb commit ae71760
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 6 deletions.
15 changes: 15 additions & 0 deletions Documentation/git-svn.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ COMMANDS
When passed to 'init' or 'clone' this regular expression will
be preserved as a config key. See 'fetch' for a description
of '--ignore-paths'.
--no-minimize-url;;
When tracking multiple directories (using --stdlayout,
--branches, or --tags options), git svn will attempt to connect
to the root (or highest allowed level) of the Subversion
repository. This default allows better tracking of history if
entire projects are moved within a repository, but may cause
issues on repositories where read access restrictions are in
place. Passing '--no-minimize-url' will allow git svn to
accept URLs as-is without attempting to connect to a higher
level directory. This option is off by default when only
one URL/branch is tracked (it would do little good).

'fetch'::
Fetch unfetched revisions from the Subversion remote we are
Expand Down Expand Up @@ -338,6 +349,10 @@ Any other arguments are passed directly to 'git log'
Shows the Subversion externals. Use -r/--revision to specify a
specific revision.

'gc'::
Compress $GIT_DIR/svn/<refname>/unhandled.log files in .git/svn
and remove $GIT_DIR/svn/<refname>index files in .git/svn.

'reset'::
Undoes the effects of 'fetch' back to the specified revision.
This allows you to re-'fetch' an SVN revision. Normally the
Expand Down
67 changes: 61 additions & 6 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
$Git::SVN::default_repo_id = 'svn';
$Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
$Git::SVN::Ra::_log_window_size = 100;
$Git::SVN::_minimize_url = 'unset';

$Git::SVN::Log::TZ = $ENV{TZ};
$ENV{TZ} = 'UTC';
Expand All @@ -31,6 +32,7 @@
if ($SVN::Core::VERSION lt '1.1.0') {
fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
}
my $can_compress = eval { require Compress::Zlib; 1};
push @Git::SVN::Ra::ISA, 'SVN::Ra';
push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
Expand All @@ -40,6 +42,7 @@
use File::Basename qw/dirname basename/;
use File::Path qw/mkpath/;
use File::Spec;
use File::Find;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use IPC::Open3;
use Git;
Expand Down Expand Up @@ -98,7 +101,7 @@ BEGIN
'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
'stdlayout|s' => \$_stdlayout,
'minimize-url|m' => \$Git::SVN::_minimize_url,
'minimize-url|m!' => \$Git::SVN::_minimize_url,
'no-metadata' => sub { $icv{noMetadata} = 1 },
'use-svm-props' => sub { $icv{useSvmProps} = 1 },
'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
Expand Down Expand Up @@ -217,6 +220,10 @@ BEGIN
"Undo fetches back to the specified SVN revision",
{ 'revision|r=s' => \$_revision,
'parent|p' => \$_fetch_parent } ],
'gc' => [ \&cmd_gc,
"Compress unhandled.log files in .git/svn and remove " .
"index files in .git/svn",
{} ],
);

my $cmd;
Expand Down Expand Up @@ -393,6 +400,10 @@ sub cmd_init {
init_subdir(@_);
do_git_init_db();

if ($Git::SVN::_minimize_url eq 'unset') {
$Git::SVN::_minimize_url = 0;
}

Git::SVN->init($url);
}

Expand Down Expand Up @@ -655,9 +666,22 @@ sub cmd_branch {
}
}
unless (defined $glob) {
die "Unknown ",
$_tag ? "tag" : "branch",
" destination $_branch_dest\n";
my $dest_re = qr/\b\Q$_branch_dest\E\b/;
foreach my $g (@{$allglobs}) {
$g->{path}->{left} =~ /$dest_re/ or next;
if (defined $glob) {
die "Ambiguous destination: ",
$_branch_dest, "\nmatches both '",
$glob->{path}->{left}, "' and '",
$g->{path}->{left}, "'\n";
}
$glob = $g;
}
unless (defined $glob) {
die "Unknown ",
$_tag ? "tag" : "branch",
" destination $_branch_dest\n";
}
}
}
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
Expand Down Expand Up @@ -1107,6 +1131,14 @@ sub cmd_reset {
print "r$r = $c ($gs->{ref_id})\n";
}

sub cmd_gc {
if (!$can_compress) {
warn "Compress::Zlib could not be found; unhandled.log " .
"files will not be compressed.\n";
}
find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn");
}

########################### utility functions #########################

sub rebase_cmd {
Expand Down Expand Up @@ -1527,6 +1559,25 @@ sub md5sum {
return $md5->hexdigest();
}

sub gc_directory {
if ($can_compress && -f $_ && basename($_) eq "unhandled.log") {
my $out_filename = $_ . ".gz";
open my $in_fh, "<", $_ or die "Unable to open $_: $!\n";
binmode $in_fh;
my $gz = Compress::Zlib::gzopen($out_filename, "ab") or
die "Unable to open $out_filename: $!\n";

my $res;
while ($res = sysread($in_fh, my $str, 1024)) {
$gz->gzwrite($str) or
die "Unable to write: ".$gz->gzerror()."!\n";
}
unlink $_ or die "unlink $File::Find::name: $!\n";
} elsif (-f $_ && basename($_) eq "index") {
unlink $_ or die "unlink $_: $!\n";
}
}

package Git::SVN;
use strict;
use warnings;
Expand Down Expand Up @@ -3954,7 +4005,7 @@ sub repo_path {
sub url_path {
my ($self, $path) = @_;
if ($self->{url} =~ m#^https?://#) {
$path =~ s/([^~a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
$path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg;
}
$self->{url} . '/' . $self->repo_path($path);
}
Expand Down Expand Up @@ -4780,7 +4831,11 @@ sub minimize_url {
my $c = '';
do {
$url .= "/$c" if length $c;
eval { (ref $self)->new($url)->get_latest_revnum };
eval {
my $ra = (ref $self)->new($url);
my $latest = $ra->get_latest_revnum;
$ra->get_log("", $latest, 0, 1, 0, 1, sub {});
};
} while ($@ && ($c = shift @components));
$url;
}
Expand Down
2 changes: 2 additions & 0 deletions t/t9142-git-svn-shallow-clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ test_expect_success 'clone trunk with "-r HEAD"' '
( cd g && git rev-parse --symbolic --verify HEAD )
'

stop_httpd

test_done
44 changes: 44 additions & 0 deletions t/t9143-git-svn-gc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh
#
# Copyright (c) 2009 Robert Allan Zeh

test_description='git svn gc basic tests'

. ./lib-git-svn.sh

test_expect_success 'setup directories and test repo' '
mkdir import &&
mkdir tmp &&
echo "Sample text for Subversion repository." > import/test.txt &&
svn_cmd import -m "import for git svn" import "$svnrepo" > /dev/null
'

test_expect_success 'checkout working copy from svn' \
'svn_cmd co "$svnrepo" test_wc'

test_expect_success 'set some properties to create an unhandled.log file' '
(
cd test_wc &&
svn_cmd propset foo bar test.txt &&
svn_cmd commit -m "property set"
)'

test_expect_success 'Setup repo' 'git svn init "$svnrepo"'

test_expect_success 'Fetch repo' 'git svn fetch'

test_expect_success 'make backup copy of unhandled.log' '
cp .git/svn/git-svn/unhandled.log tmp
'

test_expect_success 'git svn gc runs' 'git svn gc'

test_expect_success 'git svn gc produces a valid gzip file' '
gunzip .git/svn/git-svn/unhandled.log.gz
'

test_expect_success 'git svn gc does not change unhandled.log files' '
test_cmp .git/svn/git-svn/unhandled.log tmp/unhandled.log
'

test_done

0 comments on commit ae71760

Please sign in to comment.