{"thread":{"id":"31111","subject":"Extract remaining classes from git-svn","startedAt":"2012-07-27T00:25:59Z","lastAt":"2012-07-28T04:25:01Z","messageCount":16,"participants":["Michael G. Schwern","Michael G Schwern","Erik Faye-Lund","Eric Wong","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"195910","messageId":"1343348767-86446-1-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":null,"subject":"Extract remaining classes from git-svn","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:25:59Z","receivedAt":"2012-07-27T00:25:59Z","isPatch":false,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"This series of patches extracts the remaining classes from git-svn.  They're\nall simple extractions and functionally have no change.\n"},{"id":"195911","messageId":"1343348767-86446-2-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 1/8] Prepare Git::SVN::Log for extraction from git-svn.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:00Z","receivedAt":"2012-07-27T00:26:00Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\n* Load Git command functions itself.\n\n* Can't access the git-svn switch lexical any more, but its only used by\n  Git::SVN::Log so turn it into a Git::SVN::Log global.\n\n* Load Git::SVN as needed.  No need to load it always, its only used twice.\n\n* Moved a state variable to the routine it's used for. (Drive by refactoring)\n---\n git-svn.perl | 15 +++++++++++----\n 1 file changed, 11 insertions(+), 4 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex ef10f6f..e16475b 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -87,7 +87,7 @@ BEGIN {\n \tforeach (qw/command command_oneline command_noisy command_output_pipe\n \t            command_input_pipe command_close_pipe\n \t            command_bidi_pipe command_close_bidi_pipe/) {\n-\t\tfor my $package ( qw(Git::SVN::Migration Git::SVN::Log),\n+\t\tfor my $package ( qw(Git::SVN::Migration),\n \t\t\t__PACKAGE__) {\n \t\t\t*{\"${package}::$_\"} = \\&{\"Git::$_\"};\n \t\t}\n@@ -106,7 +106,7 @@ my ($_stdin, $_help, $_edit,\n \t$_version, $_fetch_all, $_no_rebase, $_fetch_parent,\n \t$_merge, $_strategy, $_preserve_merges, $_dry_run, $_local,\n \t$_prefix, $_no_checkout, $_url, $_verbose,\n-\t$_git_format, $_commit_url, $_tag, $_merge_info, $_interactive);\n+\t$_commit_url, $_tag, $_merge_info, $_interactive);\n \n # This is a refactoring artifact so Git::SVN can get at this git-svn switch.\n sub opt_prefix { return $_prefix || '' }\n@@ -270,7 +270,7 @@ my %cmd = (\n \t\t    { 'url' => \\$_url, } ],\n \t'blame' => [ \\&Git::SVN::Log::cmd_blame,\n \t            \"Show what revision and author last modified each line of a file\",\n-\t\t    { 'git-format' => \\$_git_format } ],\n+\t\t    { 'git-format' => \\$Git::SVN::Log::_git_format } ],\n \t'reset' => [ \\&cmd_reset,\n \t\t     \"Undo fetches back to the specified SVN revision\",\n \t\t     { 'revision|r=s' => \\$_revision,\n@@ -2044,11 +2044,14 @@ package Git::SVN::Log;\n use strict;\n use warnings;\n use Git::SVN::Utils qw(fatal);\n+use Git qw(command command_oneline command_output_pipe command_close_pipe);\n use POSIX qw/strftime/;\n use constant commit_log_separator => ('-' x 72) . \"\\n\";\n use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline\n             %rusers $show_commit $incremental/;\n-my $l_fmt;\n+\n+# Option set in git-svn\n+our $_git_format;\n \n sub cmt_showable {\n \tmy ($c) = @_;\n@@ -2094,6 +2097,8 @@ sub git_svn_log_cmd {\n \t}\n \n \tmy ($url, $rev, $uuid, $gs) = ::working_head_info($head);\n+\n+\trequire Git::SVN;\n \t$gs ||= Git::SVN->_new;\n \tmy @cmd = (qw/log --abbrev-commit --pretty=raw --default/,\n \t           $gs->refname);\n@@ -2155,6 +2160,7 @@ sub run_pager {\n \n sub format_svn_date {\n \tmy $t = shift || time;\n+\trequire Git::SVN;\n \tmy $gmoff = Git::SVN::get_tz($t);\n \treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\", localtime($t));\n }\n@@ -2225,6 +2231,7 @@ sub process_commit {\n \treturn 1;\n }\n \n+my $l_fmt;\n sub show_commit {\n \tmy $c = shift;\n \tif ($oneline) {\n-- \n1.7.11.1\n"},{"id":"195912","messageId":"1343348767-86446-3-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 2/8] Extract Git::SVN::Log from git-svn.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:01Z","receivedAt":"2012-07-27T00:26:01Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\nStraight cut & paste.\n\nAlso noticed Git::SVN::Ra wasn't in the compile test.  It is now.\n---\n git-svn.perl          | 395 +-------------------------------------------------\n perl/Git/SVN/Log.pm   | 395 ++++++++++++++++++++++++++++++++++++++++++++++++++\n perl/Makefile         |   1 +\n t/Git-SVN/00compile.t |   6 +-\n 4 files changed, 401 insertions(+), 396 deletions(-)\n create mode 100644 perl/Git/SVN/Log.pm\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex e16475b..7c8da44 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -11,6 +11,7 @@ $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n $VERSION = '@@GIT_VERSION@@';\n \n use Git::SVN;\n+use Git::SVN::Log;\n use Git::SVN::Utils qw(fatal can_compress);\n \n # From which subdir have we been invoked?\n@@ -2040,400 +2041,6 @@ sub gc_directory {\n }\n \n \n-package Git::SVN::Log;\n-use strict;\n-use warnings;\n-use Git::SVN::Utils qw(fatal);\n-use Git qw(command command_oneline command_output_pipe command_close_pipe);\n-use POSIX qw/strftime/;\n-use constant commit_log_separator => ('-' x 72) . \"\\n\";\n-use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline\n-            %rusers $show_commit $incremental/;\n-\n-# Option set in git-svn\n-our $_git_format;\n-\n-sub cmt_showable {\n-\tmy ($c) = @_;\n-\treturn 1 if defined $c->{r};\n-\n-\t# big commit message got truncated by the 16k pretty buffer in rev-list\n-\tif ($c->{l} && $c->{l}->[-1] eq \"...\\n\" &&\n-\t\t\t\t$c->{a_raw} =~ /\\@([a-f\\d\\-]+)>$/) {\n-\t\t@{$c->{l}} = ();\n-\t\tmy @log = command(qw/cat-file commit/, $c->{c});\n-\n-\t\t# shift off the headers\n-\t\tshift @log while ($log[0] ne '');\n-\t\tshift @log;\n-\n-\t\t# TODO: make $c->{l} not have a trailing newline in the future\n-\t\t@{$c->{l}} = map { \"$_\\n\" } grep !/^git-svn-id: /, @log;\n-\n-\t\t(undef, $c->{r}, undef) = ::extract_metadata(\n-\t\t\t\t(grep(/^git-svn-id: /, @log))[-1]);\n-\t}\n-\treturn defined $c->{r};\n-}\n-\n-sub log_use_color {\n-\treturn $color || Git->repository->get_colorbool('color.diff');\n-}\n-\n-sub git_svn_log_cmd {\n-\tmy ($r_min, $r_max, @args) = @_;\n-\tmy $head = 'HEAD';\n-\tmy (@files, @log_opts);\n-\tforeach my $x (@args) {\n-\t\tif ($x eq '--' || @files) {\n-\t\t\tpush @files, $x;\n-\t\t} else {\n-\t\t\tif (::verify_ref(\"$x^0\")) {\n-\t\t\t\t$head = $x;\n-\t\t\t} else {\n-\t\t\t\tpush @log_opts, $x;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\tmy ($url, $rev, $uuid, $gs) = ::working_head_info($head);\n-\n-\trequire Git::SVN;\n-\t$gs ||= Git::SVN->_new;\n-\tmy @cmd = (qw/log --abbrev-commit --pretty=raw --default/,\n-\t           $gs->refname);\n-\tpush @cmd, '-r' unless $non_recursive;\n-\tpush @cmd, qw/--raw --name-status/ if $verbose;\n-\tpush @cmd, '--color' if log_use_color();\n-\tpush @cmd, @log_opts;\n-\tif (defined $r_max && $r_max == $r_min) {\n-\t\tpush @cmd, '--max-count=1';\n-\t\tif (my $c = $gs->rev_map_get($r_max)) {\n-\t\t\tpush @cmd, $c;\n-\t\t}\n-\t} elsif (defined $r_max) {\n-\t\tif ($r_max < $r_min) {\n-\t\t\t($r_min, $r_max) = ($r_max, $r_min);\n-\t\t}\n-\t\tmy (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);\n-\t\tmy (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);\n-\t\t# If there are no commits in the range, both $c_max and $c_min\n-\t\t# will be undefined.  If there is at least 1 commit in the\n-\t\t# range, both will be defined.\n-\t\treturn () if !defined $c_min || !defined $c_max;\n-\t\tif ($c_min eq $c_max) {\n-\t\t\tpush @cmd, '--max-count=1', $c_min;\n-\t\t} else {\n-\t\t\tpush @cmd, '--boundary', \"$c_min..$c_max\";\n-\t\t}\n-\t}\n-\treturn (@cmd, @files);\n-}\n-\n-# adapted from pager.c\n-sub config_pager {\n-\tif (! -t *STDOUT) {\n-\t\t$ENV{GIT_PAGER_IN_USE} = 'false';\n-\t\t$pager = undef;\n-\t\treturn;\n-\t}\n-\tchomp($pager = command_oneline(qw(var GIT_PAGER)));\n-\tif ($pager eq 'cat') {\n-\t\t$pager = undef;\n-\t}\n-\t$ENV{GIT_PAGER_IN_USE} = defined($pager);\n-}\n-\n-sub run_pager {\n-\treturn unless defined $pager;\n-\tpipe my ($rfd, $wfd) or return;\n-\tdefined(my $pid = fork) or fatal \"Can't fork: $!\";\n-\tif (!$pid) {\n-\t\topen STDOUT, '>&', $wfd or\n-\t\t                     fatal \"Can't redirect to stdout: $!\";\n-\t\treturn;\n-\t}\n-\topen STDIN, '<&', $rfd or fatal \"Can't redirect stdin: $!\";\n-\t$ENV{LESS} ||= 'FRSX';\n-\texec $pager or fatal \"Can't run pager: $! ($pager)\";\n-}\n-\n-sub format_svn_date {\n-\tmy $t = shift || time;\n-\trequire Git::SVN;\n-\tmy $gmoff = Git::SVN::get_tz($t);\n-\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\", localtime($t));\n-}\n-\n-sub parse_git_date {\n-\tmy ($t, $tz) = @_;\n-\t# Date::Parse isn't in the standard Perl distro :(\n-\tif ($tz =~ s/^\\+//) {\n-\t\t$t += tz_to_s_offset($tz);\n-\t} elsif ($tz =~ s/^\\-//) {\n-\t\t$t -= tz_to_s_offset($tz);\n-\t}\n-\treturn $t;\n-}\n-\n-sub set_local_timezone {\n-\tif (defined $TZ) {\n-\t\t$ENV{TZ} = $TZ;\n-\t} else {\n-\t\tdelete $ENV{TZ};\n-\t}\n-}\n-\n-sub tz_to_s_offset {\n-\tmy ($tz) = @_;\n-\t$tz =~ s/(\\d\\d)$//;\n-\treturn ($1 * 60) + ($tz * 3600);\n-}\n-\n-sub get_author_info {\n-\tmy ($dest, $author, $t, $tz) = @_;\n-\t$author =~ s/(?:^\\s*|\\s*$)//g;\n-\t$dest->{a_raw} = $author;\n-\tmy $au;\n-\tif ($::_authors) {\n-\t\t$au = $rusers{$author} || undef;\n-\t}\n-\tif (!$au) {\n-\t\t($au) = ($author =~ /<([^>]+)\\@[^>]+>$/);\n-\t}\n-\t$dest->{t} = $t;\n-\t$dest->{tz} = $tz;\n-\t$dest->{a} = $au;\n-\t$dest->{t_utc} = parse_git_date($t, $tz);\n-}\n-\n-sub process_commit {\n-\tmy ($c, $r_min, $r_max, $defer) = @_;\n-\tif (defined $r_min && defined $r_max) {\n-\t\tif ($r_min == $c->{r} && $r_min == $r_max) {\n-\t\t\tshow_commit($c);\n-\t\t\treturn 0;\n-\t\t}\n-\t\treturn 1 if $r_min == $r_max;\n-\t\tif ($r_min < $r_max) {\n-\t\t\t# we need to reverse the print order\n-\t\t\treturn 0 if (defined $limit && --$limit < 0);\n-\t\t\tpush @$defer, $c;\n-\t\t\treturn 1;\n-\t\t}\n-\t\tif ($r_min != $r_max) {\n-\t\t\treturn 1 if ($r_min < $c->{r});\n-\t\t\treturn 1 if ($r_max > $c->{r});\n-\t\t}\n-\t}\n-\treturn 0 if (defined $limit && --$limit < 0);\n-\tshow_commit($c);\n-\treturn 1;\n-}\n-\n-my $l_fmt;\n-sub show_commit {\n-\tmy $c = shift;\n-\tif ($oneline) {\n-\t\tmy $x = \"\\n\";\n-\t\tif (my $l = $c->{l}) {\n-\t\t\twhile ($l->[0] =~ /^\\s*$/) { shift @$l }\n-\t\t\t$x = $l->[0];\n-\t\t}\n-\t\t$l_fmt ||= 'A' . length($c->{r});\n-\t\tprint 'r',pack($l_fmt, $c->{r}),' | ';\n-\t\tprint \"$c->{c} | \" if $show_commit;\n-\t\tprint $x;\n-\t} else {\n-\t\tshow_commit_normal($c);\n-\t}\n-}\n-\n-sub show_commit_changed_paths {\n-\tmy ($c) = @_;\n-\treturn unless $c->{changed};\n-\tprint \"Changed paths:\\n\", @{$c->{changed}};\n-}\n-\n-sub show_commit_normal {\n-\tmy ($c) = @_;\n-\tprint commit_log_separator, \"r$c->{r} | \";\n-\tprint \"$c->{c} | \" if $show_commit;\n-\tprint \"$c->{a} | \", format_svn_date($c->{t_utc}), ' | ';\n-\tmy $nr_line = 0;\n-\n-\tif (my $l = $c->{l}) {\n-\t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n-\t\t                          && $l->[($#$l - 1)] eq \"\\n\") {\n-\t\t\tpop @$l;\n-\t\t}\n-\t\t$nr_line = scalar @$l;\n-\t\tif (!$nr_line) {\n-\t\t\tprint \"1 line\\n\\n\\n\";\n-\t\t} else {\n-\t\t\tif ($nr_line == 1) {\n-\t\t\t\t$nr_line = '1 line';\n-\t\t\t} else {\n-\t\t\t\t$nr_line .= ' lines';\n-\t\t\t}\n-\t\t\tprint $nr_line, \"\\n\";\n-\t\t\tshow_commit_changed_paths($c);\n-\t\t\tprint \"\\n\";\n-\t\t\tprint $_ foreach @$l;\n-\t\t}\n-\t} else {\n-\t\tprint \"1 line\\n\";\n-\t\tshow_commit_changed_paths($c);\n-\t\tprint \"\\n\";\n-\n-\t}\n-\tforeach my $x (qw/raw stat diff/) {\n-\t\tif ($c->{$x}) {\n-\t\t\tprint \"\\n\";\n-\t\t\tprint $_ foreach @{$c->{$x}}\n-\t\t}\n-\t}\n-}\n-\n-sub cmd_show_log {\n-\tmy (@args) = @_;\n-\tmy ($r_min, $r_max);\n-\tmy $r_last = -1; # prevent dupes\n-\tset_local_timezone();\n-\tif (defined $::_revision) {\n-\t\tif ($::_revision =~ /^(\\d+):(\\d+)$/) {\n-\t\t\t($r_min, $r_max) = ($1, $2);\n-\t\t} elsif ($::_revision =~ /^\\d+$/) {\n-\t\t\t$r_min = $r_max = $::_revision;\n-\t\t} else {\n-\t\t\tfatal \"-r$::_revision is not supported, use \",\n-\t\t\t\t\"standard 'git log' arguments instead\";\n-\t\t}\n-\t}\n-\n-\tconfig_pager();\n-\t@args = git_svn_log_cmd($r_min, $r_max, @args);\n-\tif (!@args) {\n-\t\tprint commit_log_separator unless $incremental || $oneline;\n-\t\treturn;\n-\t}\n-\tmy $log = command_output_pipe(@args);\n-\trun_pager();\n-\tmy (@k, $c, $d, $stat);\n-\tmy $esc_color = qr/(?:\\033\\[(?:(?:\\d+;)*\\d*)?m)*/;\n-\twhile (<$log>) {\n-\t\tif (/^${esc_color}commit (?:- )?($::sha1_short)/o) {\n-\t\t\tmy $cmt = $1;\n-\t\t\tif ($c && cmt_showable($c) && $c->{r} != $r_last) {\n-\t\t\t\t$r_last = $c->{r};\n-\t\t\t\tprocess_commit($c, $r_min, $r_max, \\@k) or\n-\t\t\t\t\t\t\t\tgoto out;\n-\t\t\t}\n-\t\t\t$d = undef;\n-\t\t\t$c = { c => $cmt };\n-\t\t} elsif (/^${esc_color}author (.+) (\\d+) ([\\-\\+]?\\d+)$/o) {\n-\t\t\tget_author_info($c, $1, $2, $3);\n-\t\t} elsif (/^${esc_color}(?:tree|parent|committer) /o) {\n-\t\t\t# ignore\n-\t\t} elsif (/^${esc_color}:\\d{6} \\d{6} $::sha1_short/o) {\n-\t\t\tpush @{$c->{raw}}, $_;\n-\t\t} elsif (/^${esc_color}[ACRMDT]\\t/) {\n-\t\t\t# we could add $SVN->{svn_path} here, but that requires\n-\t\t\t# remote access at the moment (repo_path_split)...\n-\t\t\ts#^(${esc_color})([ACRMDT])\\t#$1   $2 #o;\n-\t\t\tpush @{$c->{changed}}, $_;\n-\t\t} elsif (/^${esc_color}diff /o) {\n-\t\t\t$d = 1;\n-\t\t\tpush @{$c->{diff}}, $_;\n-\t\t} elsif ($d) {\n-\t\t\tpush @{$c->{diff}}, $_;\n-\t\t} elsif (/^\\ .+\\ \\|\\s*\\d+\\ $esc_color[\\+\\-]*\n-\t\t          $esc_color*[\\+\\-]*$esc_color$/x) {\n-\t\t\t$stat = 1;\n-\t\t\tpush @{$c->{stat}}, $_;\n-\t\t} elsif ($stat && /^ \\d+ files changed, \\d+ insertions/) {\n-\t\t\tpush @{$c->{stat}}, $_;\n-\t\t\t$stat = undef;\n-\t\t} elsif (/^${esc_color}    (git-svn-id:.+)$/o) {\n-\t\t\t($c->{url}, $c->{r}, undef) = ::extract_metadata($1);\n-\t\t} elsif (s/^${esc_color}    //o) {\n-\t\t\tpush @{$c->{l}}, $_;\n-\t\t}\n-\t}\n-\tif ($c && defined $c->{r} && $c->{r} != $r_last) {\n-\t\t$r_last = $c->{r};\n-\t\tprocess_commit($c, $r_min, $r_max, \\@k);\n-\t}\n-\tif (@k) {\n-\t\t($r_min, $r_max) = ($r_max, $r_min);\n-\t\tprocess_commit($_, $r_min, $r_max) foreach reverse @k;\n-\t}\n-out:\n-\tclose $log;\n-\tprint commit_log_separator unless $incremental || $oneline;\n-}\n-\n-sub cmd_blame {\n-\tmy $path = pop;\n-\n-\tconfig_pager();\n-\trun_pager();\n-\n-\tmy ($fh, $ctx, $rev);\n-\n-\tif ($_git_format) {\n-\t\t($fh, $ctx) = command_output_pipe('blame', @_, $path);\n-\t\twhile (my $line = <$fh>) {\n-\t\t\tif ($line =~ /^\\^?([[:xdigit:]]+)\\s/) {\n-\t\t\t\t# Uncommitted edits show up as a rev ID of\n-\t\t\t\t# all zeros, which we can't look up with\n-\t\t\t\t# cmt_metadata\n-\t\t\t\tif ($1 !~ /^0+$/) {\n-\t\t\t\t\t(undef, $rev, undef) =\n-\t\t\t\t\t\t::cmt_metadata($1);\n-\t\t\t\t\t$rev = '0' if (!$rev);\n-\t\t\t\t} else {\n-\t\t\t\t\t$rev = '0';\n-\t\t\t\t}\n-\t\t\t\t$rev = sprintf('%-10s', $rev);\n-\t\t\t\t$line =~ s/^\\^?[[:xdigit:]]+(\\s)/$rev$1/;\n-\t\t\t}\n-\t\t\tprint $line;\n-\t\t}\n-\t} else {\n-\t\t($fh, $ctx) = command_output_pipe('blame', '-p', @_, 'HEAD',\n-\t\t\t\t\t\t  '--', $path);\n-\t\tmy ($sha1);\n-\t\tmy %authors;\n-\t\tmy @buffer;\n-\t\tmy %dsha; #distinct sha keys\n-\n-\t\twhile (my $line = <$fh>) {\n-\t\t\tpush @buffer, $line;\n-\t\t\tif ($line =~ /^([[:xdigit:]]{40})\\s\\d+\\s\\d+/) {\n-\t\t\t\t$dsha{$1} = 1;\n-\t\t\t}\n-\t\t}\n-\n-\t\tmy $s2r = ::cmt_sha2rev_batch([keys %dsha]);\n-\n-\t\tforeach my $line (@buffer) {\n-\t\t\tif ($line =~ /^([[:xdigit:]]{40})\\s\\d+\\s\\d+/) {\n-\t\t\t\t$rev = $s2r->{$1};\n-\t\t\t\t$rev = '0' if (!$rev)\n-\t\t\t}\n-\t\t\telsif ($line =~ /^author (.*)/) {\n-\t\t\t\t$authors{$rev} = $1;\n-\t\t\t\t$authors{$rev} =~ s/\\s/_/g;\n-\t\t\t}\n-\t\t\telsif ($line =~ /^\\t(.*)$/) {\n-\t\t\t\tprintf(\"%6s %10s %s\\n\", $rev, $authors{$rev}, $1);\n-\t\t\t}\n-\t\t}\n-\t}\n-\tcommand_close_pipe($fh, $ctx);\n-}\n-\n package Git::SVN::Migration;\n # these version numbers do NOT correspond to actual version numbers\n # of git nor git-svn.  They are just relative.\ndiff --git a/perl/Git/SVN/Log.pm b/perl/Git/SVN/Log.pm\nnew file mode 100644\nindex 0000000..3cc1c6f\n--- /dev/null\n+++ b/perl/Git/SVN/Log.pm\n@@ -0,0 +1,395 @@\n+package Git::SVN::Log;\n+use strict;\n+use warnings;\n+use Git::SVN::Utils qw(fatal);\n+use Git qw(command command_oneline command_output_pipe command_close_pipe);\n+use POSIX qw/strftime/;\n+use constant commit_log_separator => ('-' x 72) . \"\\n\";\n+use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline\n+            %rusers $show_commit $incremental/;\n+\n+# Option set in git-svn\n+our $_git_format;\n+\n+sub cmt_showable {\n+\tmy ($c) = @_;\n+\treturn 1 if defined $c->{r};\n+\n+\t# big commit message got truncated by the 16k pretty buffer in rev-list\n+\tif ($c->{l} && $c->{l}->[-1] eq \"...\\n\" &&\n+\t\t\t\t$c->{a_raw} =~ /\\@([a-f\\d\\-]+)>$/) {\n+\t\t@{$c->{l}} = ();\n+\t\tmy @log = command(qw/cat-file commit/, $c->{c});\n+\n+\t\t# shift off the headers\n+\t\tshift @log while ($log[0] ne '');\n+\t\tshift @log;\n+\n+\t\t# TODO: make $c->{l} not have a trailing newline in the future\n+\t\t@{$c->{l}} = map { \"$_\\n\" } grep !/^git-svn-id: /, @log;\n+\n+\t\t(undef, $c->{r}, undef) = ::extract_metadata(\n+\t\t\t\t(grep(/^git-svn-id: /, @log))[-1]);\n+\t}\n+\treturn defined $c->{r};\n+}\n+\n+sub log_use_color {\n+\treturn $color || Git->repository->get_colorbool('color.diff');\n+}\n+\n+sub git_svn_log_cmd {\n+\tmy ($r_min, $r_max, @args) = @_;\n+\tmy $head = 'HEAD';\n+\tmy (@files, @log_opts);\n+\tforeach my $x (@args) {\n+\t\tif ($x eq '--' || @files) {\n+\t\t\tpush @files, $x;\n+\t\t} else {\n+\t\t\tif (::verify_ref(\"$x^0\")) {\n+\t\t\t\t$head = $x;\n+\t\t\t} else {\n+\t\t\t\tpush @log_opts, $x;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tmy ($url, $rev, $uuid, $gs) = ::working_head_info($head);\n+\n+\trequire Git::SVN;\n+\t$gs ||= Git::SVN->_new;\n+\tmy @cmd = (qw/log --abbrev-commit --pretty=raw --default/,\n+\t           $gs->refname);\n+\tpush @cmd, '-r' unless $non_recursive;\n+\tpush @cmd, qw/--raw --name-status/ if $verbose;\n+\tpush @cmd, '--color' if log_use_color();\n+\tpush @cmd, @log_opts;\n+\tif (defined $r_max && $r_max == $r_min) {\n+\t\tpush @cmd, '--max-count=1';\n+\t\tif (my $c = $gs->rev_map_get($r_max)) {\n+\t\t\tpush @cmd, $c;\n+\t\t}\n+\t} elsif (defined $r_max) {\n+\t\tif ($r_max < $r_min) {\n+\t\t\t($r_min, $r_max) = ($r_max, $r_min);\n+\t\t}\n+\t\tmy (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);\n+\t\tmy (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);\n+\t\t# If there are no commits in the range, both $c_max and $c_min\n+\t\t# will be undefined.  If there is at least 1 commit in the\n+\t\t# range, both will be defined.\n+\t\treturn () if !defined $c_min || !defined $c_max;\n+\t\tif ($c_min eq $c_max) {\n+\t\t\tpush @cmd, '--max-count=1', $c_min;\n+\t\t} else {\n+\t\t\tpush @cmd, '--boundary', \"$c_min..$c_max\";\n+\t\t}\n+\t}\n+\treturn (@cmd, @files);\n+}\n+\n+# adapted from pager.c\n+sub config_pager {\n+\tif (! -t *STDOUT) {\n+\t\t$ENV{GIT_PAGER_IN_USE} = 'false';\n+\t\t$pager = undef;\n+\t\treturn;\n+\t}\n+\tchomp($pager = command_oneline(qw(var GIT_PAGER)));\n+\tif ($pager eq 'cat') {\n+\t\t$pager = undef;\n+\t}\n+\t$ENV{GIT_PAGER_IN_USE} = defined($pager);\n+}\n+\n+sub run_pager {\n+\treturn unless defined $pager;\n+\tpipe my ($rfd, $wfd) or return;\n+\tdefined(my $pid = fork) or fatal \"Can't fork: $!\";\n+\tif (!$pid) {\n+\t\topen STDOUT, '>&', $wfd or\n+\t\t                     fatal \"Can't redirect to stdout: $!\";\n+\t\treturn;\n+\t}\n+\topen STDIN, '<&', $rfd or fatal \"Can't redirect stdin: $!\";\n+\t$ENV{LESS} ||= 'FRSX';\n+\texec $pager or fatal \"Can't run pager: $! ($pager)\";\n+}\n+\n+sub format_svn_date {\n+\tmy $t = shift || time;\n+\trequire Git::SVN;\n+\tmy $gmoff = Git::SVN::get_tz($t);\n+\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\", localtime($t));\n+}\n+\n+sub parse_git_date {\n+\tmy ($t, $tz) = @_;\n+\t# Date::Parse isn't in the standard Perl distro :(\n+\tif ($tz =~ s/^\\+//) {\n+\t\t$t += tz_to_s_offset($tz);\n+\t} elsif ($tz =~ s/^\\-//) {\n+\t\t$t -= tz_to_s_offset($tz);\n+\t}\n+\treturn $t;\n+}\n+\n+sub set_local_timezone {\n+\tif (defined $TZ) {\n+\t\t$ENV{TZ} = $TZ;\n+\t} else {\n+\t\tdelete $ENV{TZ};\n+\t}\n+}\n+\n+sub tz_to_s_offset {\n+\tmy ($tz) = @_;\n+\t$tz =~ s/(\\d\\d)$//;\n+\treturn ($1 * 60) + ($tz * 3600);\n+}\n+\n+sub get_author_info {\n+\tmy ($dest, $author, $t, $tz) = @_;\n+\t$author =~ s/(?:^\\s*|\\s*$)//g;\n+\t$dest->{a_raw} = $author;\n+\tmy $au;\n+\tif ($::_authors) {\n+\t\t$au = $rusers{$author} || undef;\n+\t}\n+\tif (!$au) {\n+\t\t($au) = ($author =~ /<([^>]+)\\@[^>]+>$/);\n+\t}\n+\t$dest->{t} = $t;\n+\t$dest->{tz} = $tz;\n+\t$dest->{a} = $au;\n+\t$dest->{t_utc} = parse_git_date($t, $tz);\n+}\n+\n+sub process_commit {\n+\tmy ($c, $r_min, $r_max, $defer) = @_;\n+\tif (defined $r_min && defined $r_max) {\n+\t\tif ($r_min == $c->{r} && $r_min == $r_max) {\n+\t\t\tshow_commit($c);\n+\t\t\treturn 0;\n+\t\t}\n+\t\treturn 1 if $r_min == $r_max;\n+\t\tif ($r_min < $r_max) {\n+\t\t\t# we need to reverse the print order\n+\t\t\treturn 0 if (defined $limit && --$limit < 0);\n+\t\t\tpush @$defer, $c;\n+\t\t\treturn 1;\n+\t\t}\n+\t\tif ($r_min != $r_max) {\n+\t\t\treturn 1 if ($r_min < $c->{r});\n+\t\t\treturn 1 if ($r_max > $c->{r});\n+\t\t}\n+\t}\n+\treturn 0 if (defined $limit && --$limit < 0);\n+\tshow_commit($c);\n+\treturn 1;\n+}\n+\n+my $l_fmt;\n+sub show_commit {\n+\tmy $c = shift;\n+\tif ($oneline) {\n+\t\tmy $x = \"\\n\";\n+\t\tif (my $l = $c->{l}) {\n+\t\t\twhile ($l->[0] =~ /^\\s*$/) { shift @$l }\n+\t\t\t$x = $l->[0];\n+\t\t}\n+\t\t$l_fmt ||= 'A' . length($c->{r});\n+\t\tprint 'r',pack($l_fmt, $c->{r}),' | ';\n+\t\tprint \"$c->{c} | \" if $show_commit;\n+\t\tprint $x;\n+\t} else {\n+\t\tshow_commit_normal($c);\n+\t}\n+}\n+\n+sub show_commit_changed_paths {\n+\tmy ($c) = @_;\n+\treturn unless $c->{changed};\n+\tprint \"Changed paths:\\n\", @{$c->{changed}};\n+}\n+\n+sub show_commit_normal {\n+\tmy ($c) = @_;\n+\tprint commit_log_separator, \"r$c->{r} | \";\n+\tprint \"$c->{c} | \" if $show_commit;\n+\tprint \"$c->{a} | \", format_svn_date($c->{t_utc}), ' | ';\n+\tmy $nr_line = 0;\n+\n+\tif (my $l = $c->{l}) {\n+\t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n+\t\t                          && $l->[($#$l - 1)] eq \"\\n\") {\n+\t\t\tpop @$l;\n+\t\t}\n+\t\t$nr_line = scalar @$l;\n+\t\tif (!$nr_line) {\n+\t\t\tprint \"1 line\\n\\n\\n\";\n+\t\t} else {\n+\t\t\tif ($nr_line == 1) {\n+\t\t\t\t$nr_line = '1 line';\n+\t\t\t} else {\n+\t\t\t\t$nr_line .= ' lines';\n+\t\t\t}\n+\t\t\tprint $nr_line, \"\\n\";\n+\t\t\tshow_commit_changed_paths($c);\n+\t\t\tprint \"\\n\";\n+\t\t\tprint $_ foreach @$l;\n+\t\t}\n+\t} else {\n+\t\tprint \"1 line\\n\";\n+\t\tshow_commit_changed_paths($c);\n+\t\tprint \"\\n\";\n+\n+\t}\n+\tforeach my $x (qw/raw stat diff/) {\n+\t\tif ($c->{$x}) {\n+\t\t\tprint \"\\n\";\n+\t\t\tprint $_ foreach @{$c->{$x}}\n+\t\t}\n+\t}\n+}\n+\n+sub cmd_show_log {\n+\tmy (@args) = @_;\n+\tmy ($r_min, $r_max);\n+\tmy $r_last = -1; # prevent dupes\n+\tset_local_timezone();\n+\tif (defined $::_revision) {\n+\t\tif ($::_revision =~ /^(\\d+):(\\d+)$/) {\n+\t\t\t($r_min, $r_max) = ($1, $2);\n+\t\t} elsif ($::_revision =~ /^\\d+$/) {\n+\t\t\t$r_min = $r_max = $::_revision;\n+\t\t} else {\n+\t\t\tfatal \"-r$::_revision is not supported, use \",\n+\t\t\t\t\"standard 'git log' arguments instead\";\n+\t\t}\n+\t}\n+\n+\tconfig_pager();\n+\t@args = git_svn_log_cmd($r_min, $r_max, @args);\n+\tif (!@args) {\n+\t\tprint commit_log_separator unless $incremental || $oneline;\n+\t\treturn;\n+\t}\n+\tmy $log = command_output_pipe(@args);\n+\trun_pager();\n+\tmy (@k, $c, $d, $stat);\n+\tmy $esc_color = qr/(?:\\033\\[(?:(?:\\d+;)*\\d*)?m)*/;\n+\twhile (<$log>) {\n+\t\tif (/^${esc_color}commit (?:- )?($::sha1_short)/o) {\n+\t\t\tmy $cmt = $1;\n+\t\t\tif ($c && cmt_showable($c) && $c->{r} != $r_last) {\n+\t\t\t\t$r_last = $c->{r};\n+\t\t\t\tprocess_commit($c, $r_min, $r_max, \\@k) or\n+\t\t\t\t\t\t\t\tgoto out;\n+\t\t\t}\n+\t\t\t$d = undef;\n+\t\t\t$c = { c => $cmt };\n+\t\t} elsif (/^${esc_color}author (.+) (\\d+) ([\\-\\+]?\\d+)$/o) {\n+\t\t\tget_author_info($c, $1, $2, $3);\n+\t\t} elsif (/^${esc_color}(?:tree|parent|committer) /o) {\n+\t\t\t# ignore\n+\t\t} elsif (/^${esc_color}:\\d{6} \\d{6} $::sha1_short/o) {\n+\t\t\tpush @{$c->{raw}}, $_;\n+\t\t} elsif (/^${esc_color}[ACRMDT]\\t/) {\n+\t\t\t# we could add $SVN->{svn_path} here, but that requires\n+\t\t\t# remote access at the moment (repo_path_split)...\n+\t\t\ts#^(${esc_color})([ACRMDT])\\t#$1   $2 #o;\n+\t\t\tpush @{$c->{changed}}, $_;\n+\t\t} elsif (/^${esc_color}diff /o) {\n+\t\t\t$d = 1;\n+\t\t\tpush @{$c->{diff}}, $_;\n+\t\t} elsif ($d) {\n+\t\t\tpush @{$c->{diff}}, $_;\n+\t\t} elsif (/^\\ .+\\ \\|\\s*\\d+\\ $esc_color[\\+\\-]*\n+\t\t          $esc_color*[\\+\\-]*$esc_color$/x) {\n+\t\t\t$stat = 1;\n+\t\t\tpush @{$c->{stat}}, $_;\n+\t\t} elsif ($stat && /^ \\d+ files changed, \\d+ insertions/) {\n+\t\t\tpush @{$c->{stat}}, $_;\n+\t\t\t$stat = undef;\n+\t\t} elsif (/^${esc_color}    (git-svn-id:.+)$/o) {\n+\t\t\t($c->{url}, $c->{r}, undef) = ::extract_metadata($1);\n+\t\t} elsif (s/^${esc_color}    //o) {\n+\t\t\tpush @{$c->{l}}, $_;\n+\t\t}\n+\t}\n+\tif ($c && defined $c->{r} && $c->{r} != $r_last) {\n+\t\t$r_last = $c->{r};\n+\t\tprocess_commit($c, $r_min, $r_max, \\@k);\n+\t}\n+\tif (@k) {\n+\t\t($r_min, $r_max) = ($r_max, $r_min);\n+\t\tprocess_commit($_, $r_min, $r_max) foreach reverse @k;\n+\t}\n+out:\n+\tclose $log;\n+\tprint commit_log_separator unless $incremental || $oneline;\n+}\n+\n+sub cmd_blame {\n+\tmy $path = pop;\n+\n+\tconfig_pager();\n+\trun_pager();\n+\n+\tmy ($fh, $ctx, $rev);\n+\n+\tif ($_git_format) {\n+\t\t($fh, $ctx) = command_output_pipe('blame', @_, $path);\n+\t\twhile (my $line = <$fh>) {\n+\t\t\tif ($line =~ /^\\^?([[:xdigit:]]+)\\s/) {\n+\t\t\t\t# Uncommitted edits show up as a rev ID of\n+\t\t\t\t# all zeros, which we can't look up with\n+\t\t\t\t# cmt_metadata\n+\t\t\t\tif ($1 !~ /^0+$/) {\n+\t\t\t\t\t(undef, $rev, undef) =\n+\t\t\t\t\t\t::cmt_metadata($1);\n+\t\t\t\t\t$rev = '0' if (!$rev);\n+\t\t\t\t} else {\n+\t\t\t\t\t$rev = '0';\n+\t\t\t\t}\n+\t\t\t\t$rev = sprintf('%-10s', $rev);\n+\t\t\t\t$line =~ s/^\\^?[[:xdigit:]]+(\\s)/$rev$1/;\n+\t\t\t}\n+\t\t\tprint $line;\n+\t\t}\n+\t} else {\n+\t\t($fh, $ctx) = command_output_pipe('blame', '-p', @_, 'HEAD',\n+\t\t\t\t\t\t  '--', $path);\n+\t\tmy ($sha1);\n+\t\tmy %authors;\n+\t\tmy @buffer;\n+\t\tmy %dsha; #distinct sha keys\n+\n+\t\twhile (my $line = <$fh>) {\n+\t\t\tpush @buffer, $line;\n+\t\t\tif ($line =~ /^([[:xdigit:]]{40})\\s\\d+\\s\\d+/) {\n+\t\t\t\t$dsha{$1} = 1;\n+\t\t\t}\n+\t\t}\n+\n+\t\tmy $s2r = ::cmt_sha2rev_batch([keys %dsha]);\n+\n+\t\tforeach my $line (@buffer) {\n+\t\t\tif ($line =~ /^([[:xdigit:]]{40})\\s\\d+\\s\\d+/) {\n+\t\t\t\t$rev = $s2r->{$1};\n+\t\t\t\t$rev = '0' if (!$rev)\n+\t\t\t}\n+\t\t\telsif ($line =~ /^author (.*)/) {\n+\t\t\t\t$authors{$rev} = $1;\n+\t\t\t\t$authors{$rev} =~ s/\\s/_/g;\n+\t\t\t}\n+\t\t\telsif ($line =~ /^\\t(.*)$/) {\n+\t\t\t\tprintf(\"%6s %10s %s\\n\", $rev, $authors{$rev}, $1);\n+\t\t\t}\n+\t\t}\n+\t}\n+\tcommand_close_pipe($fh, $ctx);\n+}\n+\n+1;\ndiff --git a/perl/Makefile b/perl/Makefile\nindex 461f233..8493d76 100644\n--- a/perl/Makefile\n+++ b/perl/Makefile\n@@ -30,6 +30,7 @@ modules += Git/SVN\n modules += Git/SVN/Memoize/YAML\n modules += Git/SVN/Fetcher\n modules += Git/SVN/Editor\n+modules += Git/SVN/Log\n modules += Git/SVN/Prompt\n modules += Git/SVN/Ra\n modules += Git/SVN/Utils\ndiff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t\nindex 97475d9..37626f4 100644\n--- a/t/Git-SVN/00compile.t\n+++ b/t/Git-SVN/00compile.t\n@@ -3,7 +3,9 @@\n use strict;\n use warnings;\n \n-use Test::More tests => 2;\n+use Test::More tests => 4;\n \n-require_ok 'Git::SVN::Utils';\n require_ok 'Git::SVN';\n+require_ok 'Git::SVN::Utils';\n+require_ok 'Git::SVN::Ra';\n+require_ok 'Git::SVN::Log';\n-- \n1.7.11.1\n"},{"id":"195913","messageId":"1343348767-86446-4-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 3/8] Prepare Git::SVN::Migration for extraction from git-svn.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:02Z","receivedAt":"2012-07-27T00:26:02Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\n* Load Git command functions on its own.\n* Load Git::SVN modules on its own.\n\nDrive by refactorings...\n* Use our() instead of use vars.\n* Eliminate the auto loading of Git functions.\n---\n git-svn.perl | 36 ++++++++++++++++++++++++------------\n 1 file changed, 24 insertions(+), 12 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 7c8da44..db60984 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -14,6 +14,18 @@ use Git::SVN;\n use Git::SVN::Log;\n use Git::SVN::Utils qw(fatal can_compress);\n \n+use Git qw(\n+    git_cmd_try\n+    command\n+    command_oneline\n+    command_noisy\n+    command_output_pipe\n+    command_close_pipe\n+    command_bidi_pipe\n+    command_close_bidi_pipe\n+);\n+\n+\n # From which subdir have we been invoked?\n my $cmd_dir_prefix = eval {\n \tcommand_oneline([qw/rev-parse --show-prefix/], STDERR => 0)\n@@ -75,7 +87,6 @@ use File::Spec;\n use File::Find;\n use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;\n use IPC::Open3;\n-use Git;\n use Git::SVN::Editor qw//;\n use Git::SVN::Fetcher qw//;\n use Git::SVN::Ra qw//;\n@@ -83,16 +94,6 @@ use Git::SVN::Prompt qw//;\n use Memoize;  # core since 5.8.0, Jul 2002\n \n BEGIN {\n-\t# import functions from Git into our packages, en masse\n-\tno strict 'refs';\n-\tforeach (qw/command command_oneline command_noisy command_output_pipe\n-\t            command_input_pipe command_close_pipe\n-\t            command_bidi_pipe command_close_bidi_pipe/) {\n-\t\tfor my $package ( qw(Git::SVN::Migration),\n-\t\t\t__PACKAGE__) {\n-\t\t\t*{\"${package}::$_\"} = \\&{\"Git::$_\"};\n-\t\t}\n-\t}\n \tMemoize::memoize 'Git::config';\n \tMemoize::memoize 'Git::config_bool';\n }\n@@ -2080,7 +2081,14 @@ use warnings;\n use Carp qw/croak/;\n use File::Path qw/mkpath/;\n use File::Basename qw/dirname basename/;\n-use vars qw/$_minimize/;\n+\n+our $_minimize;\n+use Git qw(\n+\tcommand\n+\tcommand_noisy\n+\tcommand_output_pipe\n+\tcommand_close_pipe\n+);\n \n sub migrate_from_v0 {\n \tmy $git_dir = $ENV{GIT_DIR};\n@@ -2189,6 +2197,7 @@ sub migrate_from_v2 {\n \tread_old_urls(\\%l_map, '', \"$ENV{GIT_DIR}/svn\");\n \tmy $migrated = 0;\n \n+\trequire Git::SVN;\n \tforeach my $ref_id (sort keys %l_map) {\n \t\teval { Git::SVN->init($l_map{$ref_id}, '', undef, $ref_id) };\n \t\tif ($@) {\n@@ -2200,6 +2209,9 @@ sub migrate_from_v2 {\n }\n \n sub minimize_connections {\n+\trequire Git::SVN;\n+\trequire Git::SVN::Ra;\n+\n \tmy $r = Git::SVN::read_all_remotes();\n \tmy $new_urls = {};\n \tmy $root_repos = {};\n-- \n1.7.11.1\n"},{"id":"195917","messageId":"1343348767-86446-5-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 4/8] Extract Git::SVN::Migration from git-svn.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:03Z","receivedAt":"2012-07-27T00:26:03Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\nStraight cut & paste.\n---\n git-svn.perl              | 258 +---------------------------------------------\n perl/Git/SVN/Migration.pm | 258 ++++++++++++++++++++++++++++++++++++++++++++++\n perl/Makefile             |   1 +\n t/Git-SVN/00compile.t     |   3 +-\n 4 files changed, 262 insertions(+), 258 deletions(-)\n create mode 100644 perl/Git/SVN/Migration.pm\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex db60984..3741e2e 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -12,6 +12,7 @@ $VERSION = '@@GIT_VERSION@@';\n \n use Git::SVN;\n use Git::SVN::Log;\n+use Git::SVN::Migration;\n use Git::SVN::Utils qw(fatal can_compress);\n \n use Git qw(\n@@ -2042,263 +2043,6 @@ sub gc_directory {\n }\n \n \n-package Git::SVN::Migration;\n-# these version numbers do NOT correspond to actual version numbers\n-# of git nor git-svn.  They are just relative.\n-#\n-# v0 layout: .git/$id/info/url, refs/heads/$id-HEAD\n-#\n-# v1 layout: .git/$id/info/url, refs/remotes/$id\n-#\n-# v2 layout: .git/svn/$id/info/url, refs/remotes/$id\n-#\n-# v3 layout: .git/svn/$id, refs/remotes/$id\n-#            - info/url may remain for backwards compatibility\n-#            - this is what we migrate up to this layout automatically,\n-#            - this will be used by git svn init on single branches\n-# v3.1 layout (auto migrated):\n-#            - .rev_db => .rev_db.$UUID, .rev_db will remain as a symlink\n-#              for backwards compatibility\n-#\n-# v4 layout: .git/svn/$repo_id/$id, refs/remotes/$repo_id/$id\n-#            - this is only created for newly multi-init-ed\n-#              repositories.  Similar in spirit to the\n-#              --use-separate-remotes option in git-clone (now default)\n-#            - we do not automatically migrate to this (following\n-#              the example set by core git)\n-#\n-# v5 layout: .rev_db.$UUID => .rev_map.$UUID\n-#            - newer, more-efficient format that uses 24-bytes per record\n-#              with no filler space.\n-#            - use xxd -c24 < .rev_map.$UUID to view and debug\n-#            - This is a one-way migration, repositories updated to the\n-#              new format will not be able to use old git-svn without\n-#              rebuilding the .rev_db.  Rebuilding the rev_db is not\n-#              possible if noMetadata or useSvmProps are set; but should\n-#              be no problem for users that use the (sensible) defaults.\n-use strict;\n-use warnings;\n-use Carp qw/croak/;\n-use File::Path qw/mkpath/;\n-use File::Basename qw/dirname basename/;\n-\n-our $_minimize;\n-use Git qw(\n-\tcommand\n-\tcommand_noisy\n-\tcommand_output_pipe\n-\tcommand_close_pipe\n-);\n-\n-sub migrate_from_v0 {\n-\tmy $git_dir = $ENV{GIT_DIR};\n-\treturn undef unless -d $git_dir;\n-\tmy ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);\n-\tmy $migrated = 0;\n-\twhile (<$fh>) {\n-\t\tchomp;\n-\t\tmy ($id, $orig_ref) = ($_, $_);\n-\t\tnext unless $id =~ s#^refs/heads/(.+)-HEAD$#$1#;\n-\t\tnext unless -f \"$git_dir/$id/info/url\";\n-\t\tmy $new_ref = \"refs/remotes/$id\";\n-\t\tif (::verify_ref(\"$new_ref^0\")) {\n-\t\t\tprint STDERR \"W: $orig_ref is probably an old \",\n-\t\t\t             \"branch used by an ancient version of \",\n-\t\t\t\t     \"git-svn.\\n\",\n-\t\t\t\t     \"However, $new_ref also exists.\\n\",\n-\t\t\t\t     \"We will not be able \",\n-\t\t\t\t     \"to use this branch until this \",\n-\t\t\t\t     \"ambiguity is resolved.\\n\";\n-\t\t\tnext;\n-\t\t}\n-\t\tprint STDERR \"Migrating from v0 layout...\\n\" if !$migrated;\n-\t\tprint STDERR \"Renaming ref: $orig_ref => $new_ref\\n\";\n-\t\tcommand_noisy('update-ref', $new_ref, $orig_ref);\n-\t\tcommand_noisy('update-ref', '-d', $orig_ref, $orig_ref);\n-\t\t$migrated++;\n-\t}\n-\tcommand_close_pipe($fh, $ctx);\n-\tprint STDERR \"Done migrating from v0 layout...\\n\" if $migrated;\n-\t$migrated;\n-}\n-\n-sub migrate_from_v1 {\n-\tmy $git_dir = $ENV{GIT_DIR};\n-\tmy $migrated = 0;\n-\treturn $migrated unless -d $git_dir;\n-\tmy $svn_dir = \"$git_dir/svn\";\n-\n-\t# just in case somebody used 'svn' as their $id at some point...\n-\treturn $migrated if -d $svn_dir && ! -f \"$svn_dir/info/url\";\n-\n-\tprint STDERR \"Migrating from a git-svn v1 layout...\\n\";\n-\tmkpath([$svn_dir]);\n-\tprint STDERR \"Data from a previous version of git-svn exists, but\\n\\t\",\n-\t             \"$svn_dir\\n\\t(required for this version \",\n-\t             \"($::VERSION) of git-svn) does not exist.\\n\";\n-\tmy ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);\n-\twhile (<$fh>) {\n-\t\tmy $x = $_;\n-\t\tnext unless $x =~ s#^refs/remotes/##;\n-\t\tchomp $x;\n-\t\tnext unless -f \"$git_dir/$x/info/url\";\n-\t\tmy $u = eval { ::file_to_s(\"$git_dir/$x/info/url\") };\n-\t\tnext unless $u;\n-\t\tmy $dn = dirname(\"$git_dir/svn/$x\");\n-\t\tmkpath([$dn]) unless -d $dn;\n-\t\tif ($x eq 'svn') { # they used 'svn' as GIT_SVN_ID:\n-\t\t\tmkpath([\"$git_dir/svn/svn\"]);\n-\t\t\tprint STDERR \" - $git_dir/$x/info => \",\n-\t\t\t                \"$git_dir/svn/$x/info\\n\";\n-\t\t\trename \"$git_dir/$x/info\", \"$git_dir/svn/$x/info\" or\n-\t\t\t       croak \"$!: $x\";\n-\t\t\t# don't worry too much about these, they probably\n-\t\t\t# don't exist with repos this old (save for index,\n-\t\t\t# and we can easily regenerate that)\n-\t\t\tforeach my $f (qw/unhandled.log index .rev_db/) {\n-\t\t\t\trename \"$git_dir/$x/$f\", \"$git_dir/svn/$x/$f\";\n-\t\t\t}\n-\t\t} else {\n-\t\t\tprint STDERR \" - $git_dir/$x => $git_dir/svn/$x\\n\";\n-\t\t\trename \"$git_dir/$x\", \"$git_dir/svn/$x\" or\n-\t\t\t       croak \"$!: $x\";\n-\t\t}\n-\t\t$migrated++;\n-\t}\n-\tcommand_close_pipe($fh, $ctx);\n-\tprint STDERR \"Done migrating from a git-svn v1 layout\\n\";\n-\t$migrated;\n-}\n-\n-sub read_old_urls {\n-\tmy ($l_map, $pfx, $path) = @_;\n-\tmy @dir;\n-\tforeach (<$path/*>) {\n-\t\tif (-r \"$_/info/url\") {\n-\t\t\t$pfx .= '/' if $pfx && $pfx !~ m!/$!;\n-\t\t\tmy $ref_id = $pfx . basename $_;\n-\t\t\tmy $url = ::file_to_s(\"$_/info/url\");\n-\t\t\t$l_map->{$ref_id} = $url;\n-\t\t} elsif (-d $_) {\n-\t\t\tpush @dir, $_;\n-\t\t}\n-\t}\n-\tforeach (@dir) {\n-\t\tmy $x = $_;\n-\t\t$x =~ s!^\\Q$ENV{GIT_DIR}\\E/svn/!!o;\n-\t\tread_old_urls($l_map, $x, $_);\n-\t}\n-}\n-\n-sub migrate_from_v2 {\n-\tmy @cfg = command(qw/config -l/);\n-\treturn if grep /^svn-remote\\..+\\.url=/, @cfg;\n-\tmy %l_map;\n-\tread_old_urls(\\%l_map, '', \"$ENV{GIT_DIR}/svn\");\n-\tmy $migrated = 0;\n-\n-\trequire Git::SVN;\n-\tforeach my $ref_id (sort keys %l_map) {\n-\t\teval { Git::SVN->init($l_map{$ref_id}, '', undef, $ref_id) };\n-\t\tif ($@) {\n-\t\t\tGit::SVN->init($l_map{$ref_id}, '', $ref_id, $ref_id);\n-\t\t}\n-\t\t$migrated++;\n-\t}\n-\t$migrated;\n-}\n-\n-sub minimize_connections {\n-\trequire Git::SVN;\n-\trequire Git::SVN::Ra;\n-\n-\tmy $r = Git::SVN::read_all_remotes();\n-\tmy $new_urls = {};\n-\tmy $root_repos = {};\n-\tforeach my $repo_id (keys %$r) {\n-\t\tmy $url = $r->{$repo_id}->{url} or next;\n-\t\tmy $fetch = $r->{$repo_id}->{fetch} or next;\n-\t\tmy $ra = Git::SVN::Ra->new($url);\n-\n-\t\t# skip existing cases where we already connect to the root\n-\t\tif (($ra->{url} eq $ra->{repos_root}) ||\n-\t\t    ($ra->{repos_root} eq $repo_id)) {\n-\t\t\t$root_repos->{$ra->{url}} = $repo_id;\n-\t\t\tnext;\n-\t\t}\n-\n-\t\tmy $root_ra = Git::SVN::Ra->new($ra->{repos_root});\n-\t\tmy $root_path = $ra->{url};\n-\t\t$root_path =~ s#^\\Q$ra->{repos_root}\\E(/|$)##;\n-\t\tforeach my $path (keys %$fetch) {\n-\t\t\tmy $ref_id = $fetch->{$path};\n-\t\t\tmy $gs = Git::SVN->new($ref_id, $repo_id, $path);\n-\n-\t\t\t# make sure we can read when connecting to\n-\t\t\t# a higher level of a repository\n-\t\t\tmy ($last_rev, undef) = $gs->last_rev_commit;\n-\t\t\tif (!defined $last_rev) {\n-\t\t\t\t$last_rev = eval {\n-\t\t\t\t\t$root_ra->get_latest_revnum;\n-\t\t\t\t};\n-\t\t\t\tnext if $@;\n-\t\t\t}\n-\t\t\tmy $new = $root_path;\n-\t\t\t$new .= length $path ? \"/$path\" : '';\n-\t\t\teval {\n-\t\t\t\t$root_ra->get_log([$new], $last_rev, $last_rev,\n-\t\t\t                          0, 0, 1, sub { });\n-\t\t\t};\n-\t\t\tnext if $@;\n-\t\t\t$new_urls->{$ra->{repos_root}}->{$new} =\n-\t\t\t        { ref_id => $ref_id,\n-\t\t\t\t  old_repo_id => $repo_id,\n-\t\t\t\t  old_path => $path };\n-\t\t}\n-\t}\n-\n-\tmy @emptied;\n-\tforeach my $url (keys %$new_urls) {\n-\t\t# see if we can re-use an existing [svn-remote \"repo_id\"]\n-\t\t# instead of creating a(n ugly) new section:\n-\t\tmy $repo_id = $root_repos->{$url} || $url;\n-\n-\t\tmy $fetch = $new_urls->{$url};\n-\t\tforeach my $path (keys %$fetch) {\n-\t\t\tmy $x = $fetch->{$path};\n-\t\t\tGit::SVN->init($url, $path, $repo_id, $x->{ref_id});\n-\t\t\tmy $pfx = \"svn-remote.$x->{old_repo_id}\";\n-\n-\t\t\tmy $old_fetch = quotemeta(\"$x->{old_path}:\".\n-\t\t\t                          \"$x->{ref_id}\");\n-\t\t\tcommand_noisy(qw/config --unset/,\n-\t\t\t              \"$pfx.fetch\", '^'. $old_fetch . '$');\n-\t\t\tdelete $r->{$x->{old_repo_id}}->\n-\t\t\t       {fetch}->{$x->{old_path}};\n-\t\t\tif (!keys %{$r->{$x->{old_repo_id}}->{fetch}}) {\n-\t\t\t\tcommand_noisy(qw/config --unset/,\n-\t\t\t\t              \"$pfx.url\");\n-\t\t\t\tpush @emptied, $x->{old_repo_id}\n-\t\t\t}\n-\t\t}\n-\t}\n-\tif (@emptied) {\n-\t\tmy $file = $ENV{GIT_CONFIG} || \"$ENV{GIT_DIR}/config\";\n-\t\tprint STDERR <<EOF;\n-The following [svn-remote] sections in your config file ($file) are empty\n-and can be safely removed:\n-EOF\n-\t\tprint STDERR \"[svn-remote \\\"$_\\\"]\\n\" foreach @emptied;\n-\t}\n-}\n-\n-sub migration_check {\n-\tmigrate_from_v0();\n-\tmigrate_from_v1();\n-\tmigrate_from_v2();\n-\tminimize_connections() if $_minimize;\n-}\n-\n package Git::IndexInfo;\n use strict;\n use warnings;\ndiff --git a/perl/Git/SVN/Migration.pm b/perl/Git/SVN/Migration.pm\nnew file mode 100644\nindex 0000000..75d7429\n--- /dev/null\n+++ b/perl/Git/SVN/Migration.pm\n@@ -0,0 +1,258 @@\n+package Git::SVN::Migration;\n+# these version numbers do NOT correspond to actual version numbers\n+# of git nor git-svn.  They are just relative.\n+#\n+# v0 layout: .git/$id/info/url, refs/heads/$id-HEAD\n+#\n+# v1 layout: .git/$id/info/url, refs/remotes/$id\n+#\n+# v2 layout: .git/svn/$id/info/url, refs/remotes/$id\n+#\n+# v3 layout: .git/svn/$id, refs/remotes/$id\n+#            - info/url may remain for backwards compatibility\n+#            - this is what we migrate up to this layout automatically,\n+#            - this will be used by git svn init on single branches\n+# v3.1 layout (auto migrated):\n+#            - .rev_db => .rev_db.$UUID, .rev_db will remain as a symlink\n+#              for backwards compatibility\n+#\n+# v4 layout: .git/svn/$repo_id/$id, refs/remotes/$repo_id/$id\n+#            - this is only created for newly multi-init-ed\n+#              repositories.  Similar in spirit to the\n+#              --use-separate-remotes option in git-clone (now default)\n+#            - we do not automatically migrate to this (following\n+#              the example set by core git)\n+#\n+# v5 layout: .rev_db.$UUID => .rev_map.$UUID\n+#            - newer, more-efficient format that uses 24-bytes per record\n+#              with no filler space.\n+#            - use xxd -c24 < .rev_map.$UUID to view and debug\n+#            - This is a one-way migration, repositories updated to the\n+#              new format will not be able to use old git-svn without\n+#              rebuilding the .rev_db.  Rebuilding the rev_db is not\n+#              possible if noMetadata or useSvmProps are set; but should\n+#              be no problem for users that use the (sensible) defaults.\n+use strict;\n+use warnings;\n+use Carp qw/croak/;\n+use File::Path qw/mkpath/;\n+use File::Basename qw/dirname basename/;\n+\n+our $_minimize;\n+use Git qw(\n+\tcommand\n+\tcommand_noisy\n+\tcommand_output_pipe\n+\tcommand_close_pipe\n+);\n+\n+sub migrate_from_v0 {\n+\tmy $git_dir = $ENV{GIT_DIR};\n+\treturn undef unless -d $git_dir;\n+\tmy ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);\n+\tmy $migrated = 0;\n+\twhile (<$fh>) {\n+\t\tchomp;\n+\t\tmy ($id, $orig_ref) = ($_, $_);\n+\t\tnext unless $id =~ s#^refs/heads/(.+)-HEAD$#$1#;\n+\t\tnext unless -f \"$git_dir/$id/info/url\";\n+\t\tmy $new_ref = \"refs/remotes/$id\";\n+\t\tif (::verify_ref(\"$new_ref^0\")) {\n+\t\t\tprint STDERR \"W: $orig_ref is probably an old \",\n+\t\t\t             \"branch used by an ancient version of \",\n+\t\t\t\t     \"git-svn.\\n\",\n+\t\t\t\t     \"However, $new_ref also exists.\\n\",\n+\t\t\t\t     \"We will not be able \",\n+\t\t\t\t     \"to use this branch until this \",\n+\t\t\t\t     \"ambiguity is resolved.\\n\";\n+\t\t\tnext;\n+\t\t}\n+\t\tprint STDERR \"Migrating from v0 layout...\\n\" if !$migrated;\n+\t\tprint STDERR \"Renaming ref: $orig_ref => $new_ref\\n\";\n+\t\tcommand_noisy('update-ref', $new_ref, $orig_ref);\n+\t\tcommand_noisy('update-ref', '-d', $orig_ref, $orig_ref);\n+\t\t$migrated++;\n+\t}\n+\tcommand_close_pipe($fh, $ctx);\n+\tprint STDERR \"Done migrating from v0 layout...\\n\" if $migrated;\n+\t$migrated;\n+}\n+\n+sub migrate_from_v1 {\n+\tmy $git_dir = $ENV{GIT_DIR};\n+\tmy $migrated = 0;\n+\treturn $migrated unless -d $git_dir;\n+\tmy $svn_dir = \"$git_dir/svn\";\n+\n+\t# just in case somebody used 'svn' as their $id at some point...\n+\treturn $migrated if -d $svn_dir && ! -f \"$svn_dir/info/url\";\n+\n+\tprint STDERR \"Migrating from a git-svn v1 layout...\\n\";\n+\tmkpath([$svn_dir]);\n+\tprint STDERR \"Data from a previous version of git-svn exists, but\\n\\t\",\n+\t             \"$svn_dir\\n\\t(required for this version \",\n+\t             \"($::VERSION) of git-svn) does not exist.\\n\";\n+\tmy ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);\n+\twhile (<$fh>) {\n+\t\tmy $x = $_;\n+\t\tnext unless $x =~ s#^refs/remotes/##;\n+\t\tchomp $x;\n+\t\tnext unless -f \"$git_dir/$x/info/url\";\n+\t\tmy $u = eval { ::file_to_s(\"$git_dir/$x/info/url\") };\n+\t\tnext unless $u;\n+\t\tmy $dn = dirname(\"$git_dir/svn/$x\");\n+\t\tmkpath([$dn]) unless -d $dn;\n+\t\tif ($x eq 'svn') { # they used 'svn' as GIT_SVN_ID:\n+\t\t\tmkpath([\"$git_dir/svn/svn\"]);\n+\t\t\tprint STDERR \" - $git_dir/$x/info => \",\n+\t\t\t                \"$git_dir/svn/$x/info\\n\";\n+\t\t\trename \"$git_dir/$x/info\", \"$git_dir/svn/$x/info\" or\n+\t\t\t       croak \"$!: $x\";\n+\t\t\t# don't worry too much about these, they probably\n+\t\t\t# don't exist with repos this old (save for index,\n+\t\t\t# and we can easily regenerate that)\n+\t\t\tforeach my $f (qw/unhandled.log index .rev_db/) {\n+\t\t\t\trename \"$git_dir/$x/$f\", \"$git_dir/svn/$x/$f\";\n+\t\t\t}\n+\t\t} else {\n+\t\t\tprint STDERR \" - $git_dir/$x => $git_dir/svn/$x\\n\";\n+\t\t\trename \"$git_dir/$x\", \"$git_dir/svn/$x\" or\n+\t\t\t       croak \"$!: $x\";\n+\t\t}\n+\t\t$migrated++;\n+\t}\n+\tcommand_close_pipe($fh, $ctx);\n+\tprint STDERR \"Done migrating from a git-svn v1 layout\\n\";\n+\t$migrated;\n+}\n+\n+sub read_old_urls {\n+\tmy ($l_map, $pfx, $path) = @_;\n+\tmy @dir;\n+\tforeach (<$path/*>) {\n+\t\tif (-r \"$_/info/url\") {\n+\t\t\t$pfx .= '/' if $pfx && $pfx !~ m!/$!;\n+\t\t\tmy $ref_id = $pfx . basename $_;\n+\t\t\tmy $url = ::file_to_s(\"$_/info/url\");\n+\t\t\t$l_map->{$ref_id} = $url;\n+\t\t} elsif (-d $_) {\n+\t\t\tpush @dir, $_;\n+\t\t}\n+\t}\n+\tforeach (@dir) {\n+\t\tmy $x = $_;\n+\t\t$x =~ s!^\\Q$ENV{GIT_DIR}\\E/svn/!!o;\n+\t\tread_old_urls($l_map, $x, $_);\n+\t}\n+}\n+\n+sub migrate_from_v2 {\n+\tmy @cfg = command(qw/config -l/);\n+\treturn if grep /^svn-remote\\..+\\.url=/, @cfg;\n+\tmy %l_map;\n+\tread_old_urls(\\%l_map, '', \"$ENV{GIT_DIR}/svn\");\n+\tmy $migrated = 0;\n+\n+\trequire Git::SVN;\n+\tforeach my $ref_id (sort keys %l_map) {\n+\t\teval { Git::SVN->init($l_map{$ref_id}, '', undef, $ref_id) };\n+\t\tif ($@) {\n+\t\t\tGit::SVN->init($l_map{$ref_id}, '', $ref_id, $ref_id);\n+\t\t}\n+\t\t$migrated++;\n+\t}\n+\t$migrated;\n+}\n+\n+sub minimize_connections {\n+\trequire Git::SVN;\n+\trequire Git::SVN::Ra;\n+\n+\tmy $r = Git::SVN::read_all_remotes();\n+\tmy $new_urls = {};\n+\tmy $root_repos = {};\n+\tforeach my $repo_id (keys %$r) {\n+\t\tmy $url = $r->{$repo_id}->{url} or next;\n+\t\tmy $fetch = $r->{$repo_id}->{fetch} or next;\n+\t\tmy $ra = Git::SVN::Ra->new($url);\n+\n+\t\t# skip existing cases where we already connect to the root\n+\t\tif (($ra->{url} eq $ra->{repos_root}) ||\n+\t\t    ($ra->{repos_root} eq $repo_id)) {\n+\t\t\t$root_repos->{$ra->{url}} = $repo_id;\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tmy $root_ra = Git::SVN::Ra->new($ra->{repos_root});\n+\t\tmy $root_path = $ra->{url};\n+\t\t$root_path =~ s#^\\Q$ra->{repos_root}\\E(/|$)##;\n+\t\tforeach my $path (keys %$fetch) {\n+\t\t\tmy $ref_id = $fetch->{$path};\n+\t\t\tmy $gs = Git::SVN->new($ref_id, $repo_id, $path);\n+\n+\t\t\t# make sure we can read when connecting to\n+\t\t\t# a higher level of a repository\n+\t\t\tmy ($last_rev, undef) = $gs->last_rev_commit;\n+\t\t\tif (!defined $last_rev) {\n+\t\t\t\t$last_rev = eval {\n+\t\t\t\t\t$root_ra->get_latest_revnum;\n+\t\t\t\t};\n+\t\t\t\tnext if $@;\n+\t\t\t}\n+\t\t\tmy $new = $root_path;\n+\t\t\t$new .= length $path ? \"/$path\" : '';\n+\t\t\teval {\n+\t\t\t\t$root_ra->get_log([$new], $last_rev, $last_rev,\n+\t\t\t                          0, 0, 1, sub { });\n+\t\t\t};\n+\t\t\tnext if $@;\n+\t\t\t$new_urls->{$ra->{repos_root}}->{$new} =\n+\t\t\t        { ref_id => $ref_id,\n+\t\t\t\t  old_repo_id => $repo_id,\n+\t\t\t\t  old_path => $path };\n+\t\t}\n+\t}\n+\n+\tmy @emptied;\n+\tforeach my $url (keys %$new_urls) {\n+\t\t# see if we can re-use an existing [svn-remote \"repo_id\"]\n+\t\t# instead of creating a(n ugly) new section:\n+\t\tmy $repo_id = $root_repos->{$url} || $url;\n+\n+\t\tmy $fetch = $new_urls->{$url};\n+\t\tforeach my $path (keys %$fetch) {\n+\t\t\tmy $x = $fetch->{$path};\n+\t\t\tGit::SVN->init($url, $path, $repo_id, $x->{ref_id});\n+\t\t\tmy $pfx = \"svn-remote.$x->{old_repo_id}\";\n+\n+\t\t\tmy $old_fetch = quotemeta(\"$x->{old_path}:\".\n+\t\t\t                          \"$x->{ref_id}\");\n+\t\t\tcommand_noisy(qw/config --unset/,\n+\t\t\t              \"$pfx.fetch\", '^'. $old_fetch . '$');\n+\t\t\tdelete $r->{$x->{old_repo_id}}->\n+\t\t\t       {fetch}->{$x->{old_path}};\n+\t\t\tif (!keys %{$r->{$x->{old_repo_id}}->{fetch}}) {\n+\t\t\t\tcommand_noisy(qw/config --unset/,\n+\t\t\t\t              \"$pfx.url\");\n+\t\t\t\tpush @emptied, $x->{old_repo_id}\n+\t\t\t}\n+\t\t}\n+\t}\n+\tif (@emptied) {\n+\t\tmy $file = $ENV{GIT_CONFIG} || \"$ENV{GIT_DIR}/config\";\n+\t\tprint STDERR <<EOF;\n+The following [svn-remote] sections in your config file ($file) are empty\n+and can be safely removed:\n+EOF\n+\t\tprint STDERR \"[svn-remote \\\"$_\\\"]\\n\" foreach @emptied;\n+\t}\n+}\n+\n+sub migration_check {\n+\tmigrate_from_v0();\n+\tmigrate_from_v1();\n+\tmigrate_from_v2();\n+\tminimize_connections() if $_minimize;\n+}\n+\n+1;\ndiff --git a/perl/Makefile b/perl/Makefile\nindex 8493d76..ff83848 100644\n--- a/perl/Makefile\n+++ b/perl/Makefile\n@@ -31,6 +31,7 @@ modules += Git/SVN/Memoize/YAML\n modules += Git/SVN/Fetcher\n modules += Git/SVN/Editor\n modules += Git/SVN/Log\n+modules += Git/SVN/Migration\n modules += Git/SVN/Prompt\n modules += Git/SVN/Ra\n modules += Git/SVN/Utils\ndiff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t\nindex 37626f4..1307b65 100644\n--- a/t/Git-SVN/00compile.t\n+++ b/t/Git-SVN/00compile.t\n@@ -3,9 +3,10 @@\n use strict;\n use warnings;\n \n-use Test::More tests => 4;\n+use Test::More tests => 5;\n \n require_ok 'Git::SVN';\n require_ok 'Git::SVN::Utils';\n require_ok 'Git::SVN::Ra';\n require_ok 'Git::SVN::Log';\n+require_ok 'Git::SVN::Migration';\n-- \n1.7.11.1\n"},{"id":"195918","messageId":"1343348767-86446-6-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 5/8] Load all the modules in one place and before running code.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:04Z","receivedAt":"2012-07-27T00:26:04Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\nJust makes the code easier to follow.  No functional change.\n\nAlso eliminate an unused lexical $SVN.\n---\n git-svn.perl | 44 +++++++++++++++++++++-----------------------\n 1 file changed, 21 insertions(+), 23 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 3741e2e..fc49ad6 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -10,11 +10,26 @@ use vars qw/\t$AUTHOR $VERSION\n $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n $VERSION = '@@GIT_VERSION@@';\n \n+use Carp qw/croak/;\n+use Digest::MD5;\n+use IO::File qw//;\n+use File::Basename qw/dirname basename/;\n+use File::Path qw/mkpath/;\n+use File::Spec;\n+use File::Find;\n+use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;\n+use IPC::Open3;\n+use Memoize;\n+\n use Git::SVN;\n+use Git::SVN::Editor;\n+use Git::SVN::Fetcher;\n+use Git::SVN::Ra;\n+use Git::SVN::Prompt;\n use Git::SVN::Log;\n use Git::SVN::Migration;\n-use Git::SVN::Utils qw(fatal can_compress);\n \n+use Git::SVN::Utils qw(fatal can_compress);\n use Git qw(\n     git_cmd_try\n     command\n@@ -26,6 +41,11 @@ use Git qw(\n     command_close_bidi_pipe\n );\n \n+BEGIN {\n+\tMemoize::memoize 'Git::config';\n+\tMemoize::memoize 'Git::config_bool';\n+}\n+\n \n # From which subdir have we been invoked?\n my $cmd_dir_prefix = eval {\n@@ -79,28 +99,6 @@ sub _req_svn {\n \t}\n }\n \n-use Carp qw/croak/;\n-use Digest::MD5;\n-use IO::File qw//;\n-use File::Basename qw/dirname basename/;\n-use File::Path qw/mkpath/;\n-use File::Spec;\n-use File::Find;\n-use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;\n-use IPC::Open3;\n-use Git::SVN::Editor qw//;\n-use Git::SVN::Fetcher qw//;\n-use Git::SVN::Ra qw//;\n-use Git::SVN::Prompt qw//;\n-use Memoize;  # core since 5.8.0, Jul 2002\n-\n-BEGIN {\n-\tMemoize::memoize 'Git::config';\n-\tMemoize::memoize 'Git::config_bool';\n-}\n-\n-my ($SVN);\n-\n $sha1 = qr/[a-f\\d]{40}/;\n $sha1_short = qr/[a-f\\d]{4,40}/;\n my ($_stdin, $_help, $_edit,\n-- \n1.7.11.1\n"},{"id":"195916","messageId":"1343348767-86446-7-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 6/8] Move Git::IndexInfo into its own file.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:05Z","receivedAt":"2012-07-27T00:26:05Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\nStraight cut & paste.  Didn't require any fixing.\n---\n git-svn.perl            | 32 --------------------------------\n perl/Git/IndexInfo.pm   | 33 +++++++++++++++++++++++++++++++++\n perl/Git/SVN/Fetcher.pm |  1 +\n perl/Makefile           |  1 +\n t/Git-SVN/00compile.t   |  3 ++-\n 5 files changed, 37 insertions(+), 33 deletions(-)\n create mode 100644 perl/Git/IndexInfo.pm\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex fc49ad6..0856a77 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -2041,38 +2041,6 @@ sub gc_directory {\n }\n \n \n-package Git::IndexInfo;\n-use strict;\n-use warnings;\n-use Git qw/command_input_pipe command_close_pipe/;\n-\n-sub new {\n-\tmy ($class) = @_;\n-\tmy ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);\n-\tbless { gui => $gui, ctx => $ctx, nr => 0}, $class;\n-}\n-\n-sub remove {\n-\tmy ($self, $path) = @_;\n-\tif (print { $self->{gui} } '0 ', 0 x 40, \"\\t\", $path, \"\\0\") {\n-\t\treturn ++$self->{nr};\n-\t}\n-\tundef;\n-}\n-\n-sub update {\n-\tmy ($self, $mode, $hash, $path) = @_;\n-\tif (print { $self->{gui} } $mode, ' ', $hash, \"\\t\", $path, \"\\0\") {\n-\t\treturn ++$self->{nr};\n-\t}\n-\tundef;\n-}\n-\n-sub DESTROY {\n-\tmy ($self) = @_;\n-\tcommand_close_pipe($self->{gui}, $self->{ctx});\n-}\n-\n package Git::SVN::GlobSpec;\n use strict;\n use warnings;\ndiff --git a/perl/Git/IndexInfo.pm b/perl/Git/IndexInfo.pm\nnew file mode 100644\nindex 0000000..a43108c\n--- /dev/null\n+++ b/perl/Git/IndexInfo.pm\n@@ -0,0 +1,33 @@\n+package Git::IndexInfo;\n+use strict;\n+use warnings;\n+use Git qw/command_input_pipe command_close_pipe/;\n+\n+sub new {\n+\tmy ($class) = @_;\n+\tmy ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);\n+\tbless { gui => $gui, ctx => $ctx, nr => 0}, $class;\n+}\n+\n+sub remove {\n+\tmy ($self, $path) = @_;\n+\tif (print { $self->{gui} } '0 ', 0 x 40, \"\\t\", $path, \"\\0\") {\n+\t\treturn ++$self->{nr};\n+\t}\n+\tundef;\n+}\n+\n+sub update {\n+\tmy ($self, $mode, $hash, $path) = @_;\n+\tif (print { $self->{gui} } $mode, ' ', $hash, \"\\t\", $path, \"\\0\") {\n+\t\treturn ++$self->{nr};\n+\t}\n+\tundef;\n+}\n+\n+sub DESTROY {\n+\tmy ($self) = @_;\n+\tcommand_close_pipe($self->{gui}, $self->{ctx});\n+}\n+\n+1;\ndiff --git a/perl/Git/SVN/Fetcher.pm b/perl/Git/SVN/Fetcher.pm\nindex ef8e9ed..76fae9b 100644\n--- a/perl/Git/SVN/Fetcher.pm\n+++ b/perl/Git/SVN/Fetcher.pm\n@@ -57,6 +57,7 @@ sub new {\n \t$self->{file_prop} = {};\n \t$self->{absent_dir} = {};\n \t$self->{absent_file} = {};\n+\trequire Git::IndexInfo;\n \t$self->{gii} = $git_svn->tmp_index_do(sub { Git::IndexInfo->new });\n \t$self->{pathnameencoding} = Git::config('svn.pathnameencoding');\n \t$self;\ndiff --git a/perl/Makefile b/perl/Makefile\nindex ff83848..2428e59 100644\n--- a/perl/Makefile\n+++ b/perl/Makefile\n@@ -26,6 +26,7 @@ instdir_SQ = $(subst ','\\'',$(prefix)/lib)\n \n modules += Git\n modules += Git/I18N\n+modules += Git/IndexInfo\n modules += Git/SVN\n modules += Git/SVN/Memoize/YAML\n modules += Git/SVN/Fetcher\ndiff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t\nindex 1307b65..5419438 100644\n--- a/t/Git-SVN/00compile.t\n+++ b/t/Git-SVN/00compile.t\n@@ -3,10 +3,11 @@\n use strict;\n use warnings;\n \n-use Test::More tests => 5;\n+use Test::More tests => 6;\n \n require_ok 'Git::SVN';\n require_ok 'Git::SVN::Utils';\n require_ok 'Git::SVN::Ra';\n require_ok 'Git::SVN::Log';\n require_ok 'Git::SVN::Migration';\n+require_ok 'Git::IndexInfo';\n-- \n1.7.11.1\n"},{"id":"195914","messageId":"1343348767-86446-8-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 7/8] Extract Git::SVN::GlobSpec from git-svn.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:06Z","receivedAt":"2012-07-27T00:26:06Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\nStraight cut & paste.  That's the last class.\n\n* Make Git::SVN load it on its own, its the only thing that needs it.\n---\n git-svn.perl             | 59 ------------------------------------------------\n perl/Git/SVN.pm          |  2 ++\n perl/Git/SVN/GlobSpec.pm | 59 ++++++++++++++++++++++++++++++++++++++++++++++++\n perl/Makefile            |  1 +\n t/Git-SVN/00compile.t    |  3 ++-\n 5 files changed, 64 insertions(+), 60 deletions(-)\n create mode 100644 perl/Git/SVN/GlobSpec.pm\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 0856a77..584e93a 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -2040,65 +2040,6 @@ sub gc_directory {\n \t}\n }\n \n-\n-package Git::SVN::GlobSpec;\n-use strict;\n-use warnings;\n-\n-sub new {\n-\tmy ($class, $glob, $pattern_ok) = @_;\n-\tmy $re = $glob;\n-\t$re =~ s!/+$!!g; # no need for trailing slashes\n-\tmy (@left, @right, @patterns);\n-\tmy $state = \"left\";\n-\tmy $die_msg = \"Only one set of wildcard directories \" .\n-\t\t\t\t\"(e.g. '*' or '*/*/*') is supported: '$glob'\\n\";\n-\tfor my $part (split(m|/|, $glob)) {\n-\t\tif ($part =~ /\\*/ && $part ne \"*\") {\n-\t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n-\t\t} elsif ($pattern_ok && $part =~ /[{}]/ &&\n-\t\t\t $part !~ /^\\{[^{}]+\\}/) {\n-\t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n-\t\t}\n-\t\tif ($part eq \"*\") {\n-\t\t\tdie $die_msg if $state eq \"right\";\n-\t\t\t$state = \"pattern\";\n-\t\t\tpush(@patterns, \"[^/]*\");\n-\t\t} elsif ($pattern_ok && $part =~ /^\\{(.*)\\}$/) {\n-\t\t\tdie $die_msg if $state eq \"right\";\n-\t\t\t$state = \"pattern\";\n-\t\t\tmy $p = quotemeta($1);\n-\t\t\t$p =~ s/\\\\,/|/g;\n-\t\t\tpush(@patterns, \"(?:$p)\");\n-\t\t} else {\n-\t\t\tif ($state eq \"left\") {\n-\t\t\t\tpush(@left, $part);\n-\t\t\t} else {\n-\t\t\t\tpush(@right, $part);\n-\t\t\t\t$state = \"right\";\n-\t\t\t}\n-\t\t}\n-\t}\n-\tmy $depth = @patterns;\n-\tif ($depth == 0) {\n-\t\tdie \"One '*' is needed in glob: '$glob'\\n\";\n-\t}\n-\tmy $left = join('/', @left);\n-\tmy $right = join('/', @right);\n-\t$re = join('/', @patterns);\n-\t$re = join('\\/',\n-\t\t   grep(length, quotemeta($left), \"($re)\", quotemeta($right)));\n-\tmy $left_re = qr/^\\/\\Q$left\\E(\\/|$)/;\n-\tbless { left => $left, right => $right, left_regex => $left_re,\n-\t        regex => qr/$re/, glob => $glob, depth => $depth }, $class;\n-}\n-\n-sub full_path {\n-\tmy ($self, $path) = @_;\n-\treturn (length $self->{left} ? \"$self->{left}/\" : '') .\n-\t       $path . (length $self->{right} ? \"/$self->{right}\" : '');\n-}\n-\n __END__\n \n Data structures:\ndiff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm\nindex 2e0d7f0..b8b3474 100644\n--- a/perl/Git/SVN.pm\n+++ b/perl/Git/SVN.pm\n@@ -207,6 +207,8 @@ sub read_all_remotes {\n \t\t\t    . \"must start with 'refs/'\\n\")\n \t\t\t\tunless $remote_ref =~ m{^refs/};\n \t\t\t$local_ref = uri_decode($local_ref);\n+\n+\t\t\trequire Git::SVN::GlobSpec;\n \t\t\tmy $rs = {\n \t\t\t    t => $t,\n \t\t\t    remote => $remote,\ndiff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm\nnew file mode 100644\nindex 0000000..96cfd98\n--- /dev/null\n+++ b/perl/Git/SVN/GlobSpec.pm\n@@ -0,0 +1,59 @@\n+package Git::SVN::GlobSpec;\n+use strict;\n+use warnings;\n+\n+sub new {\n+\tmy ($class, $glob, $pattern_ok) = @_;\n+\tmy $re = $glob;\n+\t$re =~ s!/+$!!g; # no need for trailing slashes\n+\tmy (@left, @right, @patterns);\n+\tmy $state = \"left\";\n+\tmy $die_msg = \"Only one set of wildcard directories \" .\n+\t\t\t\t\"(e.g. '*' or '*/*/*') is supported: '$glob'\\n\";\n+\tfor my $part (split(m|/|, $glob)) {\n+\t\tif ($part =~ /\\*/ && $part ne \"*\") {\n+\t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n+\t\t} elsif ($pattern_ok && $part =~ /[{}]/ &&\n+\t\t\t $part !~ /^\\{[^{}]+\\}/) {\n+\t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n+\t\t}\n+\t\tif ($part eq \"*\") {\n+\t\t\tdie $die_msg if $state eq \"right\";\n+\t\t\t$state = \"pattern\";\n+\t\t\tpush(@patterns, \"[^/]*\");\n+\t\t} elsif ($pattern_ok && $part =~ /^\\{(.*)\\}$/) {\n+\t\t\tdie $die_msg if $state eq \"right\";\n+\t\t\t$state = \"pattern\";\n+\t\t\tmy $p = quotemeta($1);\n+\t\t\t$p =~ s/\\\\,/|/g;\n+\t\t\tpush(@patterns, \"(?:$p)\");\n+\t\t} else {\n+\t\t\tif ($state eq \"left\") {\n+\t\t\t\tpush(@left, $part);\n+\t\t\t} else {\n+\t\t\t\tpush(@right, $part);\n+\t\t\t\t$state = \"right\";\n+\t\t\t}\n+\t\t}\n+\t}\n+\tmy $depth = @patterns;\n+\tif ($depth == 0) {\n+\t\tdie \"One '*' is needed in glob: '$glob'\\n\";\n+\t}\n+\tmy $left = join('/', @left);\n+\tmy $right = join('/', @right);\n+\t$re = join('/', @patterns);\n+\t$re = join('\\/',\n+\t\t   grep(length, quotemeta($left), \"($re)\", quotemeta($right)));\n+\tmy $left_re = qr/^\\/\\Q$left\\E(\\/|$)/;\n+\tbless { left => $left, right => $right, left_regex => $left_re,\n+\t        regex => qr/$re/, glob => $glob, depth => $depth }, $class;\n+}\n+\n+sub full_path {\n+\tmy ($self, $path) = @_;\n+\treturn (length $self->{left} ? \"$self->{left}/\" : '') .\n+\t       $path . (length $self->{right} ? \"/$self->{right}\" : '');\n+}\n+\n+1;\ndiff --git a/perl/Makefile b/perl/Makefile\nindex 2428e59..22e3e81 100644\n--- a/perl/Makefile\n+++ b/perl/Makefile\n@@ -31,6 +31,7 @@ modules += Git/SVN\n modules += Git/SVN/Memoize/YAML\n modules += Git/SVN/Fetcher\n modules += Git/SVN/Editor\n+modules += Git/SVN/GlobSpec\n modules += Git/SVN/Log\n modules += Git/SVN/Migration\n modules += Git/SVN/Prompt\ndiff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t\nindex 5419438..c92fee4 100644\n--- a/t/Git-SVN/00compile.t\n+++ b/t/Git-SVN/00compile.t\n@@ -3,7 +3,7 @@\n use strict;\n use warnings;\n \n-use Test::More tests => 6;\n+use Test::More tests => 7;\n \n require_ok 'Git::SVN';\n require_ok 'Git::SVN::Utils';\n@@ -11,3 +11,4 @@ require_ok 'Git::SVN::Ra';\n require_ok 'Git::SVN::Log';\n require_ok 'Git::SVN::Migration';\n require_ok 'Git::IndexInfo';\n+require_ok 'Git::SVN::GlobSpec';\n-- \n1.7.11.1\n"},{"id":"195915","messageId":"1343348767-86446-9-git-send-email-schwern@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"[PATCH 8/8] Fix indents to match style.","fromName":"Michael G. Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:26:07Z","receivedAt":"2012-07-27T00:26:07Z","isPatch":true,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"From: \"Michael G. Schwern\" <schwern@pobox.com>\n\n---\n git-svn.perl | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 584e93a..4d173d4 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -31,14 +31,14 @@ use Git::SVN::Migration;\n \n use Git::SVN::Utils qw(fatal can_compress);\n use Git qw(\n-    git_cmd_try\n-    command\n-    command_oneline\n-    command_noisy\n-    command_output_pipe\n-    command_close_pipe\n-    command_bidi_pipe\n-    command_close_bidi_pipe\n+\tgit_cmd_try\n+\tcommand\n+\tcommand_oneline\n+\tcommand_noisy\n+\tcommand_output_pipe\n+\tcommand_close_pipe\n+\tcommand_bidi_pipe\n+\tcommand_close_bidi_pipe\n );\n \n BEGIN {\n-- \n1.7.11.1\n"},{"id":"195919","messageId":"5011E07A.807@pobox.com","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"Re: Extract remaining classes from git-svn","fromName":"Michael G Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T00:27:38Z","receivedAt":"2012-07-27T00:27:38Z","isPatch":false,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"On 2012.7.26 5:25 PM, Michael G. Schwern wrote:\n> This series of patches extracts the remaining classes from git-svn.  They're\n> all simple extractions and functionally have no change.\n\nPS  This is on top of the previous Git::SVN extraction patch series.\n\n\n-- \n100. Claymore mines are not filled with yummy candy, and it is wrong\n     to tell new soldiers that they are.\n    -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army\n           http://skippyslist.com/list/\n"},{"id":"195937","messageId":"CABPQNSYjvW9GZs18j+m4mUT6jiJ5VTUdnyi-L5Q8tHeqE7R+tg@mail.gmail.com","threadId":"31111","inReplyTo":"5011E07A.807@pobox.com","subject":"Re: Extract remaining classes from git-svn","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2012-07-27T11:29:52Z","receivedAt":"2012-07-27T11:29:52Z","isPatch":false,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Fri, Jul 27, 2012 at 2:27 AM, Michael G Schwern <schwern@pobox.com> wrote:\n> On 2012.7.26 5:25 PM, Michael G. Schwern wrote:\n>> This series of patches extracts the remaining classes from git-svn.  They're\n>> all simple extractions and functionally have no change.\n>\n> PS  This is on top of the previous Git::SVN extraction patch series.\n>\n\nNice :-)\n\nDo you have somewhere I can pull this from? I have a git-svn topic\nthat I suspect will be much easier to maintain on top of these\npatches.\n"},{"id":"195956","messageId":"5012E536.5080507@pobox.com","threadId":"31111","inReplyTo":"CABPQNSYjvW9GZs18j+m4mUT6jiJ5VTUdnyi-L5Q8tHeqE7R+tg@mail.gmail.com","subject":"Re: Extract remaining classes from git-svn","fromName":"Michael G Schwern","fromEmail":"schwern@pobox.com","sentAt":"2012-07-27T19:00:06Z","receivedAt":"2012-07-27T19:00:06Z","isPatch":false,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"On 2012.7.27 4:29 AM, Erik Faye-Lund wrote:\n> On Fri, Jul 27, 2012 at 2:27 AM, Michael G Schwern <schwern@pobox.com> wrote:\n>> On 2012.7.26 5:25 PM, Michael G. Schwern wrote:\n>>> This series of patches extracts the remaining classes from git-svn.  They're\n>>> all simple extractions and functionally have no change.\n>>\n>> PS  This is on top of the previous Git::SVN extraction patch series.\n>>\n> \n> Nice :-)\n> \n> Do you have somewhere I can pull this from? I have a git-svn topic\n> that I suspect will be much easier to maintain on top of these\n> patches.\n\nWhy yes I do!\nhttps://github.com/schwern/git\n\nThe git-svn branches should be fairly self explanatory and they stack on top\nof each other.  I'll probably be doing a lot of rebasing still, but there\nshould be little content change up to git-svn/canonicalize-accessors.  Up to\nthere passes tests with SVN 1.6.\n\nThings get a little fuzzy after that.\n\n\n-- \n24. Must not tell any officer that I am smarter than they are, especially\n    if it's true.\n    -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army\n           http://skippyslist.com/list/\n"},{"id":"195984","messageId":"20120728004026.GA5363@dcvr.yhbt.net","threadId":"31111","inReplyTo":"1343348767-86446-1-git-send-email-schwern@pobox.com","subject":"Re: Extract remaining classes from git-svn","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2012-07-28T00:40:26Z","receivedAt":"2012-07-28T00:40:26Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"\"Michael G. Schwern\" <schwern@pobox.com> wrote:\n> This series of patches extracts the remaining classes from git-svn.  They're\n> all simple extractions and functionally have no change.\n\nI've also pushed this to the \"extract-remaining\" series which\nalso includes everything that's currently in my master.\n\nI squashed Michael's 8/8 trivial change into 3/8 to avoid introducing\na needless commit.  (I don't feel strongly about indentation for\nalignment purposes in use() statements much, but since he submitted\nthe change...)\n\n\nThe following changes since commit cdd159b2f56c9e69e37bbb8f5af301abd93e5407:\n\n  Merge branch 'jc/test-lib-source-build-options-early' (2012-07-25 15:47:08 -0700)\n\nare available in the git repository at:\n\n\n  git://bogomips.org/git-svn extract-remaining\n\nfor you to fetch changes up to 3d9be15fc2b8c8198253ae1c4dcaa343b74c3b8d:\n\n  Extract Git::SVN::GlobSpec from git-svn. (2012-07-27 22:36:19 +0000)\n\n----------------------------------------------------------------\nJunio C Hamano (1):\n      perl: detect new files in MakeMaker builds\n\nMichael G. Schwern (14):\n      Quiet warning if Makefile.PL is run with -w and no --localedir\n      Don't lose Error.pm if $@ gets clobbered.\n      The Makefile.PL will now find .pm files itself.\n      Extract some utilities from git-svn to allow extracting Git::SVN.\n      Prepare Git::SVN for extraction into its own file.\n      Extract Git::SVN from git-svn into its own .pm file.\n      Move initialization of Git::SVN variables into Git::SVN.\n      Prepare Git::SVN::Log for extraction from git-svn.\n      Extract Git::SVN::Log from git-svn.\n      Prepare Git::SVN::Migration for extraction from git-svn.\n      Extract Git::SVN::Migration from git-svn.\n      Load all the modules in one place and before running code.\n      Move Git::IndexInfo into its own file.\n      Extract Git::SVN::GlobSpec from git-svn.\n\n Makefile                       |    7 +\n git-svn.perl                   | 3119 +---------------------------------------\n perl/.gitignore                |    1 +\n perl/Git/IndexInfo.pm          |   33 +\n perl/Git/SVN.pm                | 2326 ++++++++++++++++++++++++++++++\n perl/Git/SVN/Fetcher.pm        |    1 +\n perl/Git/SVN/GlobSpec.pm       |   59 +\n perl/Git/SVN/Log.pm            |  395 +++++\n perl/Git/SVN/Migration.pm      |  258 ++++\n perl/Git/SVN/Utils.pm          |   59 +\n perl/Makefile                  |    9 +\n perl/Makefile.PL               |   35 +-\n t/Git-SVN/00compile.t          |   14 +\n t/Git-SVN/Utils/can_compress.t |   11 +\n t/Git-SVN/Utils/fatal.t        |   34 +\n 15 files changed, 3272 insertions(+), 3089 deletions(-)\n create mode 100644 perl/Git/IndexInfo.pm\n create mode 100644 perl/Git/SVN.pm\n create mode 100644 perl/Git/SVN/GlobSpec.pm\n create mode 100644 perl/Git/SVN/Log.pm\n create mode 100644 perl/Git/SVN/Migration.pm\n create mode 100644 perl/Git/SVN/Utils.pm\n create mode 100644 t/Git-SVN/00compile.t\n create mode 100644 t/Git-SVN/Utils/can_compress.t\n create mode 100644 t/Git-SVN/Utils/fatal.t\n"},{"id":"195988","messageId":"7vfw8cy1gv.fsf@alter.siamese.dyndns.org","threadId":"31111","inReplyTo":"20120728004026.GA5363@dcvr.yhbt.net","subject":"Re: Extract remaining classes from git-svn","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-28T04:05:36Z","receivedAt":"2012-07-28T04:05:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Wong <normalperson@yhbt.net> writes:\n\n> \"Michael G. Schwern\" <schwern@pobox.com> wrote:\n>> This series of patches extracts the remaining classes from git-svn.  They're\n>> all simple extractions and functionally have no change.\n>\n> I've also pushed this to the \"extract-remaining\" series which\n> also includes everything that's currently in my master.\n\nDo you mean this should go in 1.7.12-rc1, or your master is for\n1.7.12 and this is for post 1.7.12 but you are pushing it out to\nhelp other developers who are working on git-svn as a preview?\n\nI didn't look at these follow-up patches, but if you say they are\nfit for the upcoming release, that is good enough for me.  Just\nchecking which way you want us to go.\n\nThanks.\n"},{"id":"195989","messageId":"20120728041223.GB6129@dcvr.yhbt.net","threadId":"31111","inReplyTo":"7vfw8cy1gv.fsf@alter.siamese.dyndns.org","subject":"Re: Extract remaining classes from git-svn","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2012-07-28T04:12:23Z","receivedAt":"2012-07-28T04:12:23Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Wong <normalperson@yhbt.net> writes:\n> \n> > \"Michael G. Schwern\" <schwern@pobox.com> wrote:\n> >> This series of patches extracts the remaining classes from git-svn.  They're\n> >> all simple extractions and functionally have no change.\n> >\n> > I've also pushed this to the \"extract-remaining\" series which\n> > also includes everything that's currently in my master.\n> \n> Do you mean this should go in 1.7.12-rc1, or your master is for\n> 1.7.12 and this is for post 1.7.12 but you are pushing it out to\n> help other developers who are working on git-svn as a preview?\n\nI'm comfortable with this series so far, so going into 1.7.12 is fine.\nI pushed to a different branch because I didn't want to change the\ncommit on my previous pull request, sorry if I wasn't clear :x\n\n> I didn't look at these follow-up patches, but if you say they are\n> fit for the upcoming release, that is good enough for me.  Just\n> checking which way you want us to go.\n\nI looked at them a few times and things seem good.  I wouldn't\nmind an extra set of eyes, though :)\n"},{"id":"195990","messageId":"7vboj0y0ki.fsf@alter.siamese.dyndns.org","threadId":"31111","inReplyTo":"20120728041223.GB6129@dcvr.yhbt.net","subject":"Re: Extract remaining classes from git-svn","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-28T04:25:01Z","receivedAt":"2012-07-28T04:25:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Wong <normalperson@yhbt.net> writes:\n\n> Junio C Hamano <gitster@pobox.com> wrote:\n>> Eric Wong <normalperson@yhbt.net> writes:\n>> \n>> > \"Michael G. Schwern\" <schwern@pobox.com> wrote:\n>> >> This series of patches extracts the remaining classes from git-svn.  They're\n>> >> all simple extractions and functionally have no change.\n>> >\n>> > I've also pushed this to the \"extract-remaining\" series which\n>> > also includes everything that's currently in my master.\n>> \n>> Do you mean this should go in 1.7.12-rc1, or your master is for\n>> 1.7.12 and this is for post 1.7.12 but you are pushing it out to\n>> help other developers who are working on git-svn as a preview?\n>\n> I'm comfortable with this series so far, so going into 1.7.12 is fine.\n\nOK.  Thanks.\n"}]}