Re: [PATCH] git-svnimport: added explicit merge graph option -G

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Junio,

Thank you for a thorough review and good suggestions. New cumulative patch is pasted and attached. 

>From: Junio C Hamano <gitster@xxxxxxxxx>
> ...
>> +# Given an SVN revision (string), returns all corresponding GIT revisions.
>> +#
>> +# Note that it is possible that one SVN revision needs to be split into two or
>> +# more GIT commits (revision). For example, this will happen if SVN user
>> +# commits two branches at once.
>> +sub svnrev_to_gitrevs($)
>> ...
>> +    my $svnrev = shift;
>> +    my @gitrevs;
>> +    for my $b (keys(%branches)) {
>> +        push (@gitrevs, $branches{$b}{$svnrev})
>> +            if defined($branches{$b}{$svnrev});
>> +    }
>> +    return @gitrevs;
>> +}
>
>Hmph.  The computation cost for this is proportional to the
>number of branches on the SVN side?  Would that be a problem in
>real-life (not an objection, but am just wondering.  "Not a
>problem, because..." is an acceptable answer).

I chose not to add and maintain an inverted data structure in parallel to %branches for simplicity.

Stas.


>From b17c89b82441dc3c5dc3155acee560a1d7f0149d Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@xxxxxxxxx>
Date: Mon, 25 Jun 2007 09:18:35 -0700
Subject: [PATCH] git-svnimport: added explicit merge graph option -G

Allows explicit merge graph information to be provided. Each line
of merge graph file must contain a pair of SVN revision numbers
separated by space. The first number is child (merged to) SVN rev
number and the second is the parent (merged from) SVN rev number.
Comments can be started with '#' and continue to the end of line.
Empty and space-only lines are allowed and will be ignored.

Signed-off-by: Stas Maximov <smaximov@xxxxxxxxx>
---
 Documentation/git-svnimport.txt |   11 +++++-
 git-svnimport.perl              |   74 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
index e97d15e..c902b64 100644
--- a/Documentation/git-svnimport.txt
+++ b/Documentation/git-svnimport.txt
@@ -13,7 +13,8 @@ SYNOPSIS
 '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 ]
+        [ -s start_chg ] [ -r ]
+        [ -m ] [ -M regex ] [-G merge_graph_file ]
         [ -I <ignorefile_name> ] [ -A <author_file> ]
         [ -R <repack_each_revs>] [ -P <path_from_trunk> ]
         <SVN_repository_URL> [ <path> ]
@@ -102,6 +103,14 @@ repository without -A.
     regex. It can be used with -m to also see the default regexes.
     You must escape forward slashes.
 
+-G <merge_graph_file>::
+    Allows explicit merge graph information to be provided. Each line
+    of merge graph file must contain a pair of SVN revision numbers
+    separated by space. The first number is child (merged to) SVN rev
+    number and the second is the parent (merged from) SVN rev number.
+    Comments can be started with '#' and continue to the end of line.
+    Empty and space-only lines are allowed and will be ignored.
+
 -l <max_rev>::
     Specify a maximum revision number to pull.
 +
diff --git a/git-svnimport.perl b/git-svnimport.perl
index b73d649..ea0bc90 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -32,7 +32,7 @@ $ENV{'TZ'}="UTC";
 
 our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
     $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,
-    $opt_P,$opt_R);
+    $opt_P,$opt_R,$opt_G);
 
 sub usage() {
     print STDERR <<END;
@@ -40,12 +40,13 @@ 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]
+       [-m] [-M regex] [-G merge_graph_file] [-A author_file]
+       [-S] [-F] [-P project_name] [SVN_URL]
 END
     exit(1);
 }
 
-getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv") or usage();
+getopts("A:b:C:dDFhiI:l:mM:G:o:rs:t:T:SP:R:uv") or usage();
 usage if $opt_h;
 
 my $tag_name = $opt_t || "tags";
@@ -80,6 +81,44 @@ if ($opt_M) {
     unshift (@mergerx, qr/$opt_M/);
 }
 
+
+# merge_graph will be used for finding all parent SVN revisions for a given SVN
+# revision. It will be implemented as a hash of arrays. Hash will be keyed with
+# the child SVN rev and contain an array of the parent SVN revisions.
+our %merge_graph;
+
+# read-in the explicit merge graph specified with -G option
+if ($opt_G) {
+    open F, '<', $opt_G
+            or die("Cannot open '$opt_G'");
+    while (<F>) {
+        chomp;
+        s/#.*//;
+        next if (/^\s*$/);
+        if (/^\s*(\d+)\s+(\d+)\s*$/) {
+            # $1: child_rev, $2: $parent_rev
+            $merge_graph{$1} ||= [];
+            push @{$merge_graph{$1}}, $2;
+        } else {
+            die "$opt_G:$. :malformed input $_\n";
+        }
+    }
+    close(F);
+}
+
+
+# Given an SVN revision (string), finds all its parent SVN revisions in the
+# merge graph.
+sub merge_graph_get_parents {
+    my $child_svnrev = shift;
+    if (exists $merge_graph{$child_svnrev}) {
+        return @{$merge_graph{$child_svnrev}};
+    }
+    return ();
+}
+
+
+
 # Absolutize filename now, since we will have chdir'ed by the time we
 # get around to opening it.
 $opt_A = File::Spec->rel2abs($opt_A) if $opt_A;
@@ -356,6 +395,23 @@ if ($opt_A) {
 
 open BRANCHES,">>", "$git_dir/svn2git";
 
+
+# Given an SVN revision (string), returns all corresponding GIT revisions.
+#
+# Note that it is possible that one SVN revision needs to be split into two or
+# more GIT commits (revision). For example, this will happen if SVN user
+# commits two branches at once.
+sub svnrev_to_gitrevs($) {
+    my $svnrev = shift;
+    my @gitrevs;
+    for my $b (keys(%branches)) {
+        push (@gitrevs, $branches{$b}{$svnrev})
+            if defined($branches{$b}{$svnrev});
+    }
+    return @gitrevs;
+}
+
+
 sub node_kind($$) {
     my ($svnpath, $revision) = @_;
     my $pool=SVN::Pool->new;
@@ -815,6 +871,18 @@ sub commit {
                     }
                 }
             }
+
+            # add parents from explicit merge graph (-G)
+            {
+                my @svnpars = merge_graph_get_parents($revision);
+                foreach my $svnp (@svnpars) {
+                    my @gitpars = svnrev_to_gitrevs($svnp);
+                    foreach my $gitp (@gitpars) {
+                        push (@parents, $gitp);
+                    }
+                }
+            }
+
             my %seen_parents = ();
             my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
             foreach my $bparent (@unique_parents) {
-- 
1.5.1.3







Attachment: 0001-git-svnimport-added-explicit-merge-graph-option-G.patch
Description: Binary data


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux