Merge git://git.bogomips.org/git-svn

* 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
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 10af599..22a0389 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -80,6 +80,17 @@
 	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
@@ -338,6 +349,10 @@
 	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
diff --git a/git-svn.perl b/git-svn.perl
index 9369acc..d075810 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -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';
@@ -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';
@@ -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;
@@ -98,7 +101,7 @@
                   '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 },
@@ -217,6 +220,10 @@
 		     "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;
@@ -393,6 +400,10 @@
 	init_subdir(@_);
 	do_git_init_db();
 
+	if ($Git::SVN::_minimize_url eq 'unset') {
+		$Git::SVN::_minimize_url = 0;
+	}
+
 	Git::SVN->init($url);
 }
 
@@ -655,9 +666,22 @@
 			}
 		}
 		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/};
@@ -1107,6 +1131,14 @@
 	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 {
@@ -1527,6 +1559,25 @@
 	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;
@@ -3954,7 +4005,7 @@
 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);
 }
@@ -4780,7 +4831,11 @@
 	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;
 }
diff --git a/t/t9142-git-svn-shallow-clone.sh b/t/t9142-git-svn-shallow-clone.sh
index fd5ad49..1236acc 100755
--- a/t/t9142-git-svn-shallow-clone.sh
+++ b/t/t9142-git-svn-shallow-clone.sh
@@ -27,4 +27,6 @@
 	( cd g && git rev-parse --symbolic --verify HEAD )
 '
 
+stop_httpd
+
 test_done
diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh
new file mode 100755
index 0000000..aaa3af0
--- /dev/null
+++ b/t/t9143-git-svn-gc.sh
@@ -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