git-svn: Allow certain refs to be ignored

Implement a new --ignore-refs option which specifies a regex of refs to ignore while importing svn history. This is a useful supplement to the --ignore-paths option, as that option only operates on the contents of branches and tags, not the branches and tags themselves. Signed-off-by: Michael Olson <mwolson@gnu.org> Acked-by: Eric Wong <normalperson@yhbt.net>

Michael Olson committed Oct 10, 2011 at 16:27 UTC cdb51a13c3cf4830d499d1138160eacdd2b8aa46
1 file changed +33 -5
git-svn.perl
+33 -5
@@ -94,7 +94,8 @@ $_q ||= 0;
94 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
95 'config-dir=s' => \$Git::SVN::Ra::config_dir,
96 'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
97 - 'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
97 + 'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex,
98 + 'ignore-refs=s' => \$Git::SVN::Ra::_ignore_refs_regex );
99 my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
100 'authors-file|A=s' => \$_authors,
101 'authors-prog=s' => \$_authors_prog,
@@ -440,9 +441,12 @@ sub do_git_init_db {
441 command_noisy('config', "$pfx.$i", $icv{$i});
442 $set = $i;
443 }
443 - my $ignore_regex = \$SVN::Git::Fetcher::_ignore_regex;
444 - command_noisy('config', "$pfx.ignore-paths", $$ignore_regex)
445 - if defined $$ignore_regex;
444 + my $ignore_paths_regex = \$SVN::Git::Fetcher::_ignore_regex;
445 + command_noisy('config', "$pfx.ignore-paths", $$ignore_paths_regex)
446 + if defined $$ignore_paths_regex;
447 + my $ignore_refs_regex = \$Git::SVN::Ra::_ignore_refs_regex;
448 + command_noisy('config', "$pfx.ignore-refs", $$ignore_refs_regex)
449 + if defined $$ignore_refs_regex;
450
451 if (defined $SVN::Git::Fetcher::_preserve_empty_dirs) {
452 my $fname = \$SVN::Git::Fetcher::_placeholder_filename;
@@ -2192,6 +2196,8 @@ sub read_all_remotes {
2196 $r->{$1}->{url} = $2;
2197 } elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
2198 $r->{$1}->{pushurl} = $2;
2199 + } elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
2200 + $r->{$1}->{ignore_refs_regex} = $2;
2201 } elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
2202 my ($remote, $t, $local_ref, $remote_ref) =
2203 ($1, $2, $3, $4);
@@ -2228,6 +2234,16 @@ sub read_all_remotes {
2234 }
2235 } keys %$r;
2236
2237 + foreach my $remote (keys %$r) {
2238 + foreach ( grep { defined $_ }
2239 + map { $r->{$remote}->{$_} } qw(branches tags) ) {
2240 + foreach my $rs ( @$_ ) {
2241 + $rs->{ignore_refs_regex} =
2242 + $r->{$remote}->{ignore_refs_regex};
2243 + }
2244 + }
2245 + }
2246 +
2247 $r;
2248 }
2249
@@ -5383,7 +5399,7 @@ sub apply_diff {
5399 }
5400
5401 package Git::SVN::Ra;
5386 -use vars qw/@ISA $config_dir $_log_window_size/;
5402 +use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
5403 use strict;
5404 use warnings;
5405 my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
@@ -5841,6 +5857,17 @@ sub get_dir_globbed {
5857 @finalents;
5858 }
5859
5860 +# return value: 0 -- don't ignore, 1 -- ignore
5861 +sub is_ref_ignored {
5862 + my ($g, $p) = @_;
5863 + my $refname = $g->{ref}->full_path($p);
5864 + return 1 if defined($g->{ignore_refs_regex}) &&
5865 + $refname =~ m!$g->{ignore_refs_regex}!;
5866 + return 0 unless defined($_ignore_refs_regex);
5867 + return 1 if $refname =~ m!$_ignore_refs_regex!o;
5868 + return 0;
5869 +}
5870 +
5871 sub match_globs {
5872 my ($self, $exists, $paths, $globs, $r) = @_;
5873
@@ -5877,6 +5904,7 @@ sub match_globs {
5904 next unless /$g->{path}->{regex}/;
5905 my $p = $1;
5906 my $pathname = $g->{path}->full_path($p);
5907 + next if is_ref_ignored($g, $p);
5908 next if $exists->{$pathname};
5909 next if ($self->check_path($pathname, $r) !=
5910 $SVN::Node::dir);