git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] git-svnimport: added explicit merge graph option -G
@ 2007-06-24  7:06 Junio C Hamano
  2007-06-24  8:44 ` Peter Baumann
  2007-06-24  9:32 ` Alex Riesen
  0 siblings, 2 replies; 10+ messages in thread
From: Junio C Hamano @ 2007-06-24  7:06 UTC (permalink / raw)
  To: git; +Cc: Stas Maximov

From: Stas Maximov <smaximov@yahoo.com>
Date: Sat, 23 Jun 2007 09:06:30 -0700

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.
---

 * Stas, please give a "Signed-off-by" line, and get in the
   habit of always CC the list.

   I received a format-patch output as attachment from Stas.  As
   I cannot comment on the patch in that format, I am making a
   verbatim forward to the list.

   I'll comment on the patch separately when I am through it,
   but would appreciate comments from people who were involved
   in git-svnimport in the past, and still use it.

   "You should use git-svn instead" people can repeat that as
   usual, but at the same time it might be worth realizing that
   there are people who maintain git-svnimport being better for
   one-short importing.

 Documentation/git-svnimport.txt |   11 +++++-
 git-svnimport.perl              |   71 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 4 deletions(-)
 mode change 100644 => 100755 Documentation/git-svnimport.txt

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100644
new mode 100755
index e97d15e..c902b64
--- 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 f459762..113b252 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,39 @@ 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 hashes. First level hash will
+# be keyed with the child SVN rev and contain a hash keyed with the parent SVN
+# revisions. Values of the second level hash are not important (1 will be
+# used). The keys will be used to store the parent revs for uniqueness.
+our %merge_graph;
+
+
+# read-in the explicit merge graph specified with -G option
+if ($opt_G) {
+    open(F,"cat $opt_G | sed -e 's/#.*\$//' -e '/^\$/d' |") or
+        die("Can not open $opt_G");
+    while(<F>) {
+        chomp;
+        die "ERROR: invalid line in $opt_G: $_" unless /^\s*(\d+)\s+(\d+)\s*$/;
+        # $merge_graph{child_rev}{parent_rev} = 1;
+        $merge_graph{$1}{$2} = 1;
+    }
+    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;
+    my @parents = keys(%{$merge_graph{$child_svnrev}});
+    return @parents;
+}
+
+
 # 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 +390,24 @@ 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 +867,19 @@ 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);
