{"thread":{"id":"8697","subject":"[PATCH] git-svnimport: added explicit merge graph option -G","startedAt":"2007-06-24T07:06:20Z","lastAt":"2007-06-25T08:54:12Z","messageCount":5,"participants":["Junio C Hamano","Peter Baumann","Alex Riesen","Steven Grimm"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"45644","messageId":"7vk5tt25n7.fsf@assigned-by-dhcp.cox.net","threadId":"8697","inReplyTo":null,"subject":"[PATCH] git-svnimport: added explicit merge graph option -G","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-24T07:06:20Z","receivedAt":"2007-06-24T07:06:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Stas Maximov <smaximov@yahoo.com>\nDate: Sat, 23 Jun 2007 09:06:30 -0700\n\nAllows explicit merge graph information to be provided. Each line\nof merge graph file must contain a pair of SVN revision numbers\nseparated by space. The first number is child (merged to) SVN rev\nnumber and the second is the parent (merged from) SVN rev number.\nComments can be started with '#' and continue to the end of line.\nEmpty and space-only lines are allowed and will be ignored.\n---\n\n * Stas, please give a \"Signed-off-by\" line, and get in the\n   habit of always CC the list.\n\n   I received a format-patch output as attachment from Stas.  As\n   I cannot comment on the patch in that format, I am making a\n   verbatim forward to the list.\n\n   I'll comment on the patch separately when I am through it,\n   but would appreciate comments from people who were involved\n   in git-svnimport in the past, and still use it.\n\n   \"You should use git-svn instead\" people can repeat that as\n   usual, but at the same time it might be worth realizing that\n   there are people who maintain git-svnimport being better for\n   one-short importing.\n\n Documentation/git-svnimport.txt |   11 +++++-\n git-svnimport.perl              |   71 +++++++++++++++++++++++++++++++++++++--\n 2 files changed, 78 insertions(+), 4 deletions(-)\n mode change 100644 => 100755 Documentation/git-svnimport.txt\n\ndiff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt\nold mode 100644\nnew mode 100755\nindex e97d15e..c902b64\n--- a/Documentation/git-svnimport.txt\n+++ b/Documentation/git-svnimport.txt\n@@ -13,7 +13,8 @@ SYNOPSIS\n 'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]\n \t\t[ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]\n \t\t[ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]\n-\t\t[ -s start_chg ] [ -m ] [ -r ] [ -M regex ]\n+\t\t[ -s start_chg ] [ -r ]\n+\t\t[ -m ] [ -M regex ] [-G merge_graph_file ]\n \t\t[ -I <ignorefile_name> ] [ -A <author_file> ]\n \t\t[ -R <repack_each_revs>] [ -P <path_from_trunk> ]\n \t\t<SVN_repository_URL> [ <path> ]\n@@ -102,6 +103,14 @@ repository without -A.\n \tregex. It can be used with -m to also see the default regexes.\n \tYou must escape forward slashes.\n \n+-G <merge_graph_file>::\n+\tAllows explicit merge graph information to be provided. Each line\n+\tof merge graph file must contain a pair of SVN revision numbers\n+\tseparated by space. The first number is child (merged to) SVN rev\n+\tnumber and the second is the parent (merged from) SVN rev number.\n+\tComments can be started with '#' and continue to the end of line.\n+\tEmpty and space-only lines are allowed and will be ignored.\n+\n -l <max_rev>::\n \tSpecify a maximum revision number to pull.\n +\ndiff --git a/git-svnimport.perl b/git-svnimport.perl\nindex f459762..113b252 100755\n--- a/git-svnimport.perl\n+++ b/git-svnimport.perl\n@@ -32,7 +32,7 @@ $ENV{'TZ'}=\"UTC\";\n \n our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,\n     $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,\n-    $opt_P,$opt_R);\n+    $opt_P,$opt_R,$opt_G);\n \n sub usage() {\n \tprint STDERR <<END;\n@@ -40,12 +40,13 @@ Usage: ${\\basename $0}     # fetch/update GIT from SVN\n        [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]\n        [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]\n        [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]\n-       [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]\n+       [-m] [-M regex] [-G merge_graph_file] [-A author_file]\n+       [-S] [-F] [-P project_name] [SVN_URL]\n END\n \texit(1);\n }\n \n-getopts(\"A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv\") or usage();\n+getopts(\"A:b:C:dDFhiI:l:mM:G:o:rs:t:T:SP:R:uv\") or usage();\n usage if $opt_h;\n \n my $tag_name = $opt_t || \"tags\";\n@@ -80,6 +81,39 @@ if ($opt_M) {\n \tunshift (@mergerx, qr/$opt_M/);\n }\n \n+\n+# merge_graph will be used for finding all parent SVN revisions for a given SVN\n+# revision. It will be implemented as a hash of hashes. First level hash will\n+# be keyed with the child SVN rev and contain a hash keyed with the parent SVN\n+# revisions. Values of the second level hash are not important (1 will be\n+# used). The keys will be used to store the parent revs for uniqueness.\n+our %merge_graph;\n+\n+\n+# read-in the explicit merge graph specified with -G option\n+if ($opt_G) {\n+    open(F,\"cat $opt_G | sed -e 's/#.*\\$//' -e '/^\\$/d' |\") or\n+        die(\"Can not open $opt_G\");\n+    while(<F>) {\n+        chomp;\n+        die \"ERROR: invalid line in $opt_G: $_\" unless /^\\s*(\\d+)\\s+(\\d+)\\s*$/;\n+        # $merge_graph{child_rev}{parent_rev} = 1;\n+        $merge_graph{$1}{$2} = 1;\n+    }\n+    close(F);\n+}\n+\n+\n+# Given an SVN revision (string), finds all its parent SVN revisions in the\n+# merge graph.\n+sub merge_graph_get_parents($)\n+{\n+    my $child_svnrev = shift;\n+    my @parents = keys(%{$merge_graph{$child_svnrev}});\n+    return @parents;\n+}\n+\n+\n # Absolutize filename now, since we will have chdir'ed by the time we\n # get around to opening it.\n $opt_A = File::Spec->rel2abs($opt_A) if $opt_A;\n@@ -356,6 +390,24 @@ if ($opt_A) {\n \n open BRANCHES,\">>\", \"$git_dir/svn2git\";\n \n+\n+# Given an SVN revision (string), returns all corresponding GIT revisions.\n+#\n+# Note that it is possible that one SVN revision needs to be split into two or\n+# more GIT commits (revision). For example, this will happen if SVN user\n+# commits two branches at once.\n+sub svnrev_to_gitrevs($)\n+{\n+    my $svnrev = shift;\n+    my @gitrevs;\n+    for my $b (keys(%branches)) {\n+        push (@gitrevs, $branches{$b}{$svnrev})\n+            if defined($branches{$b}{$svnrev});\n+    }\n+    return @gitrevs;\n+}\n+\n+\n sub node_kind($$) {\n \tmy ($svnpath, $revision) = @_;\n \tmy $pool=SVN::Pool->new;\n@@ -815,6 +867,19 @@ sub commit {\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n+\n+            # add parents from explicit merge graph (-G)\n+            {\n+                my @svnpars = merge_graph_get_parents($revision);\n+                foreach my $svnp (@svnpars) {\n+                    my @gitpars = svnrev_to_gitrevs($svnp);\n+                    foreach my $gitp (@gitpars) {\n+                        push (@parents, $gitp);\n+                        #print OUT \"MG: $svnp -merge-> $revision\\n\";\n+                    }\n+                }\n+            }\n+\n \t\t\tmy %seen_parents = ();\n \t\t\tmy @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;\n \t\t\tforeach my $bparent (@unique_parents) {\n-- \n1.5.1.3\n"},{"id":"45651","messageId":"20070624084427.GA7715@xp.machine.xx","threadId":"8697","inReplyTo":"7vk5tt25n7.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-svnimport: added explicit merge graph option -G","fromName":"Peter Baumann","fromEmail":"waste.manager@gmx.de","sentAt":"2007-06-24T08:44:27Z","receivedAt":"2007-06-24T08:44:27Z","isPatch":true,"sender":{"key":"waste.manager@gmx.de","avatar":null},"body":"On Sun, Jun 24, 2007 at 12:06:20AM -0700, Junio C Hamano wrote:\n> From: Stas Maximov <smaximov@yahoo.com>\n> Date: Sat, 23 Jun 2007 09:06:30 -0700\n> \n> Allows explicit merge graph information to be provided. Each line\n> of merge graph file must contain a pair of SVN revision numbers\n> separated by space. The first number is child (merged to) SVN rev\n> number and the second is the parent (merged from) SVN rev number.\n> Comments can be started with '#' and continue to the end of line.\n> Empty and space-only lines are allowed and will be ignored.\n> ---\n> \n>  * Stas, please give a \"Signed-off-by\" line, and get in the\n>    habit of always CC the list.\n> \n>    I received a format-patch output as attachment from Stas.  As\n>    I cannot comment on the patch in that format, I am making a\n>    verbatim forward to the list.\n> \n>    I'll comment on the patch separately when I am through it,\n>    but would appreciate comments from people who were involved\n>    in git-svnimport in the past, and still use it.\n> \n>    \"You should use git-svn instead\" people can repeat that as\n>    usual, but at the same time it might be worth realizing that\n>    there are people who maintain git-svnimport being better for\n>    one-short importing.\n> \n\n[exchanging To:/Cc: as Junio just forwarded the message from Stas]\n\nNot commenting on the patch per se, but wouldn't it make more\nsense to have such functionality in a history rewriting tool like\ne.g. git-branch-filter?\n\nI had an svn import (git-svn) where I wanted to give correct\nbranch/merge points, too, and so I manually created a grafts file\nannotating all the svn merges. Having such a thing as a _generic_ tool\nwhich operates on grafts would be much more usefull because you get one\nimplementation which could be used for each and every importer out\nthere. Sure, you have to transform the native revision specifieres into\nthe GIT commit id's if you only have e.g. \"merged r4711:4720 into trunk\",\nbut these functionality is much more common to have in importers\nthan whats implemented in the above mentioned patch.\n\nAnother bonus point of using the grafts mechanism you'll get for free is\nthat you could _look_ at the commit graph in gitk *before* doing the\noften expensive reimport of your project, so could be sure you haven't\nforgotten to mark a merge.\n\n-Peter Baumann\n"},{"id":"45655","messageId":"20070624093211.GD2467@steel.home","threadId":"8697","inReplyTo":"7vk5tt25n7.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-svnimport: added explicit merge graph option -G","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-06-24T09:32:11Z","receivedAt":"2007-06-24T09:32:11Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sun, Jun 24, 2007 09:06:20 +0200:\n>    I received a format-patch output as attachment from Stas.  As\n>    I cannot comment on the patch in that format, I am making a\n>    verbatim forward to the list.\n...\n> diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt\n> old mode 100644\n> new mode 100755\n\nexecutable .txt?\n"},{"id":"45677","messageId":"467EA994.6030105@midwinter.com","threadId":"8697","inReplyTo":"20070624084427.GA7715@xp.machine.xx","subject":"Re: [PATCH] git-svnimport: added explicit merge graph option -G","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-06-24T17:27:48Z","receivedAt":"2007-06-24T17:27:48Z","isPatch":true,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Peter Baumann wrote:\n> Sure, you have to transform the native revision specifieres into\n> the GIT commit id's if you only have e.g. \"merged r4711:4720 into trunk\",\n>   \n\nIMO the major point of this patch is precisely to *avoid* having to do \nthat transformation. If you're already going to the trouble of \nconverting svn identifiers into git identifiers, then you don't need \nanother tool; you just stick the IDs in the grafts file and you're done.\n\nI agree that this functionality is useful in general, though.\n\n-Steve\n"},{"id":"45754","messageId":"20070625085412.GC4559@xp.machine.xx","threadId":"8697","inReplyTo":"20070624084427.GA7715@xp.machine.xx","subject":"Re: [PATCH] git-svnimport: added explicit merge graph option -G","fromName":"Peter Baumann","fromEmail":"waste.manager@gmx.de","sentAt":"2007-06-25T08:54:12Z","receivedAt":"2007-06-25T08:54:12Z","isPatch":true,"sender":{"key":"waste.manager@gmx.de","avatar":null},"body":"On Sun, Jun 24, 2007 at 10:44:27AM +0200, Peter Baumann wrote:\n> On Sun, Jun 24, 2007 at 12:06:20AM -0700, Junio C Hamano wrote:\n> > From: Stas Maximov <smaximov@yahoo.com>\n> > Date: Sat, 23 Jun 2007 09:06:30 -0700\n> > \n> > Allows explicit merge graph information to be provided. Each line\n> > of merge graph file must contain a pair of SVN revision numbers\n> > separated by space. The first number is child (merged to) SVN rev\n> > number and the second is the parent (merged from) SVN rev number.\n> > Comments can be started with '#' and continue to the end of line.\n> > Empty and space-only lines are allowed and will be ignored.\n> > ---\n> > \n> >  * Stas, please give a \"Signed-off-by\" line, and get in the\n> >    habit of always CC the list.\n> > \n> >    I received a format-patch output as attachment from Stas.  As\n> >    I cannot comment on the patch in that format, I am making a\n> >    verbatim forward to the list.\n> > \n> >    I'll comment on the patch separately when I am through it,\n> >    but would appreciate comments from people who were involved\n> >    in git-svnimport in the past, and still use it.\n> > \n> >    \"You should use git-svn instead\" people can repeat that as\n> >    usual, but at the same time it might be worth realizing that\n> >    there are people who maintain git-svnimport being better for\n> >    one-short importing.\n> > \n> \n> [exchanging To:/Cc: as Junio just forwarded the message from Stas]\n> \n> Not commenting on the patch per se, but wouldn't it make more\n> sense to have such functionality in a history rewriting tool like\n> e.g. git-branch-filter?\n> \n> I had an svn import (git-svn) where I wanted to give correct\n> branch/merge points, too, and so I manually created a grafts file\n> annotating all the svn merges. Having such a thing as a _generic_ tool\n> which operates on grafts would be much more usefull because you get one\n> implementation which could be used for each and every importer out\n> there. Sure, you have to transform the native revision specifieres into\n> the GIT commit id's if you only have e.g. \"merged r4711:4720 into trunk\",\n> but these functionality is much more common to have in importers\n> than whats implemented in the above mentioned patch.\n> \n> Another bonus point of using the grafts mechanism you'll get for free is\n> that you could _look_ at the commit graph in gitk *before* doing the\n> often expensive reimport of your project, so could be sure you haven't\n> forgotten to mark a merge.\n> \n\nThere was a message that git-filter-branch already could to this, which\nI didn't know:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/50736/focus=50872\n\n-Peter\n"}]}