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
This commit is contained in:
commit
ae71760d24
@ -80,6 +80,17 @@ COMMANDS
|
|||||||
When passed to 'init' or 'clone' this regular expression will
|
When passed to 'init' or 'clone' this regular expression will
|
||||||
be preserved as a config key. See 'fetch' for a description
|
be preserved as a config key. See 'fetch' for a description
|
||||||
of '--ignore-paths'.
|
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'::
|
||||||
Fetch unfetched revisions from the Subversion remote we are
|
Fetch unfetched revisions from the Subversion remote we are
|
||||||
@ -338,6 +349,10 @@ Any other arguments are passed directly to 'git log'
|
|||||||
Shows the Subversion externals. Use -r/--revision to specify a
|
Shows the Subversion externals. Use -r/--revision to specify a
|
||||||
specific revision.
|
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'::
|
'reset'::
|
||||||
Undoes the effects of 'fetch' back to the specified revision.
|
Undoes the effects of 'fetch' back to the specified revision.
|
||||||
This allows you to re-'fetch' an SVN revision. Normally the
|
This allows you to re-'fetch' an SVN revision. Normally the
|
||||||
|
67
git-svn.perl
67
git-svn.perl
@ -19,6 +19,7 @@ $ENV{GIT_DIR} ||= '.git';
|
|||||||
$Git::SVN::default_repo_id = 'svn';
|
$Git::SVN::default_repo_id = 'svn';
|
||||||
$Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
|
$Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
|
||||||
$Git::SVN::Ra::_log_window_size = 100;
|
$Git::SVN::Ra::_log_window_size = 100;
|
||||||
|
$Git::SVN::_minimize_url = 'unset';
|
||||||
|
|
||||||
$Git::SVN::Log::TZ = $ENV{TZ};
|
$Git::SVN::Log::TZ = $ENV{TZ};
|
||||||
$ENV{TZ} = 'UTC';
|
$ENV{TZ} = 'UTC';
|
||||||
@ -31,6 +32,7 @@ require SVN::Delta;
|
|||||||
if ($SVN::Core::VERSION lt '1.1.0') {
|
if ($SVN::Core::VERSION lt '1.1.0') {
|
||||||
fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
|
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 @Git::SVN::Ra::ISA, 'SVN::Ra';
|
||||||
push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
|
push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
|
||||||
push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
|
push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
|
||||||
@ -40,6 +42,7 @@ use IO::File qw//;
|
|||||||
use File::Basename qw/dirname basename/;
|
use File::Basename qw/dirname basename/;
|
||||||
use File::Path qw/mkpath/;
|
use File::Path qw/mkpath/;
|
||||||
use File::Spec;
|
use File::Spec;
|
||||||
|
use File::Find;
|
||||||
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
|
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
|
||||||
use IPC::Open3;
|
use IPC::Open3;
|
||||||
use Git;
|
use Git;
|
||||||
@ -98,7 +101,7 @@ my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
|
|||||||
'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
|
'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
|
||||||
'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
|
'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
|
||||||
'stdlayout|s' => \$_stdlayout,
|
'stdlayout|s' => \$_stdlayout,
|
||||||
'minimize-url|m' => \$Git::SVN::_minimize_url,
|
'minimize-url|m!' => \$Git::SVN::_minimize_url,
|
||||||
'no-metadata' => sub { $icv{noMetadata} = 1 },
|
'no-metadata' => sub { $icv{noMetadata} = 1 },
|
||||||
'use-svm-props' => sub { $icv{useSvmProps} = 1 },
|
'use-svm-props' => sub { $icv{useSvmProps} = 1 },
|
||||||
'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
|
'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
|
||||||
@ -217,6 +220,10 @@ my %cmd = (
|
|||||||
"Undo fetches back to the specified SVN revision",
|
"Undo fetches back to the specified SVN revision",
|
||||||
{ 'revision|r=s' => \$_revision,
|
{ 'revision|r=s' => \$_revision,
|
||||||
'parent|p' => \$_fetch_parent } ],
|
'parent|p' => \$_fetch_parent } ],
|
||||||
|
'gc' => [ \&cmd_gc,
|
||||||
|
"Compress unhandled.log files in .git/svn and remove " .
|
||||||
|
"index files in .git/svn",
|
||||||
|
{} ],
|
||||||
);
|
);
|
||||||
|
|
||||||
my $cmd;
|
my $cmd;
|
||||||
@ -393,6 +400,10 @@ sub cmd_init {
|
|||||||
init_subdir(@_);
|
init_subdir(@_);
|
||||||
do_git_init_db();
|
do_git_init_db();
|
||||||
|
|
||||||
|
if ($Git::SVN::_minimize_url eq 'unset') {
|
||||||
|
$Git::SVN::_minimize_url = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Git::SVN->init($url);
|
Git::SVN->init($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,9 +666,22 @@ sub cmd_branch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unless (defined $glob) {
|
unless (defined $glob) {
|
||||||
die "Unknown ",
|
my $dest_re = qr/\b\Q$_branch_dest\E\b/;
|
||||||
$_tag ? "tag" : "branch",
|
foreach my $g (@{$allglobs}) {
|
||||||
" destination $_branch_dest\n";
|
$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/};
|
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
|
||||||
@ -1107,6 +1131,14 @@ sub cmd_reset {
|
|||||||
print "r$r = $c ($gs->{ref_id})\n";
|
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 #########################
|
########################### utility functions #########################
|
||||||
|
|
||||||
sub rebase_cmd {
|
sub rebase_cmd {
|
||||||
@ -1527,6 +1559,25 @@ sub md5sum {
|
|||||||
return $md5->hexdigest();
|
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;
|
package Git::SVN;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
@ -3954,7 +4005,7 @@ sub repo_path {
|
|||||||
sub url_path {
|
sub url_path {
|
||||||
my ($self, $path) = @_;
|
my ($self, $path) = @_;
|
||||||
if ($self->{url} =~ m#^https?://#) {
|
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);
|
$self->{url} . '/' . $self->repo_path($path);
|
||||||
}
|
}
|
||||||
@ -4780,7 +4831,11 @@ sub minimize_url {
|
|||||||
my $c = '';
|
my $c = '';
|
||||||
do {
|
do {
|
||||||
$url .= "/$c" if length $c;
|
$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));
|
} while ($@ && ($c = shift @components));
|
||||||
$url;
|
$url;
|
||||||
}
|
}
|
||||||
|
@ -27,4 +27,6 @@ test_expect_success 'clone trunk with "-r HEAD"' '
|
|||||||
( cd g && git rev-parse --symbolic --verify HEAD )
|
( cd g && git rev-parse --symbolic --verify HEAD )
|
||||||
'
|
'
|
||||||
|
|
||||||
|
stop_httpd
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
44
t/t9143-git-svn-gc.sh
Executable file
44
t/t9143-git-svn-gc.sh
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user