+                        #print OUT "MG: $svnp -merge-> $revision\n";
+                    }
+                }
+            }
+
 			my %seen_parents = ();
 			my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
 			foreach my $bparent (@unique_parents) {
-- 
1.5.1.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread
* Re: [PATCH] git-svnimport: added explicit merge graph option -G
@ 2007-06-24 21:48 Stas Maximov
  2007-06-24 22:17 ` Junio C Hamano
  0 siblings, 1 reply; 10+ messages in thread
From: Stas Maximov @ 2007-06-24 21:48 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Peter Baumann

[-- Attachment #1: Type: text/plain, Size: 2846 bytes --]

Attached are two patches:

1. resubmission of the original patch with proper sign-off; and 
2. patch with permissions fix (thanks to Alex Reisen for pointing out);
 
 
 A few points in defense of specification of merge graph in terms of SVN rev numbers.

a) This information is often directly available from svn log records. While there is no one agreed format of svn commit messages reflecting merge information, many projects adopted their own rules about that. So it is often possible to write a project-specific script which will automate the step of creating the graph in terms of SVN revs. Suggested merge graph format serves as an interface between such scripts and git-svnimport.

As there is no need to operate in terms of git commit ids, debugging of such script does not require any import operations. 

b) Generic git tool which allows fine editing of merge lines in git repo is certainly a good thing to have, but it is more suitable for fine editing after the import completed, where only a small number of corrections is required. This tool is beyond the scope of this patch.

c) Different importers may have very different issues to deal with. The proposed patch for git-svnimport takes advantage of a notion of a changeset available in SVN. For example CVS does not have such a concept, so different means should be used there. See how options -m/-M of git-svnimport were carried over from CVS to SVN. This is likely to be the case with other importers. 


Stas.
 

----- Original Message ----
From: Peter Baumann <waste.manager@gmx.de>
To: Stas Maximov <smaximov@yahoo.com>
Cc: git@vger.kernel.org; Junio C Hamano <gitster@pobox.com>
Sent: Sunday, June 24, 2007 1:44:27 AM
Subject: Re: [PATCH] git-svnimport: added explicit merge graph option -G

[exchanging To:/Cc: as Junio just forwarded the message from Stas]

Not commenting on the patch per se, but wouldn't it make more
sense to have such functionality in a history rewriting tool like
e.g. git-branch-filter?

I had an svn import (git-svn) where I wanted to give correct
branch/merge points, too, and so I manually created a grafts file
annotating all the svn merges. Having such a thing as a _generic_ tool
which operates on grafts would be much more usefull because you get one
implementation which could be used for each and every importer out
there. Sure, you have to transform the native revision specifieres into
the GIT commit id's if you only have e.g. "merged r4711:4720 into trunk",
but these functionality is much more common to have in importers
than whats implemented in the above mentioned patch.

Another bonus point of using the grafts mechanism you'll get for free is
that you could _look_ at the commit graph in gitk *before* doing the
often expensive reimport of your project, so could be sure you haven't
forgotten to mark a merge.

-Peter Baumann



[-- Attachment #2: 0001-git-svnimport-added-explicit-merge-graph-option-G.patch --]
[-- Type: application/octet-stream, Size: 5942 bytes --]

From fd83a4e003802b6cb4dc8a2d058310f235f65e17 Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sat, 23 Jun 2007 09:06:30 -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@yahoo.com>
---
 Documentation/git-svnimport.txt |   11 +++++-
 git-svnimport.perl              |   71 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 4 deletions(-)
 mode change 100644 => 100755 Documentation/git-svnimport.txt

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100644
new mode 100755
index e97d15e..c902b64
--- 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 f459762..113b252 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,39 @@ 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 hashes. First level hash will
+# be keyed with the child SVN rev and contain a hash keyed with the parent SVN
+# revisions. Values of the second level hash are not important (1 will be
+# used). The keys will be used to store the parent revs for uniqueness.
+our %merge_graph;
+
+
+# read-in the explicit merge graph specified with -G option
+if ($opt_G) {
+    open(F,"cat $opt_G | sed -e 's/#.*\$//' -e '/^\$/d' |") or
+        die("Can not open $opt_G");
+    while(<F>) {
+        chomp;
+        die "ERROR: invalid line in $opt_G: $_" unless /^\s*(\d+)\s+(\d+)\s*$/;
+        # $merge_graph{child_rev}{parent_rev} = 1;
+        $merge_graph{$1}{$2} = 1;
+    }
+    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;
+    my @parents = keys(%{$merge_graph{$child_svnrev}});
+    return @parents;
+}
+
+
 # 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 +390,24 @@ 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 +867,19 @@ 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);
+                        #print OUT "MG: $svnp -merge-> $revision\n";
+                    }
+                }
+            }
+
 			my %seen_parents = ();
 			my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
 			foreach my $bparent (@unique_parents) {
-- 
1.5.1.3


[-- Attachment #3: 0002-Fixed-permissions-of-Documentation-git-svnimport.txt.patch --]
[-- Type: application/octet-stream, Size: 511 bytes --]

From 7008a13f1fe00fdbd90be6a12ad1197dceedaebb Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sun, 24 Jun 2007 14:23:29 -0700
Subject: [PATCH] Fixed permissions of Documentation/git-svnimport.txt


Signed-off-by: Stas Maximov <smaximov@yahoo.com>
---
 0 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 Documentation/git-svnimport.txt

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100755
new mode 100644
-- 
1.5.1.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* Re: [PATCH] git-svnimport: added explicit merge graph option -G
@ 2007-06-24 23:10 Stas Maximov
  2007-06-25  7:05 ` Junio C Hamano
  0 siblings, 1 reply; 10+ messages in thread
From: Stas Maximov @ 2007-06-24 23:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 7497 bytes --]

Junio,

Below is what I got with 

git-format-patch -p -M -s  --stdout origin

I hope this is acceptable. I checked, I do not have a MUA which preserves whitespaces such that the result is suitable for applying the patch. So I am pasting the patch below for discussion and also attaching to be suitable for applying.

Stas.

>From fd83a4e003802b6cb4dc8a2d058310f235f65e17 Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sat, 23 Jun 2007 09:06:30 -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@yahoo.com>

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100644
new mode 100755
index e97d15e..c902b64
--- 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 f459762..113b252 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,39 @@ 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 hashes. First level hash will
+# be keyed with the child SVN rev and contain a hash keyed with the parent SVN
+# revisions. Values of the second level hash are not important (1 will be
+# used). The keys will be used to store the parent revs for uniqueness.
+our %merge_graph;
+
+
+# read-in the explicit merge graph specified with -G option
+if ($opt_G) {
+    open(F,"cat $opt_G | sed -e 's/#.*\$//' -e '/^\$/d' |") or
+        die("Can not open $opt_G");
+    while(<F>) {
+        chomp;
+        die "ERROR: invalid line in $opt_G: $_" unless /^\s*(\d+)\s+(\d+)\s*$/;
+        # $merge_graph{child_rev}{parent_rev} = 1;
+        $merge_graph{$1}{$2} = 1;
+    }
+    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;
+    my @parents = keys(%{$merge_graph{$child_svnrev}});
+    return @parents;
+}
+
+
 # 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 +390,24 @@ 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 +867,19 @@ 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);
