From: Sam Vilain <sam.vilain@catalyst.net.nz>
To: git@vger.kernel.org
Cc: Sam Vilain <sam.vilain@catalyst.net.nz>
Subject: [PATCH 5/5] git-svn: convert SVN 1.5+ / svnmerge.py svn:mergeinfo props to parents
Date: Tue, 20 Oct 2009 15:42:03 +1300 [thread overview]
Message-ID: <1256006523-5493-6-git-send-email-sam.vilain@catalyst.net.nz> (raw)
In-Reply-To: <1256006523-5493-5-git-send-email-sam.vilain@catalyst.net.nz>
This feature is long overdue; convert SVN's merge representation to git's
as revisions are imported. This works by converting the list of revisions
in each line of the svn:mergeinfo into git revision ranges, and then
checking the latest of each of these revision ranges for A) being new and
B) now being completely merged.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
---
There's much more implemented here than is tested...
git-svn.perl | 93 ++++++++++++++++++++++++++++++++++++++++++++++
t/t9151-svn-mergeinfo.sh | 21 ++++++++++
2 files changed, 114 insertions(+), 0 deletions(-)
create mode 100644 t/t9151-svn-mergeinfo.sh
diff --git a/git-svn.perl b/git-svn.perl
index 3c2534c..244e40d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -2916,6 +2916,93 @@ sub find_extra_svk_parents {
}
}
+# note: this function should only be called if the various dirprops
+# have actually changed
+sub find_extra_svn_parents {
+ my ($self, $ed, $mergeinfo, $parents) = @_;
+ # aha! svk:merge property changed...
+
+ # We first search for merged tips which are not in our
+ # history. Then, we figure out which git revisions are in
+ # that tip, but not this revision. If all of those revisions
+ # are now marked as merge, we can add the tip as a parent.
+ my @merges = split "\n", $mergeinfo;
+ my @merge_tips;
+ my @merged_commit_ranges;
+ my $url = $self->rewrite_root || $self->{url};
+ for my $merge ( @merges ) {
+ my ($source, $revs) = split ":", $merge;
+ my $path = $source;
+ $path =~ s{^/}{};
+ my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
+ if ( !$gs ) {
+ warn "Couldn't find revmap for $url$source\n";
+ next;
+ }
+ my @ranges = split ",", $revs;
+ my ($tip, $tip_commit);
+ # find the tip
+ for my $range ( @ranges ) {
+ my ($bottom, $top) = split "-", $range;
+ $top ||= $bottom;
+ my $bottom_commit =
+ $gs->rev_map_get($bottom, $self->ra_uuid) ||
+ $gs->rev_map_get($bottom+1, $self->ra_uuid);
+ my $top_commit =
+ $gs->rev_map_get($top, $self->ra_uuid);
+
+ unless ($top_commit and $bottom_commit) {
+ warn "W:unknown path/rev in svn:mergeinfo "
+ ."dirprop: $source:$range\n";
+ next;
+ }
+
+ push @merged_commit_ranges,
+ "$bottom_commit..$top_commit";
+
+ if ( !defined $tip or $top > $tip ) {
+ $tip = $top;
+ $tip_commit = $top_commit;
+ }
+ }
+ unless (!$tip_commit or
+ grep { $_ eq $tip_commit } @$parents ) {
+ push @merge_tips, $tip_commit;
+ }
+ else {
+ push @merge_tips, undef;
+ }
+ }
+ for my $merge_tip ( @merge_tips ) {
+ my $spec = shift @merges;
+ next unless $merge_tip;
+ my @cmd = ('rev-list', "-1", $merge_tip,
+ "--not", @$parents );
+ my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+ my $new;
+ while ( <$msg_fh> ) {
+ $new=1;last;
+ }
+ command_close_pipe($msg_fh, $ctx);
+ if ( $new ) {
+ push @cmd, @merged_commit_ranges;
+ my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+ my $unmerged;
+ while ( <$msg_fh> ) {
+ $unmerged=1;last;
+ }
+ command_close_pipe($msg_fh, $ctx);
+ if ( $unmerged ) {
+ warn "W:svn cherry-pick ignored ($spec)\n";
+ }
+ else {
+ warn "Found merge parent (svn:mergeinfo prop): $merge_tip\n";
+ push @$parents, $merge_tip;
+ }
+ }
+ }
+}
+
sub make_log_entry {
my ($self, $rev, $parents, $ed) = @_;
my $untracked = $self->get_untracked($ed);
@@ -2928,6 +3015,12 @@ sub make_log_entry {
$self->find_extra_svk_parents
($ed, $props->{"svk:merge"}, \@parents);
}
+ if ( $props->{"svn:mergeinfo"} ) {
+ $self->find_extra_svn_parents
+ ($ed,
+ $props->{"svn:mergeinfo"},
+ \@parents);
+ }
}
open my $un, '>>', "$self->{dir}/unhandled.log" or croak $!;
diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh
new file mode 100644
index 0000000..7eb36e5
--- /dev/null
+++ b/t/t9151-svn-mergeinfo.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Copyright (c) 2007, 2009 Sam Vilain
+#
+
+test_description='git-svn svn mergeinfo properties'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load svn dump' "
+ svnadmin load -q '$rawsvnrepo' < '../t9151/svn-mergeinfo.dump' &&
+ git svn init --minimize-url -R svnmerge \
+ -T trunk -b branches '$svnrepo' &&
+ git svn fetch --all
+ "
+
+test_expect_success 'svn merges were represented coming in' "
+ [ `git cat-file commit HEAD | grep parent | wc -l` -eq 2 ]
+ "
+
+test_done
--
1.6.3.3
next prev parent reply other threads:[~2009-10-20 2:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-20 2:41 git-svn: add support for merges during 'git svn fetch' Sam Vilain
2009-10-20 2:41 ` [PATCH 1/5] git-svn: add test data for SVK merge, with script Sam Vilain
2009-10-20 2:42 ` [PATCH 2/5] git-svn: allow test setup script to support PERL env. var Sam Vilain
2009-10-20 2:42 ` [PATCH 3/5] git-svn: convert SVK merge tickets to extra parents Sam Vilain
2009-10-20 2:42 ` [PATCH 4/5] git-svn: add test data for SVN 1.5+ merge, with script Sam Vilain
2009-10-20 2:42 ` Sam Vilain [this message]
2009-10-20 2:46 ` git-svn: add support for merges during 'git svn fetch' Sam Vilain
2009-10-20 6:32 ` Junio C Hamano
2009-10-20 21:16 ` Eric Wong
2009-10-27 3:40 ` Nanako Shiraishi
2009-10-27 7:14 ` Eric Wong
2009-10-28 7:17 ` Junio C Hamano
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=1256006523-5493-6-git-send-email-sam.vilain@catalyst.net.nz \
--to=sam.vilain@catalyst.net.nz \
--cc=git@vger.kernel.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 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).