From: Stefan Sperling <stsp@elego.de>
To: git@vger.kernel.org
Cc: subversion@elego.de
Subject: [PATCH] Allow multiple tag and branch directories in git-svnimport
Date: Tue, 21 Aug 2007 19:08:58 +0200 [thread overview]
Message-ID: <20070821170858.GA1721@jack.stsp.lan> (raw)
[-- Attachment #1: Type: text/plain, Size: 8182 bytes --]
With this patch, users can specify colon-seperated lists of
directories containing tags and branches, respectively.
This makes git-svnimport much more usable in the real world
because there are Subversion repositories that use a deeper
tag and branch hierarchy than the recommended hierarchy of
trunk/
tags/
branches/
The patch assumes my memleak fix patch from
http://marc.info/?l=git&m=118554191513822&w=2
but applies cleanly to current vanilla git head as well.
I'm not subscribed to the list so please Cc me in replies, thanks.
diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
index e97d15e..2cfc407 100644
--- a/Documentation/git-svnimport.txt
+++ b/Documentation/git-svnimport.txt
@@ -12,11 +12,11 @@ SYNOPSIS
[verse]
'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]
[ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]
- [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]
- [ -s start_chg ] [ -m ] [ -r ] [ -M regex ]
- [ -I <ignorefile_name> ] [ -A <author_file> ]
- [ -R <repack_each_revs>] [ -P <path_from_trunk> ]
- <SVN_repository_URL> [ <path> ]
+ [ -b branch_subdir[:branch_subdir:...] ] [ -T trunk_subdir ]
+ [ -t tag_subdir[:tag_subdir:...] ] [ -s start_chg ] [ -m ]
+ [ -r ] [ -M regex ] [ -I <ignorefile_name> ]
+ [ -A <author_file> ] [ -R <repack_each_revs>]
+ [ -P <path_from_trunk> ] <SVN_repository_URL> [ <path> ]
DESCRIPTION
@@ -26,11 +26,6 @@ repository, or incrementally import into an existing one.
SVN access is done by the SVN::Perl module.
-git-svnimport assumes that SVN repositories are organized into one
-"trunk" directory where the main development happens, "branches/FOO"
-directories for branches, and "/tags/FOO" directories for tags.
-Other subdirectories are ignored.
-
git-svnimport creates a file ".git/svn2git", which is required for
incremental SVN imports.
@@ -53,11 +48,13 @@ When importing incrementally, you might need to edit the .git/svn2git file.
-T <trunk_subdir>::
Name the SVN trunk. Default "trunk".
--t <tag_subdir>::
- Name the SVN subdirectory for tags. Default "tags".
+-t <tag_subdir[:tag_subdir:..]>::
+ Colon-seperated list of names of subdirectories containing tags.
+ Default "tags".
--b <branch_subdir>::
- Name the SVN subdirectory for branches. Default "branches".
+-b <branch_subdir[:branch_subdir:...]>::
+ Colon-seperated list of names of subdirectories containing branches.
+ Default "branches".
-o <branch-for-HEAD>::
The 'trunk' branch from SVN is imported to the 'origin' branch within
diff --git a/git-svnimport.perl b/git-svnimport.perl
index fc9ea71..96f0926 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -38,9 +38,10 @@ sub usage() {
print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from SVN
[-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]
- [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
- [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
- [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
+ [-C GIT_repository] [-t tag_subdir[:tag_subdir:...]] [-T trunk_subdir]
+ [-b branch_subdir[:branch_subdir:...]] [-d|-D] [-i] [-u] [-r]
+ [-I ignorefilename] [-s start_chg] [-m] [-M regex]
+ [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
END
exit(1);
}
@@ -48,9 +49,9 @@ END
getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv") or usage();
usage if $opt_h;
-my $tag_name = $opt_t || "tags";
-my $trunk_name = defined $opt_T ? $opt_T : "trunk";
-my $branch_name = $opt_b || "branches";
+my @tag_dirs = defined $opt_t ? split /:/,$opt_t : "tags";
+my $trunk_dir = defined $opt_T ? $opt_T : "trunk";
+my @branch_dirs = defined $opt_b ? split /:/,$opt_b : "branches";
my $project_name = $opt_P || "";
$project_name = "/" . $project_name if ($project_name);
my $repack_after = $opt_R || 1000;
@@ -68,14 +69,18 @@ my $svn_dir = $ARGV[1];
our @mergerx = ();
if ($opt_m) {
- my $branch_esc = quotemeta ($branch_name);
- my $trunk_esc = quotemeta ($trunk_name);
- @mergerx =
- (
- qr!\b(?:merg(?:ed?|ing))\b.*?\b((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
- qr!\b(?:from|of)\W+((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
- qr!\b(?:from|of)\W+(?:the )?([\w\.\-]+)[-\s]branch\b!i
- );
+ my @branch_escs;
+ foreach (@branch_dirs) { push @branch_escs, quotemeta ($_); }
+ my $trunk_esc = quotemeta ($trunk_dir);
+
+ foreach my $branch_esc (@branch_escs) {
+ push (@mergerx,
+ (
+ qr!\b(?:merg(?:ed?|ing))\b.*?\b((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
+ qr!\b(?:from|of)\W+((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
+ qr!\b(?:from|of)\W+(?:the )?([\w\.\-]+)[-\s]branch\b!i
+ ));
+ }
}
if ($opt_M) {
unshift (@mergerx, qr/$opt_M/);
@@ -452,29 +457,39 @@ sub project_path($$)
sub split_path($$) {
my($rev,$path) = @_;
- my $branch;
+ my $dir; # tag or branch dir
+
+ OUTER: foreach my $tag_dir (@tag_dirs) {
+ foreach my $branch_dir (@branch_dirs) {
+ if ($path =~ s#^/\Q$tag_dir\E/([^/]+)/?##) {
+ $dir = "/$1";
+ } elsif ($path =~ s#^/\Q$trunk_dir\E/?##) {
+ $dir = "/";
+ } elsif ($path =~ s#^/\Q$branch_dir\E/([^/]+)/?##) {
+ $dir = $1;
+ }
+ last OUTER if $dir;
+ }
+ }
- if($path =~ s#^/\Q$tag_name\E/([^/]+)/?##) {
- $branch = "/$1";
- } elsif($path =~ s#^/\Q$trunk_name\E/?##) {
- $branch = "/";
- } elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) {
- $branch = $1;
- } else {
- my %no_error = (
- "/" => 1,
- "/$tag_name" => 1,
- "/$branch_name" => 1
- );
- print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path});
- return ()
+ if (! $dir) {
+ my %no_error = ( "/" => 1, "/tags" => 1, "/branches" => 1 );
+ foreach (@tag_dirs) {
+ $no_error{"/$_"} = 1;
+ }
+ foreach (@branch_dirs) {
+ $no_error{"/$_"} = 1;
+ }
+ print STDERR "$rev: Could not determine tag or branch ",
+ "directory for path '$path'\n",
+ unless (defined $no_error{$path});
}
if ($path eq "") {
$path = "/";
} elsif ($project_name) {
$path = project_path($path, $project_name);
}
- return ($branch,$path);
+ return ($dir,$path);
}
sub branch_rev($$) {
@@ -874,9 +889,32 @@ sub commit {
$dest =~ tr/_/\./ if $opt_u;
- system('git-tag', $dest, $cid) == 0
- or die "Cannot create tag $dest: $!\n";
-
+ # Since we support multiple directories that host tags we
+ # must support repositories that contain the same tag name
+ # in different tag directories for whatever reason,
+ # e.g. tags/jim/1.0-rc3 and tags/huck/1.0-rc3
+ #
+ # Also, because in Subversion a given tag directory could
+ # exist in revision A, be deleted in revision B and later
+ # recreated under the same name in revision C, we
+ # cannot guarantee that a tag is unique simply by
+ # looking at the tag's path.
+ #
+ # So if we fail to create the tag the first time, we try
+ # to create the tag with the same name except with the
+ # revision number of the current commit appended.
+ # Users can rename tags again later after the repository
+ # has been converted if they don't like this.
+ # It's still much better than failing to convert the
+ # repository alltogether.
+ if (system('git-tag', $dest, $cid) != 0) {
+ print STDERR "Could not create tag $dest, ",
+ "trying to create tag $dest-r$revision ",
+ "instead\n";
+ $dest = "$dest-r$revision";
+ system('git-tag', $dest, $cid) == 0
+ or die "Cannot create tag $dest: $? $!\n";
+ }
print "Created tag '$dest' on '$branch'\n" if $opt_v;
}
$branches{$branch}{"LAST"} = $cid;
--
Stefan Sperling <stsp@elego.de> Software Developer
elego Software Solutions GmbH HRB 77719
Gustav-Meyer-Allee 25, Gebaeude 12 Tel: +49 30 23 45 86 96
13355 Berlin Fax: +49 30 23 45 86 95
http://www.elego.de Geschaeftsfuehrer: Olaf Wagner
[-- Attachment #2: Type: application/pgp-signature, Size: 187 bytes --]
next reply other threads:[~2007-08-21 17:16 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-21 17:08 Stefan Sperling [this message]
2007-08-21 17:38 ` [PATCH] Allow multiple tag and branch directories in git-svnimport Stefan Sperling
2007-08-21 17:46 ` Randal L. Schwartz
2007-08-22 10:24 ` Stefan Sperling
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=20070821170858.GA1721@jack.stsp.lan \
--to=stsp@elego.de \
--cc=git@vger.kernel.org \
--cc=subversion@elego.de \
/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).