+                        #print OUT "MG: $svnp -merge-> $revision\n";
+                    }
+                }
+            }
+
             my %seen_parents = ();
             my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
             foreach my $bparent (@unique_parents) {
-- 
1.5.1.3


>From 7008a13f1fe00fdbd90be6a12ad1197dceedaebb Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sun, 24 Jun 2007 14:23:29 -0700
Subject: [PATCH] Fixed permissions of Documentation/git-svnimport.txt


Signed-off-by: Stas Maximov <smaximov@yahoo.com>

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100755
new mode 100644
-- 
1.5.1.3





----- Original Message ----
From: Junio C Hamano <gitster@pobox.com>
To: Stas Maximov <smaximov@yahoo.com>
Cc: git@vger.kernel.org; Peter Baumann <waste.manager@gmx.de>
Sent: Sunday, June 24, 2007 3:17:05 PM
Subject: Re: [PATCH] git-svnimport: added explicit merge graph option -G

Stas Maximov <smaximov@yahoo.com> writes:

> Attached are two patches:
>
> 1. resubmission of the original patch with proper sign-off; and 
> 2. patch with permissions fix (thanks to Alex Reisen for pointing out);

As you are assuming that the original patch was rejected (by
resending that as the first one here), I do not think these
changes should be in two separate commits.  Please redo them as
a single patch.

Also please do not "Attach".  When you have N patches to send,
send N e-mail messages, numbered from [PATCH 1/N] to [PATCH
N/N], each with one patch in the message itself.

Please see Documentation/SubmittingPatches.




[-- Attachment #2: 0001-git-svnimport-added-explicit-merge-graph-option-G.patch --]
[-- Type: application/octet-stream, Size: 6094 bytes --]

From fd83a4e003802b6cb4dc8a2d058310f235f65e17 Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sat, 23 Jun 2007 09:06:30 -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@yahoo.com>

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100644
new mode 100755
index e97d15e..c902b64
--- 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 f459762..113b252 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,39 @@ 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 hashes. First level hash will
+# be keyed with the child SVN rev and contain a hash keyed with the parent SVN
+# revisions. Values of the second level hash are not important (1 will be
+# used). The keys will be used to store the parent revs for uniqueness.
+our %merge_graph;
+
+
+# read-in the explicit merge graph specified with -G option
+if ($opt_G) {
+    open(F,"cat $opt_G | sed -e 's/#.*\$//' -e '/^\$/d' |") or
+        die("Can not open $opt_G");
+    while(<F>) {
+        chomp;
+        die "ERROR: invalid line in $opt_G: $_" unless /^\s*(\d+)\s+(\d+)\s*$/;
+        # $merge_graph{child_rev}{parent_rev} = 1;
+        $merge_graph{$1}{$2} = 1;
+    }
+    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;
+    my @parents = keys(%{$merge_graph{$child_svnrev}});
+    return @parents;
+}
+
+
 # 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 +390,24 @@ 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 +867,19 @@ 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);
+                        #print OUT "MG: $svnp -merge-> $revision\n";
+                    }
+                }
+            }
+
 			my %seen_parents = ();
 			my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
 			foreach my $bparent (@unique_parents) {
-- 
1.5.1.3


From 7008a13f1fe00fdbd90be6a12ad1197dceedaebb Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
Date: Sun, 24 Jun 2007 14:23:29 -0700
Subject: [PATCH] Fixed permissions of Documentation/git-svnimport.txt


Signed-off-by: Stas Maximov <smaximov@yahoo.com>

diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
old mode 100755
new mode 100644
-- 
1.5.1.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* Re: [PATCH] git-svnimport: added explicit merge graph option -G
@ 2007-06-25 16:23 Stas Maximov
  0 siblings, 0 replies; 10+ messages in thread
From: Stas Maximov @ 2007-06-25 16:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 6976 bytes --]

Hi Junio,

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

>From: Junio C Hamano <gitster@pobox.com>
> ...
>> +# 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@yahoo.com>
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@yahoo.com>
---
 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 #2: 0001-git-svnimport-added-explicit-merge-graph-option-G.patch --]
[-- Type: application/octet-stream, Size: 5760 bytes --]

From b17c89b82441dc3c5dc3155acee560a1d7f0149d Mon Sep 17 00:00:00 2001
From: Stas Maximov <smaximov@yahoo.com>
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@yahoo.com>
---
 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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-06-25 16:24 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-24  7:06 [PATCH] git-svnimport: added explicit merge graph option -G Junio C Hamano
2007-06-24  8:44 ` Peter Baumann
2007-06-24 17:27   ` Steven Grimm
2007-06-25  8:54   ` Peter Baumann
2007-06-24  9:32 ` Alex Riesen
  -- strict thread matches above, loose matches on Subject: below --
2007-06-24 21:48 Stas Maximov
2007-06-24 22:17 ` Junio C Hamano
2007-06-24 23:10 Stas Maximov
2007-06-25  7:05 ` Junio C Hamano
2007-06-25 16:23 Stas Maximov

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).