threads / patch / 28618

patchgit-svn: Allow certain refs to be ignored

Subject: [PATCH] git-svn: Allow certain refs to be ignored

## tl;dr

5 messages between Oct 7, 2011 and Oct 14, 2011. Diffs are folded; open one to read it.

replies: 4people: 4as markdown or json

Michael Olson· Oct 7, 2011, 00:41 UTC · lore

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>
---
Re-sent by request of Piotr Krukowiecki.  This is against v1.7.4.1,
and I've been using it stably for a while.
 git-svn.perl |   38 +++++++++++++++++++++++++++++++++-----
 1 files changed, 33 insertions(+), 5 deletions(-)
Show changes to git-svn.perl +33 −5
diff --git a/git-svn.perl b/git-svn.perl
index 177dd25..541fa2d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -90,7 +90,8 @@ $_q ||= 0;
 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
                     'config-dir=s' => \$Git::SVN::Ra::config_dir,
                     'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
-                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
+                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex,
+                    'ignore-refs=s' => \$Git::SVN::Ra::_ignore_refs_regex );
 my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
 		'authors-file|A=s' => \$_authors,
 		'authors-prog=s' => \$_authors_prog,
@@ -380,9 +381,12 @@ sub do_git_init_db {
 		command_noisy('config', "$pfx.$i", $icv{$i});
 		$set = $i;
 	}
-	my $ignore_regex = \$SVN::Git::Fetcher::_ignore_regex;
-	command_noisy('config', "$pfx.ignore-paths", $$ignore_regex)
-		if defined $$ignore_regex;
+	my $ignore_paths_regex = \$SVN::Git::Fetcher::_ignore_regex;
+	command_noisy('config', "$pfx.ignore-paths", $$ignore_paths_regex)
+		if defined $$ignore_paths_regex;
+	my $ignore_refs_regex = \$Git::SVN::Ra::_ignore_refs_regex;
+	command_noisy('config', "$pfx.ignore-refs", $$ignore_refs_regex)
+		if defined $$ignore_refs_regex;
 }

 sub init_subdir {
@@ -1831,6 +1835,8 @@ sub read_all_remotes {
 			$r->{$1}->{svm} = {};
 		} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
 			$r->{$1}->{url} = $2;
+		} elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
+			$r->{$1}->{ignore_refs_regex} = $2;
 		} elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
 			my ($remote, $t, $local_ref, $remote_ref) =
 			                                     ($1, $2, $3, $4);
@@ -1867,6 +1873,16 @@ sub read_all_remotes {
 		}
 	} keys %$r;

+	foreach my $remote (keys %$r) {
+		foreach ( grep { defined $_ }
+			  map { $r->{$remote}->{$_} } qw(branches tags) ) {
+			foreach my $rs ( @$_ ) {
+				$rs->{ignore_refs_regex} =
+				    $r->{$remote}->{ignore_refs_regex};
+			}
+		}
+	}
+
 	$r;
 }

@@ -4876,7 +4892,7 @@ sub apply_diff {
 }

 package Git::SVN::Ra;
-use vars qw/@ISA $config_dir $_log_window_size/;
+use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
 use strict;
 use warnings;
 my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
@@ -5334,6 +5350,17 @@ sub get_dir_globbed {
 	@finalents;
 }

