From: Eric Wong <normalperson@yhbt.net>
To: Junio C Hamano <junkio@cox.net>, Yann Dirson <ydirson@altern.org>
Cc: git@vger.kernel.org
Subject: [PATCH] contrib/git-svn: fix svn compat and fetch args
Date: Thu, 9 Mar 2006 03:48:47 -0800 [thread overview]
Message-ID: <20060309114846.GA11934@localdomain> (raw)
In-Reply-To: <7vacc07wwp.fsf@assigned-by-dhcp.cox.net>
'svn info' doesn't work with URLs in svn <= 1.1. Now we
only run svn info in local directories.
As a side effect, this should also work better for 'init' off
directories that are no longer in the latest revision of the
repository.
svn checkout -r<revision> arguments are fixed.
Newer versions of svn (1.2.x) seem to need URL@REV as well as
-rREV to checkout a particular revision...
Add an example in the manpage of how to track directory that has
been moved since its initial revision.
A huge thanks to Yann Dirson for the bug reporting and testing
my original patch. Thanks also to Junio C Hamano for suggesting
a safer way to use git-rev-parse.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > Junio: please don't apply this patch to git.git just yet. It seems fine
> > to me, but I haven't tested it heavily yet (Yann can help me, I hope :)
> > I hardly slept the past few days and I may have broken something badly
> > (it pasts all the tests, though).
>
> I won't be applying it then.
You can apply this one :)
> I think this part is wrong.
Cool, thanks for the example.
contrib/git-svn/git-svn.perl | 63 ++++++++++++++++++++++++++++++------------
contrib/git-svn/git-svn.txt | 32 ++++++++++++++++++++-
2 files changed, 75 insertions(+), 20 deletions(-)
1e07c915bbc3ff06967a85a71c0cbad82fa40cf6
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 3c860e4..dca4e5c 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -30,6 +30,7 @@ my $sha1_short = qr/[a-f\d]{4,40}/;
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
$_find_copies_harder, $_l, $_version, $_upgrade, $_authors);
my (@_branch_from, %tree_map, %users);
+my $_svn_co_url_revs;
my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext,
'branch|b=s' => \@_branch_from,
@@ -77,7 +78,7 @@ usage(0) if $_help;
version() if $_version;
usage(1) unless defined $cmd;
load_authors() if $_authors;
-svn_check_ignore_externals();
+svn_compat_check();
$cmd{$cmd}->[0]->(@ARGV);
exit 0;
@@ -162,7 +163,8 @@ sub rebuild {
croak "SVN repository location required: $url\n";
}
$SVN_URL ||= $url;
- $SVN_UUID ||= setup_git_svn();
+ $SVN_UUID ||= $uuid;
+ setup_git_svn();
$latest = $rev;
}
assert_revision_eq_or_unknown($rev, $c);
@@ -171,9 +173,7 @@ sub rebuild {
}
close $rev_list or croak $?;
if (!chdir $SVN_WC) {
- my @svn_co = ('svn','co',"-r$latest");
- push @svn_co, '--ignore-externals' unless $_no_ignore_ext;
- sys(@svn_co, $SVN_URL, $SVN_WC);
+ svn_cmd_checkout($SVN_URL, $latest, $SVN_WC);
chdir $SVN_WC or croak $!;
}
@@ -222,14 +222,14 @@ sub fetch {
my $base = shift @$svn_log or croak "No base revision!\n";
my $last_commit = undef;
unless (-d $SVN_WC) {
- my @svn_co = ('svn','co',"-r$base->{revision}");
- push @svn_co,'--ignore-externals' unless $_no_ignore_ext;
- sys(@svn_co, $SVN_URL, $SVN_WC);
+ svn_cmd_checkout($SVN_URL,$base->{revision},$SVN_WC);
chdir $SVN_WC or croak $!;
+ read_uuid();
$last_commit = git_commit($base, @parents);
assert_svn_wc_clean($base->{revision}, $last_commit);
} else {
chdir $SVN_WC or croak $!;
+ read_uuid();
$last_commit = file_to_s("$REV_DIR/$base->{revision}");
}
my @svn_up = qw(svn up);
@@ -275,7 +275,9 @@ sub commit {
fetch();
chdir $SVN_WC or croak $!;
- my $svn_current_rev = svn_info('.')->{'Last Changed Rev'};
+ my $info = svn_info('.');
+ read_uuid($info);
+ my $svn_current_rev = $info->{'Last Changed Rev'};
foreach my $c (@revs) {
my $mods = svn_checkout_tree($svn_current_rev, $c);
if (scalar @$mods == 0) {
@@ -314,6 +316,14 @@ sub show_ignore {
########################### utility functions #########################
+sub read_uuid {
+ return if $SVN_UUID;
+ my $info = shift || svn_info('.');
+ $SVN_UUID = $info->{'Repository UUID'} or
+ croak "Repository UUID unreadable\n";
+ s_to_file($SVN_UUID,"$GIT_DIR/$GIT_SVN/info/uuid");
+}
+
sub setup_git_svn {
defined $SVN_URL or croak "SVN repository location required\n";
unless (-d $GIT_DIR) {
@@ -323,14 +333,10 @@ sub setup_git_svn {
mkpath(["$GIT_DIR/$GIT_SVN/info"]);
mkpath([$REV_DIR]);
s_to_file($SVN_URL,"$GIT_DIR/$GIT_SVN/info/url");
- $SVN_UUID = svn_info($SVN_URL)->{'Repository UUID'} or
- croak "Repository UUID unreadable\n";
- s_to_file($SVN_UUID,"$GIT_DIR/$GIT_SVN/info/uuid");
open my $fd, '>>', "$GIT_DIR/$GIT_SVN/info/exclude" or croak $!;
print $fd '.svn',"\n";
close $fd or croak $!;
- return $SVN_UUID;
}
sub assert_svn_wc_clean {
@@ -860,7 +866,6 @@ sub git_commit {
my ($log_msg, @parents) = @_;
assert_revision_unknown($log_msg->{revision});
my $out_fh = IO::File->new_tmpfile or croak $!;
- $SVN_UUID ||= svn_info('.')->{'Repository UUID'};
map_tree_joins() if (@_branch_from && !%tree_map);
@@ -922,7 +927,16 @@ sub git_commit {
}
my @update_ref = ('git-update-ref',"refs/remotes/$GIT_SVN",$commit);
if (my $primary_parent = shift @exec_parents) {
- push @update_ref, $primary_parent;
+ $pid = fork;
+ defined $pid or croak $!;
+ if (!$pid) {
+ close STDERR;
+ close STDOUT;
+ exec 'git-rev-parse','--verify',
+ "refs/remotes/$GIT_SVN^0";
+ }
+ waitpid $pid, 0;
+ push @update_ref, $primary_parent unless $?;
}
sys(@update_ref);
sys('git-update-ref',"$GIT_SVN/revs/$log_msg->{revision}",$commit);
@@ -995,13 +1009,26 @@ sub safe_qx {
return wantarray ? @ret : join('',@ret);
}
-sub svn_check_ignore_externals {
- return if $_no_ignore_ext;
- unless (grep /ignore-externals/,(safe_qx(qw(svn co -h)))) {
+sub svn_compat_check {
+ my @co_help = safe_qx(qw(svn co -h));
+ unless (grep /ignore-externals/,@co_help) {
print STDERR "W: Installed svn version does not support ",
"--ignore-externals\n";
$_no_ignore_ext = 1;
}
+ if (grep /usage: checkout URL\[\@REV\]/,@co_help) {
+ $_svn_co_url_revs = 1;
+ }
+}
+
+# *sigh*, new versions of svn won't honor -r<rev> without URL@<rev>,
+# (and they won't honor URL@<rev> without -r<rev>, too!)
+sub svn_cmd_checkout {
+ my ($url, $rev, $dir) = @_;
+ my @cmd = ('svn','co', "-r$rev");
+ push @cmd, '--ignore-externals' unless $_no_ignore_ext;
+ $url .= "\@$rev" if $_svn_co_url_revs;
+ sys(@cmd, $url, $dir);
}
sub check_upgrade_needed {
diff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt
index 8e9a971..5fb5b7c 100644
--- a/contrib/git-svn/git-svn.txt
+++ b/contrib/git-svn/git-svn.txt
@@ -175,8 +175,8 @@ COMPATIBILITY OPTIONS
Do not use this flag unless you know exactly what you're getting
yourself into. You have been warned.
-Examples
-~~~~~~~~
+Basic Examples
+~~~~~~~~~~~~~~
Tracking and contributing to an Subversion managed-project:
@@ -234,6 +234,34 @@ This allows you to tie unfetched SVN rev
git-svn fetch 375=$(git-rev-parse HEAD)
+Advanced Example: Tracking a Reorganized Repository
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you're tracking a directory that has moved, or otherwise been
+branched or tagged off of another directory in the repository and you
+care about the full history of the project, then you can read this
+section.
+
+This is how Yann Dirson tracked the trunk of the ufoai directory when
+the /trunk directory of his repository was moved to /ufoai/trunk and
+he needed to continue tracking /ufoai/trunk where /trunk left off.
+
+ # This log message shows when the repository was reorganized::
+ r166 | ydirson | 2006-03-02 01:36:55 +0100 (Thu, 02 Mar 2006) | 1 line
+ Changed paths:
+ D /trunk
+ A /ufoai/trunk (from /trunk:165)
+
+ # First we start tracking the old revisions::
+ GIT_SVN_ID=git-oldsvn git-svn init \
+ https://svn.sourceforge.net/svnroot/ufoai/trunk
+ GIT_SVN_ID=git-oldsvn git-svn fetch -r1:165
+
+ # And now, we continue tracking the new revisions::
+ GIT_SVN_ID=git-newsvn git-svn init \
+ https://svn.sourceforge.net/svnroot/ufoai/ufoai/trunk
+ GIT_SVN_ID=git-newsvn git-svn fetch \
+ 166=`git-rev-parse refs/remotes/git-oldsvn`
+
BUGS
----
If somebody commits a conflicting changeset to SVN at a bad moment
--
1.2.4.ga2910
next prev parent reply other threads:[~2006-03-09 11:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-07 22:08 git-svn, tree moves, and --no-stop-on-copy Yann Dirson
2006-03-08 1:42 ` Eric Wong
2006-03-08 1:57 ` [PATCH] contrib/git-svn: fix UUID reading w/pre-1.2 svn; fetch args Eric Wong
2006-03-09 10:08 ` Junio C Hamano
2006-03-09 11:48 ` Eric Wong [this message]
2006-03-08 22:15 ` git-svn, tree moves, and --no-stop-on-copy Yann Dirson
2006-03-08 22:41 ` Yann Dirson
2006-03-09 11:50 ` [PATCH] contrib/git-svn: remove the --no-stop-on-copy flag Eric Wong
2006-03-08 17:02 ` git-svn, tree moves, and --no-stop-on-copy Matthias Urlichs
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=20060309114846.GA11934@localdomain \
--to=normalperson@yhbt.net \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
--cc=ydirson@altern.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.