git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Olson <mwolson@gnu.org>
To: git@vger.kernel.org
Cc: Eric Wong <normalperson@yhbt.net>
Subject: [PATCH/RFC] git-svn: Allow multiple branch and tag patterns
Date: Mon, 22 Feb 2010 14:29:34 -0800	[thread overview]
Message-ID: <c8b3bef91002221429l3b277429l56f4e4cac4fdeb43@mail.gmail.com> (raw)

This change allows multiple branch and tag patterns to be specified in
.git/config for git-svn projects.  This is useful for fetching several
different parts out of the namespace of an svn repository.
Additionally, a new repeatable directive called "skip" has been added
to specify a specific tag or branch to ignore.

Signed-off-by: Michael W. Olson <mwolson@gnu.org>
---
I've been using this patch regularly for over a year on a very large
svn repository.

This patch is known to work on git 1.6.3.3 specifically.  Once I get a
few responses about whether or not it is useful, I'll rebase it
against the git.git master branch.  Some further documentation
(perhaps just a relevant example or two) would also need to be added
to the git-svn manpage.

Here is an example ~/.git/config file which works with these changes.
The example upstream svn repository has branches in tags in 2
different namespaces.  Originally all tags/branches were directly
under /root/mod/branches and /root/mod/tags.  Later on, they created
new branches and tags in subdirectories such as
/root/mod/branches/myorg/bugs/BUGID.  This config file forces
old-style branches and tags into the "old/" namespace in git, and puts
new-style branches and tags into (for example) "myorg/bugs/BUGID".
The "skip" directives prevent the first level of the new namespace
("myorg", in particular) from being replicated underneath "old/" in
git, which is for cosmetic purposes.

[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[svn-remote "svn"]
	url = https://svn.my.org/svn/root
	fetch = mod/trunk:refs/remotes/trunk
	branches = mod/branches/*:refs/remotes/old/*
        skip = branches:old/myorg
	tags = mod/tags/*:refs/remotes/tags/old/*
        skip = tags:old/myorg
	branches = mod/branches/myorg/bugs/*:refs/remotes/myorg/bugs/*
	tags = mod/tags/myorg/bugs/*:refs/remotes/tags/myorg/bugs/*
	branches = mod/branches/myorg/projects/*:refs/remotes/myorg/projects/*
	tags = mod/tags/myorg/projects/*:refs/remotes/tags/myorg/projects/*
	branches = mod/branches/myorg/releases/*:refs/remotes/myorg/releases/*
	tags = mod/tags/myorg/releases/*:refs/remotes/tags/myorg/releases/*

 git-svn.perl |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index ef1d30d..f7ec70c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1548,7 +1548,7 @@ sub fetch_all {
 	# read the max revs for wildcard expansion (branches/*, tags/*)
 	foreach my $t (qw/branches tags/) {
 		defined $remote->{$t} or next;
-		push @globs, $remote->{$t};
+		push @globs, @{$remote->{$t}};
 		my $max_rev = eval { tmp_config(qw/--int --get/,
 		                         "svn-remote.$repo_id.${t}-maxRev") };
 		if (defined $max_rev && ($max_rev < $base)) {
@@ -1592,14 +1592,17 @@ sub read_all_remotes {
 			$r->{$1}->{svm} = {};
 		} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
 			$r->{$1}->{url} = $2;
+		} elsif (m!^(.+)\.skip=(branches|tags):\s*(.*)\s*$!) {
+			push @{$r->{$1}->{skip}->{$2}}, $3;
 		} elsif (m!^(.+)\.(branches|tags)=
 		           (.*):refs/remotes/(.+)\s*$/!x) {
 			my ($p, $g) = ($3, $4);
-			my $rs = $r->{$1}->{$2} = {
+			my $rs = {
 			                  t => $2,
 					  remote => $1,
 			                  path => Git::SVN::GlobSpec->new($p),
 			                  ref => Git::SVN::GlobSpec->new($g) };
+			push @{$r->{$1}->{$2}}, $rs;
 			if (length($rs->{ref}->{right}) != 0) {
 				die "The '*' glob character must be the last ",
 				    "character of '$g'\n";
@@ -1623,6 +1626,14 @@ sub read_all_remotes {
 		}
 	} keys %$r;

+	for my $rname (keys %$r) {
+		map { $_->{skip} = $r->{$rname}->{skip}->{branches} }
+		    @{$r->{$rname}->{branches}};
+		map { $_->{skip} =
+			[ map { "tags/$_" } @{$r->{$rname}->{skip}->{tags}} ] }
+		    @{$r->{$rname}->{tags}};
+	}
+
 	$r;
 }

@@ -1744,8 +1755,9 @@ sub find_by_url { # repos_root and, path are optional

 		my $fetch = $remotes->{$repo_id}->{fetch} || {};
 		foreach (qw/branches tags/) {
-			resolve_local_globs($u, $fetch,
-			                    $remotes->{$repo_id}->{$_});
+			for my $p (@{$remotes->{$repo_id}->{$_}}) {
+				resolve_local_globs($u, $fetch, $p);
+			}
 		}
 		my $p = $path;
 		my $rwr = rewrite_root({repo_id => $repo_id});
@@ -4586,12 +4598,15 @@ sub match_globs {
 			next unless /$g->{path}->{regex}/;
 			my $p = $1;
 			my $pathname = $g->{path}->full_path($p);
+			my $refname = $g->{ref}->full_path($p);
+			next if $g->{skip} && grep { $refname eq $_ }
+						   @{$g->{skip}};
 			next if $exists->{$pathname};
 			next if ($self->check_path($pathname, $r) !=
 			         $SVN::Node::dir);
 			$exists->{$pathname} = Git::SVN->init(
 			                      $self->{url}, $pathname, undef,
-			                      $g->{ref}->full_path($p), 1);
+			                      $refname, 1);
 		}
 		my $c = '';
 		foreach (split m#/#, $g->{path}->{left}) {
-- 
1.6.3.3

             reply	other threads:[~2010-02-22 22:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-22 22:29 Michael Olson [this message]
2010-02-23  2:50 ` [PATCH/RFC] git-svn: Allow multiple branch and tag patterns Tim Stoakes
2010-02-23 10:50 ` Michael J Gruber
2010-02-23 14:41   ` Michael Olson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c8b3bef91002221429l3b277429l56f4e4cac4fdeb43@mail.gmail.com \
    --to=mwolson@gnu.org \
    --cc=git@vger.kernel.org \
    --cc=normalperson@yhbt.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).