+# return value: 0 -- don't ignore, 1 -- ignore
+sub is_ref_ignored {
+	my ($g, $p) = @_;
+	my $refname = $g->{ref}->full_path($p);
+	return 1 if defined($g->{ignore_refs_regex}) &&
+	            $refname =~ m!$g->{ignore_refs_regex}!;
+	return 0 unless defined($_ignore_refs_regex);
+	return 1 if $refname =~ m!$_ignore_refs_regex!o;
+	return 0;
+}
+
 sub match_globs {
 	my ($self, $exists, $paths, $globs, $r) = @_;

@@ -5370,6 +5397,7 @@ sub match_globs {
 			next unless /$g->{path}->{regex}/;
 			my $p = $1;
 			my $pathname = $g->{path}->full_path($p);
+			next if is_ref_ignored($g, $p);
 			next if $exists->{$pathname};
 			next if ($self->check_path($pathname, $r) !=
 			         $SVN::Node::dir);
-- 
1.7.4.1
Junio C Hamano· Oct 7, 2011, 23:23 UTC · re: Michael Olson · lore

Re: [PATCH] git-svn: Allow certain refs to be ignored

Asking Eric to comment when he has time to do so.

I find these pattern matches that are not anchored on either side somewhat disturbing (e.g. --ignore-refs=master would ignore master2) but ignore-paths codepath seems to follow the same pattern, so perhaps it is in line with what git-svn users want. I dunno.

Michael Olson <mwolson@gnu.org> writes:
Show 106 quoted lines
> 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>
> ---
> Re-sent by request of Piotr Krukowiecki.  This is against v1.7.4.1,
> and I've been using it stably for a while.
>
>  git-svn.perl |   38 +++++++++++++++++++++++++++++++++-----
>  1 files changed, 33 insertions(+), 5 deletions(-)
>
> diff --git a/git-svn.perl b/git-svn.perl
> index 177dd25..541fa2d 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -90,7 +90,8 @@ $_q ||= 0;
>  my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
>                      'config-dir=s' => \$Git::SVN::Ra::config_dir,
>                      'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
> -                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
> +                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex,
> +                    'ignore-refs=s' => \$Git::SVN::Ra::_ignore_refs_regex );
>  my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
>  		'authors-file|A=s' => \$_authors,
>  		'authors-prog=s' => \$_authors_prog,
> @@ -380,9 +381,12 @@ sub do_git_init_db {
>  		command_noisy('config', "$pfx.$i", $icv{$i});
>  		$set = $i;
>  	}
> -	my $ignore_regex = \$SVN::Git::Fetcher::_ignore_regex;
> -	command_noisy('config', "$pfx.ignore-paths", $$ignore_regex)
> -		if defined $$ignore_regex;
> +	my $ignore_paths_regex = \$SVN::Git::Fetcher::_ignore_regex;
> +	command_noisy('config', "$pfx.ignore-paths", $$ignore_paths_regex)
> +		if defined $$ignore_paths_regex;
> +	my $ignore_refs_regex = \$Git::SVN::Ra::_ignore_refs_regex;
> +	command_noisy('config', "$pfx.ignore-refs", $$ignore_refs_regex)
> +		if defined $$ignore_refs_regex;
>  }
>
>  sub init_subdir {
> @@ -1831,6 +1835,8 @@ sub read_all_remotes {
>  			$r->{$1}->{svm} = {};
>  		} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
>  			$r->{$1}->{url} = $2;
> +		} elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
> +			$r->{$1}->{ignore_refs_regex} = $2;
>  		} elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
>  			my ($remote, $t, $local_ref, $remote_ref) =
>  			                                     ($1, $2, $3, $4);
> @@ -1867,6 +1873,16 @@ sub read_all_remotes {
>  		}
>  	} keys %$r;
>
> +	foreach my $remote (keys %$r) {
> +		foreach ( grep { defined $_ }
> +			  map { $r->{$remote}->{$_} } qw(branches tags) ) {
> +			foreach my $rs ( @$_ ) {
> +				$rs->{ignore_refs_regex} =
> +				    $r->{$remote}->{ignore_refs_regex};
> +			}
> +		}
> +	}
> +
>  	$r;
>  }
>
> @@ -4876,7 +4892,7 @@ sub apply_diff {
>  }
>
>  package Git::SVN::Ra;
> -use vars qw/@ISA $config_dir $_log_window_size/;
> +use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
>  use strict;
>  use warnings;
>  my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
> @@ -5334,6 +5350,17 @@ sub get_dir_globbed {
>  	@finalents;
>  }
>
> +# return value: 0 -- don't ignore, 1 -- ignore
> +sub is_ref_ignored {
> +	my ($g, $p) = @_;
> +	my $refname = $g->{ref}->full_path($p);
> +	return 1 if defined($g->{ignore_refs_regex}) &&
> +	            $refname =~ m!$g->{ignore_refs_regex}!;
> +	return 0 unless defined($_ignore_refs_regex);
> +	return 1 if $refname =~ m!$_ignore_refs_regex!o;
> +	return 0;
> +}
> +
>  sub match_globs {
>  	my ($self, $exists, $paths, $globs, $r) = @_;
>
> @@ -5370,6 +5397,7 @@ sub match_globs {
>  			next unless /$g->{path}->{regex}/;
>  			my $p = $1;
>  			my $pathname = $g->{path}->full_path($p);
> +			next if is_ref_ignored($g, $p);
>  			next if $exists->{$pathname};
>  			next if ($self->check_path($pathname, $r) !=
>  			         $SVN::Node::dir);
Michael Olson· Oct 7, 2011, 23:33 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-svn: Allow certain refs to be ignored

On Fri, Oct 7, 2011 at 4:23 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 6 quoted lines
> Asking Eric to comment when he has time to do so.
>
> I find these pattern matches that are not anchored on either side
> somewhat disturbing (e.g. --ignore-refs=master would ignore master2)
> but ignore-paths codepath seems to follow the same pattern, so perhaps it
> is in line with what git-svn users want. I dunno.

My own personal use of this takes a list of patterns, concatenates them into one giant pattern, adds '^', '$', and writes it out to .gitconfig. So I don't really have a preference, other than to make both options consistent.

-- 
Michael Olson  |  http://mwolson.org/
Eric Wong· Oct 10, 2011, 22:58 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-svn: Allow certain refs to be ignored

Junio C Hamano <gitster@pobox.com> wrote:
Show 6 quoted lines
> Asking Eric to comment when he has time to do so.
> 
> I find these pattern matches that are not anchored on either side 
> somewhat disturbing (e.g. --ignore-refs=master would ignore master2)
> but ignore-paths codepath seems to follow the same pattern, so perhaps it
> is in line with what git-svn users want. I dunno.

As stated last year, I remember wanting globs instead of regexps, but we already made the regexp mistake with ignore-paths, too :(

I don't think it's horrible with regexps, and if git-svn users find it useful, it's fine by me.

> Michael Olson <mwolson@gnu.org> writes:
> > Re-sent by request of Piotr Krukowiecki.  This is against v1.7.4.1,
> > and I've been using it stably for a while.
Michael: can you please rebase against latest and resend?  Thanks.
Piotr Krukowiecki· Oct 14, 2011, 09:24 UTC · re: Eric Wong · lore

Re: [PATCH] git-svn: Allow certain refs to be ignored

On Tue, Oct 11, 2011 at 12:58 AM, Eric Wong <normalperson@yhbt.net> wrote:
Show 13 quoted lines
> Junio C Hamano <gitster@pobox.com> wrote:
>> Asking Eric to comment when he has time to do so.
>>
>> I find these pattern matches that are not anchored on either side
>> somewhat disturbing (e.g. --ignore-refs=master would ignore master2)
>> but ignore-paths codepath seems to follow the same pattern, so perhaps it
>> is in line with what git-svn users want. I dunno.
>
> As stated last year, I remember wanting globs instead of regexps, but
> we already made the regexp mistake with ignore-paths, too :(
>
> I don't think it's horrible with regexps, and if git-svn users find it
> useful, it's fine by me.
In my case globs would be too limited. I'm using negative look-ahead
assertions to match only branches/tags for projects that are
interesting to me. With globs it's not possible AFAIK (I would have to
specify all ignored patterns by hand which would work only for known
patterns):
  ignore-paths = ^path/branches/(?!proj1|proj2)
Show 5 quoted lines
>> Michael Olson <mwolson@gnu.org> writes:
>> > Re-sent by request of Piotr Krukowiecki.  This is against v1.7.4.1,
>> > and I've been using it stably for a while.
>
> Michael: can you please rebase against latest and resend?  Thanks.

I've got following error while using the patch. I don't know it also happens without the patch...

	M	...
r216099 = 4d16d4890915f4c02ba541956957a4e4b4bed400
(refs/remotes/proj2/proj2-branch9)
Auto packing the repository for optimum performance. You may also
run "git gc" manually. See "git help gc" for more information.
Counting objects: 10284, done.
Compressing objects: 100% (7695/7695), done.
Writing objects: 100% (10284/10284), done.
Total 10284 (delta 5077), reused 0 (delta 0)
fatal: refs/remotes/proj1/trunk: not a valid SHA1
update-ref refs/heads/master refs/remotes/proj1/trunk: command
returned error: 128

$ git log -1 fatal: bad default revision 'HEAD' $ git log -1 trunk fatal: ambiguous argument 'trunk': unknown revision or path not in the working tree. Use '--' to separate paths from revisions $ ls .git/refs/remotes/ proj2

The commands I've used:

git svn init --prefix=proj2/ -Rproj2 -s --ignore-paths='^proj2/branches/(?!proj1|proj2)|^proj2/tags/(?!proj1|proj2)|^proj2/(?!trunk|branches|tags)' --ignore-refs='^refs/remotes/proj2/(?!proj1|proj2|trunk|tag)|^refs/remotes/proj2/tags/(?!proj1|proj2)' http://url/svn/repos/proj2 git svn init --prefix=proj1/ -Rproj1 -s --ignore-paths='^proj1/branches/(?!proj1|proj2)|^proj1/tags/(?!proj1|proj2)|^proj2/(?!trunk|branches|tags)' --ignore-refs='^refs/remotes/proj1/(?!proj1|proj2|trunk|tag)|^refs/remotes/proj1/tags/(?!proj1|proj2)' http://url/svn/repos/proj1 git svn fetch proj2 && git svn fetch proj1

The error happened while fetching proj2. I wonder why it tried to set master to proj1? Is my command ok? I want to have both proj1 and proj2 under one git repository.

-- 
Piotr Krukowiecki

← back to recent threads