{"thread":{"id":"3535","subject":"contrib/git-svn: polishing up","startedAt":"2006-03-03T09:20:07Z","lastAt":"2006-03-03T09:20:07Z","messageCount":2,"participants":["Eric Wong"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"17104","messageId":"11413776074123-git-send-email-normalperson@yhbt.net","threadId":"3535","inReplyTo":null,"subject":"contrib/git-svn: polishing up","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-03-03T09:20:07Z","receivedAt":"2006-03-03T09:20:07Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"\nMostly small things: documentation and code cleanups.\n\nOne bugfix of some significance:\n    \n    Edited commit messages are parsed back to remotes/git-svn\n    correctly.  The sequential commit optimization broke this :x\n\nSignificant new features:\n    \n    --branch/-b is interesting and fun for those of you who miss 'real'\n    branch support in SVN.\n\n    --authors-file/-A support, because git-svnimport has it :)\n\nNone of the core commit/fetch tree-writing code was touched.\n\n git-svn.perl |  210 ++++++++++++++++++++++++++++++++++++++++-------------------\n git-svn.txt  |   34 ++++++++-\n 2 files changed, 176 insertions(+), 68 deletions(-)\n"},{"id":"17105","messageId":"11413776074148-git-send-email-normalperson@yhbt.net","threadId":"3535","inReplyTo":"11413776074123-git-send-email-normalperson@yhbt.net","subject":"[PATCH 1/9] contrib/git-svn: add -b/--branch switch for branch detection","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-03-03T09:20:07Z","receivedAt":"2006-03-03T09:20:07Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"I've said I don't like branches in Subversion, and I still don't.\nThis is a bit more flexible, though, as the argument for -b is any\narbitrary git head/tag reference.\n\nThis makes some things easier:\n * Importing git history into a brand new SVN branch.\n * Tracking multiple SVN branches via GIT_SVN_ID, even from multiple\n   repositories.\n * Adding tags from SVN (still need to use GIT_SVN_ID, though).\n * Even merge tracking is supported, if and only the heads end up with\n   100% equivalent tree objects.  This is more stricter but more robust\n   and foolproof than parsing commit messages, imho.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n\n---\n\n contrib/git-svn/git-svn.perl |   38 ++++++++++++++++++++++++++++++++++++++\n contrib/git-svn/git-svn.txt  |   17 ++++++++++++++++-\n 2 files changed, 54 insertions(+), 1 deletions(-)\n\n536109ffa6682954d3b2bb6a184978fd185ecaa4\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex 0e092c5..1f9a470 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -35,6 +35,7 @@ my $sha1 = qr/[a-f\\d]{40}/;\n my $sha1_short = qr/[a-f\\d]{6,40}/;\n my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,\n \t$_find_copies_harder, $_l, $_version, $_upgrade);\n+my (@_branch_from, %tree_map);\n \n GetOptions(\t'revision|r=s' => \\$_revision,\n \t\t'no-ignore-externals' => \\$_no_ignore_ext,\n@@ -43,6 +44,7 @@ GetOptions(\t'revision|r=s' => \\$_revisio\n \t\t'rmdir' => \\$_rmdir,\n \t\t'upgrade' => \\$_upgrade,\n \t\t'help|H|h' => \\$_help,\n+\t\t'branch|b=s' => \\@_branch_from,\n \t\t'find-copies-harder' => \\$_find_copies_harder,\n \t\t'l=i' => \\$_l,\n \t\t'version|V' => \\$_version,\n@@ -831,6 +833,8 @@ sub git_commit {\n \tmy $uuid = $info->{'Repository UUID'};\n \tdefined $uuid or croak \"Unable to get Repository UUID\\n\";\n \n+\tmap_tree_joins() if (@_branch_from && !%tree_map);\n+\n \t# commit parents can be conditionally bound to a particular\n \t# svn revision via: \"svn_revno=commit_sha1\", filter them out here:\n \tmy @exec_parents;\n@@ -852,6 +856,17 @@ sub git_commit {\n \t\tgit_addremove();\n \t\tchomp(my $tree = `git-write-tree`);\n \t\tcroak if $?;\n+\t\tif (exists $tree_map{$tree}) {\n+\t\t\tmy %seen_parent = map { $_ => 1 } @exec_parents;\n+\t\t\tforeach (@{$tree_map{$tree}}) {\n+\t\t\t\t# MAXPARENT is defined to 16 in commit-tree.c:\n+\t\t\t\tif ($seen_parent{$_} || @exec_parents > 16) {\n+\t\t\t\t\tnext;\n+\t\t\t\t}\n+\t\t\t\tpush @exec_parents, $_;\n+\t\t\t\t$seen_parent{$_} = 1;\n+\t\t\t}\n+\t\t}\n \t\tmy $msg_fh = IO::File->new_tmpfile or croak $!;\n \t\tprint $msg_fh $log_msg->{msg}, \"\\ngit-svn-id: \",\n \t\t\t\t\t\"$SVN_URL\\@$log_msg->{revision}\",\n@@ -975,6 +990,29 @@ sub check_upgrade_needed {\n \t}\n }\n \n+# fills %tree_map with a reverse mapping of trees to commits.  Useful\n+# for finding parents to commit on.\n+sub map_tree_joins {\n+\tforeach my $br (@_branch_from) {\n+\t\tmy $pid = open my $pipe, '-|';\n+\t\tdefined $pid or croak $!;\n+\t\tif ($pid == 0) {\n+\t\t\texec(qw(git-rev-list --pretty=raw), $br) or croak $?;\n+\t\t}\n+\t\twhile (<$pipe>) {\n+\t\t\tif (/^commit ($sha1)$/o) {\n+\t\t\t\tmy $commit = $1;\n+\t\t\t\tmy ($tree) = (<$pipe> =~ /^tree ($sha1)$/o);\n+\t\t\t\tunless (defined $tree) {\n+\t\t\t\t\tdie \"Failed to parse commit $commit\\n\";\n+\t\t\t\t}\n+\t\t\t\tpush @{$tree_map{$tree}}, $commit;\n+\t\t\t}\n+\t\t}\n+\t\tclose $pipe or croak $?;\n+\t}\n+}\n+\n __END__\n \n Data structures:\ndiff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt\nindex 4102deb..7306048 100644\n--- a/contrib/git-svn/git-svn.txt\n+++ b/contrib/git-svn/git-svn.txt\n@@ -27,7 +27,7 @@ For importing svn, git-svnimport is pote\n operating on repositories organized under the recommended\n trunk/branch/tags structure, and should be faster, too.\n \n-git-svn completely ignores the very limited view of branching that\n+git-svn mostly ignores the very limited view of branching that\n Subversion has.  This allows git-svn to be much easier to use,\n especially on repositories that are not organized in a manner that\n git-svnimport is designed for.\n@@ -116,6 +116,21 @@ OPTIONS\n \tThey are both passed directly to git-diff-tree see\n \tgit-diff-tree(1) for more information.\n \n+-b<refname>::\n+--branch <refname>::\n+\tUsed with 'fetch' or 'commit'.\n+\n+\tThis can be used to join arbitrary git branches to remotes/git-svn\n+\ton new commits where the tree object is equivalent.\n+\n+\tWhen used with different GIT_SVN_ID values, tags and branches in\n+\tSVN can be tracked this way, as can some merges where the heads\n+\tend up having completely equivalent content.  This can even be\n+\tused to track branches across multiple SVN _repositories_.\n+\n+\tThis option may be specified multiple times, once for each\n+\tbranch.\n+\n COMPATIBILITY OPTIONS\n ---------------------\n --no-ignore-externals::\n-- \n1.2.3.g4676\n"}]}