diff options
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-x | git-svn.perl | 91 |
1 files changed, 67 insertions, 24 deletions
diff --git a/git-svn.perl b/git-svn.perl index cf6dbbc427..4dc33801a8 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit, $_version, $_fetch_all, $_no_rebase, $_merge, $_strategy, $_dry_run, $_local, $_prefix, $_no_checkout, $_url, $_verbose, - $_git_format); + $_git_format, $_commit_url); $Git::SVN::_follow_parent = 1; my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username, 'config-dir=s' => \$Git::SVN::Ra::config_dir, @@ -127,6 +127,8 @@ my %cmd = ( 'verbose|v' => \$_verbose, 'dry-run|n' => \$_dry_run, 'fetch-all|all' => \$_fetch_all, + 'commit-url=s' => \$_commit_url, + 'revision|r=i' => \$_revision, 'no-rebase' => \$_no_rebase, %cmt_opts, %fc_opts } ], 'set-tree' => [ \&cmd_set_tree, @@ -169,7 +171,8 @@ my %cmd = ( 'color' => \$Git::SVN::Log::color, 'pager=s' => \$Git::SVN::Log::pager } ], - 'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish", + 'find-rev' => [ \&cmd_find_rev, + "Translate between SVN revision numbers and tree-ish", {} ], 'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory", { 'merge|m|M' => \$_merge, @@ -229,7 +232,9 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) { my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd); read_repo_config(\%opts); -Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')); +if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')) { + Getopt::Long::Configure('pass_through'); +} my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version, 'minimize-connections' => \$Git::SVN::Migration::_minimize, 'id|i=s' => \$Git::SVN::default_ref_id, @@ -416,6 +421,8 @@ sub cmd_dcommit { $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); + $url = $_commit_url if defined $_commit_url; + my $last_rev = $_revision if defined $_revision; if ($url) { print "Committing to $url ...\n"; } @@ -423,7 +430,6 @@ sub cmd_dcommit { die "Unable to determine upstream SVN information from ", "$head history.\nPerhaps the repository is empty."; } - my $last_rev; my ($linear_refs, $parents) = linearize_history($gs, \@refs); if ($_no_rebase && scalar(@$linear_refs) > 1) { warn "Attempting to commit more than one change while ", @@ -446,7 +452,7 @@ sub cmd_dcommit { my $cmt_rev; my %ed_opts = ( r => $last_rev, log => get_commit_entry($d)->{log}, - ra => Git::SVN::Ra->new($gs->full_url), + ra => Git::SVN::Ra->new($url), config => SVN::Core::config_get_config( $Git::SVN::Ra::config_dir ), @@ -796,8 +802,8 @@ sub cmd_commit_diff { } sub cmd_info { - my $path = canonicalize_path(shift or "."); - unless (scalar(@_) == 0) { + my $path = canonicalize_path(defined($_[0]) ? $_[0] : "."); + if (exists $_[1]) { die "Too many arguments specified\n"; } @@ -813,6 +819,10 @@ sub cmd_info { die "Unable to determine upstream SVN information from ", "working tree history\n"; } + + # canonicalize_path() will return "" to make libsvn 1.5.x happy, + $path = "." if $path eq ""; + my $full_url = $url . ($path eq "." ? "" : "/$path"); if ($_url) { @@ -980,8 +990,10 @@ sub complete_url_ls_init { if (length $pfx && $pfx !~ m#/$#) { die "--prefix='$pfx' must have a trailing slash '/'\n"; } - command_noisy('config', "svn-remote.$gs->{repo_id}.$n", - "$remote_path:refs/remotes/$pfx*"); + command_noisy('config', + "svn-remote.$gs->{repo_id}.$n", + "$remote_path:refs/remotes/$pfx*" . + ('/*' x (($remote_path =~ tr/*/*/) - 1)) ); } sub verify_ref { @@ -1420,8 +1432,12 @@ sub read_all_remotes { svn.useSvmProps/) }; $use_svm_props = $use_svm_props eq 'true' if $use_svm_props; foreach (grep { s/^svn-remote\.// } command(qw/config -l/)) { - if (m!^(.+)\.fetch=\s*(.*)\s*:\s*refs/remotes/(.+)\s*$!) { - my ($remote, $local_ref, $remote_ref) = ($1, $2, $3); + if (m!^(.+)\.fetch=\s*(.*)\s*:\s*(.+)\s*$!) { + my ($remote, $local_ref, $_remote_ref) = ($1, $2, $3); + die("svn-remote.$remote: remote ref '$_remote_ref' " + . "must start with 'refs/remotes/'\n") + unless $_remote_ref =~ m{^refs/remotes/(.+)}; + my $remote_ref = $1; $local_ref =~ s{^/}{}; $r->{$remote}->{fetch}->{$local_ref} = $remote_ref; $r->{$remote}->{svm} = {} if $use_svm_props; @@ -4113,16 +4129,38 @@ sub gs_fetch_loop_common { Git::SVN::gc(); } +sub get_dir_globbed { + my ($self, $left, $depth, $r) = @_; + + my @x = eval { $self->get_dir($left, $r) }; + return unless scalar @x == 3; + my $dirents = $x[0]; + my @finalents; + foreach my $de (keys %$dirents) { + next if $dirents->{$de}->{kind} != $SVN::Node::dir; + if ($depth > 1) { + my @args = ("$left/$de", $depth - 1, $r); + foreach my $dir ($self->get_dir_globbed(@args)) { + push @finalents, "$de/$dir"; + } + } else { + push @finalents, $de; + } + } + @finalents; +} + sub match_globs { my ($self, $exists, $paths, $globs, $r) = @_; sub get_dir_check { my ($self, $exists, $g, $r) = @_; - my @x = eval { $self->get_dir($g->{path}->{left}, $r) }; - return unless scalar @x == 3; - my $dirents = $x[0]; - foreach my $de (keys %$dirents) { - next if $dirents->{$de}->{kind} != $SVN::Node::dir; + + my @dirs = $self->get_dir_globbed($g->{path}->{left}, + $g->{path}->{depth}, + $r); + + foreach my $de (@dirs) { my $p = $g->{path}->full_path($de); next if $exists->{$p}; next if (length $g->{path}->{right} && @@ -4904,15 +4942,20 @@ sub new { my ($class, $glob) = @_; my $re = $glob; $re =~ s!/+$!!g; # no need for trailing slashes - my $nr = ($re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g); - my ($left, $right) = ($1, $2); - if ($nr > 1) { - die "Only one '*' wildcard expansion ", - "is supported (got $nr): '$glob'\n"; - } elsif ($nr == 0) { + $re =~ m!^([^*]*)(\*(?:/\*)*)([^*]*)$!; + my $temp = $re; + my ($left, $right) = ($1, $3); + $re = $2; + my $depth = $re =~ tr/*/*/; + if ($depth != $temp =~ tr/*/*/) { + die "Only one set of wildcard directories " . + "(e.g. '*' or '*/*/*') is supported: '$glob'\n"; + } + if ($depth == 0) { die "One '*' is needed for glob: '$glob'\n"; } - $re = quotemeta($left) . $re . quotemeta($right); + $re =~ s!\*!\[^/\]*!g; + $re = quotemeta($left) . "($re)" . quotemeta($right); if (length $left && !($left =~ s!/+$!!g)) { die "Missing trailing '/' on left side of: '$glob' ($left)\n"; } @@ -4921,7 +4964,7 @@ sub new { } my $left_re = qr/^\/\Q$left\E(\/|$)/; bless { left => $left, right => $right, left_regex => $left_re, - regex => qr/$re/, glob => $glob }, $class; + regex => qr/$re/, glob => $glob, depth => $depth }, $class; } sub full_path { |