{"thread":{"id":"6142","subject":"[PATCH 1/4] git-svn: remove non-delta fetch code paths","startedAt":"2006-12-28T09:16:19Z","lastAt":"2006-12-28T09:16:22Z","messageCount":4,"participants":["Eric Wong"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"30428","messageId":"11672973823960-git-send-email-normalperson@yhbt.net","threadId":"6142","inReplyTo":null,"subject":"[PATCH 1/4] git-svn: remove non-delta fetch code paths","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-28T09:16:19Z","receivedAt":"2006-12-28T09:16:19Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"We have less code to worry about now.  As a bonus, --revision\ncan be used to reliably skip parts of history whenever fetch is\nrun, not just the first time.  I'm not sure why anybody would\nwant to skip history in the middle, however...\n\nFor people (nearly everyone at the moment) without the\ndo_switch() function in their Perl SVN library, the entire tree\nmust be refetched if --follow-parent is used and a parent is\nfound.  Future versions of SVN will have a working do_switch()\nfunction accessible via Perl.\n\nAccessing repositories on the local machine (especially file://\nones) is also slightly slower as a result; but I suspect most\ngit-svn users will be using it to access remote repositories.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-svn.perl |  194 ++++++----------------------------------------------------\n t/Makefile   |    3 +-\n 2 files changed, 21 insertions(+), 176 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex c2cdceb..0ef13b2 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -69,7 +69,7 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,\n \t$_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,\n \t$_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m,\n \t$_merge, $_strategy, $_dry_run, $_ignore_nodate, $_non_recursive,\n-\t$_username, $_config_dir, $_no_auth_cache, $_xfer_delta,\n+\t$_username, $_config_dir, $_no_auth_cache,\n \t$_pager, $_color);\n my (@_branch_from, %tree_map, %users, %rusers, %equiv);\n my ($_svn_can_do_switch);\n@@ -2044,13 +2044,6 @@ sub libsvn_connect {\n \t                      config => $config,\n \t                      pool => SVN::Pool->new,\n \t                      auth_provider_callbacks => $callbacks);\n-\n-\tmy $df = $ENV{GIT_SVN_DELTA_FETCH};\n-\tif (defined $df) {\n-\t\t$_xfer_delta = $df;\n-\t} else {\n-\t\t$_xfer_delta = ($url =~ m#^file://#) ? undef : 1;\n-\t}\n \t$ra->{svn_path} = $url;\n \t$ra->{repos_root} = $ra->get_repos_root;\n \t$ra->{svn_path} =~ s#^\\Q$ra->{repos_root}\\E/*##;\n@@ -2082,49 +2075,6 @@ sub libsvn_dup_ra {\n \t             auth auth_provider_callbacks repos_root svn_path/);\n }\n \n-sub libsvn_get_file {\n-\tmy ($gui, $f, $rev, $chg, $untracked) = @_;\n-\t$f =~ s#^/##;\n-\tprint \"\\t$chg\\t$f\\n\" unless $_q;\n-\n-\tmy ($hash, $pid, $in, $out);\n-\tmy $pool = SVN::Pool->new;\n-\tdefined($pid = open3($in, $out, '>&STDERR',\n-\t\t\t\tqw/git-hash-object -w --stdin/)) or croak $!;\n-\t# redirect STDOUT for SVN 1.1.x compatibility\n-\topen my $stdout, '>&', \\*STDOUT or croak $!;\n-\topen STDOUT, '>&', $in or croak $!;\n-\tmy ($r, $props) = $SVN->get_file($f, $rev, \\*STDOUT, $pool);\n-\t$in->flush == 0 or croak $!;\n-\topen STDOUT, '>&', $stdout or croak $!;\n-\tclose $in or croak $!;\n-\tclose $stdout or croak $!;\n-\t$pool->clear;\n-\tchomp($hash = do { local $/; <$out> });\n-\tclose $out or croak $!;\n-\twaitpid $pid, 0;\n-\t$hash =~ /^$sha1$/o or die \"not a sha1: $hash\\n\";\n-\n-\tmy $mode = exists $props->{'svn:executable'} ? '100755' : '100644';\n-\tif (exists $props->{'svn:special'}) {\n-\t\t$mode = '120000';\n-\t\tmy $link = `git-cat-file blob $hash`; # no chomping symlinks\n-\t\t$link =~ s/^link // or die \"svn:special file with contents: <\",\n-\t\t\t\t\t\t$link, \"> is not understood\\n\";\n-\t\tdefined($pid = open3($in, $out, '>&STDERR',\n-\t\t\t\tqw/git-hash-object -w --stdin/)) or croak $!;\n-\t\tprint $in $link;\n-\t\t$in->flush == 0 or croak $!;\n-\t\tclose $in or croak $!;\n-\t\tchomp($hash = do { local $/; <$out> });\n-\t\tclose $out or croak $!;\n-\t\twaitpid $pid, 0;\n-\t\t$hash =~ /^$sha1$/o or die \"not a sha1: $hash\\n\";\n-\t}\n-\t%{$untracked->{file_prop}->{$f}} = %$props;\n-\tprint $gui $mode,' ',$hash,\"\\t\",$f,\"\\0\" or croak $!;\n-}\n-\n sub uri_encode {\n \tmy ($f) = @_;\n \t$f =~ s#([^a-zA-Z0-9\\*!\\:_\\./\\-])#uc sprintf(\"%%%02x\",ord($1))#eg;\n@@ -2232,10 +2182,6 @@ sub process_rm {\n }\n \n sub libsvn_fetch {\n-\t$_xfer_delta ? libsvn_fetch_delta(@_) : libsvn_fetch_full(@_);\n-}\n-\n-sub libsvn_fetch_delta {\n \tmy ($last_commit, $paths, $rev, $author, $date, $msg) = @_;\n \tmy $pool = SVN::Pool->new;\n \tmy $ed = SVN::Git::Fetcher->new({ c => $last_commit, q => $_q });\n@@ -2251,66 +2197,6 @@ sub libsvn_fetch_delta {\n \tlibsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ed);\n }\n \n-sub libsvn_fetch_full {\n-\tmy ($last_commit, $paths, $rev, $author, $date, $msg) = @_;\n-\tmy ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);\n-\tmy %amr;\n-\tmy $ut = { empty => {}, dir_prop => {}, file_prop => {} };\n-\tmy $p = $SVN->{svn_path};\n-\tforeach my $f (keys %$paths) {\n-\t\tmy $m = $paths->{$f}->action();\n-\t\tif (length $p) {\n-\t\t\t$f =~ s#^/\\Q$p\\E/##;\n-\t\t\tnext if $f =~ m#^/#;\n-\t\t} else {\n-\t\t\t$f =~ s#^/##;\n-\t\t}\n-\t\tif ($m =~ /^[DR]$/) {\n-\t\t\tmy $t = process_rm($gui, $last_commit, $f, $_q);\n-\t\t\tif ($m eq 'D') {\n-\t\t\t\t$ut->{empty}->{$f} = 0 if $t == $SVN::Node::dir;\n-\t\t\t\tnext;\n-\t\t\t}\n-\t\t\t# 'R' can be file replacements, too, right?\n-\t\t}\n-\t\tmy $pool = SVN::Pool->new;\n-\t\tmy $t = $SVN->check_path($f, $rev, $pool);\n-\t\tif ($t == $SVN::Node::file) {\n-\t\t\tif ($m =~ /^[AMR]$/) {\n-\t\t\t\t$amr{$f} = $m;\n-\t\t\t} else {\n-\t\t\t\tdie \"Unrecognized action: $m, ($f r$rev)\\n\";\n-\t\t\t}\n-\t\t} elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) {\n-\t\t\tmy @traversed = ();\n-\t\t\tlibsvn_traverse($gui, '', $f, $rev, \\@traversed, $ut);\n-\t\t\tif (@traversed) {\n-\t\t\t\tforeach (@traversed) {\n-\t\t\t\t\t$amr{$_} = $m;\n-\t\t\t\t}\n-\t\t\t} else {\n-\t\t\t\tmy ($dir, $file) = ($f =~ m#^(.*?)/?([^/]+)$#);\n-\t\t\t\tdelete $ut->{empty}->{$dir};\n-\t\t\t\t$ut->{empty}->{$f} = 1;\n-\t\t\t}\n-\t\t}\n-\t\t$pool->clear;\n-\t}\n-\tforeach (keys %amr) {\n-\t\tlibsvn_get_file($gui, $_, $rev, $amr{$_}, $ut);\n-\t\tmy ($d) = ($_ =~ m#^(.*?)/?(?:[^/]+)$#);\n-\t\tdelete $ut->{empty}->{$d};\n-\t}\n-\tunless (exists $ut->{dir_prop}->{''}) {\n-\t\tmy $pool = SVN::Pool->new;\n-\t\tmy (undef, undef, $props) = $SVN->get_dir('', $rev, $pool);\n-\t\t%{$ut->{dir_prop}->{''}} = %$props;\n-\t\t$pool->clear;\n-\t}\n-\tcommand_close_pipe($gui, $ctx);\n-\tlibsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ut);\n-}\n-\n sub svn_grab_base_rev {\n \tmy $c = eval { command_oneline([qw/rev-parse --verify/,\n \t                                \"refs/remotes/$GIT_SVN^0\"],\n@@ -2362,41 +2248,6 @@ sub libsvn_parse_revision {\n \t\t\"Try using the command-line svn client instead\\n\";\n }\n \n-sub libsvn_traverse {\n-\tmy ($gui, $pfx, $path, $rev, $files, $untracked) = @_;\n-\tmy $cwd = length $pfx ? \"$pfx/$path\" : $path;\n-\tmy $pool = SVN::Pool->new;\n-\t$cwd =~ s#^\\Q$SVN->{svn_path}\\E##;\n-\tmy $nr = 0;\n-\tmy ($dirent, $r, $props) = $SVN->get_dir($cwd, $rev, $pool);\n-\t%{$untracked->{dir_prop}->{$cwd}} = %$props;\n-\tforeach my $d (keys %$dirent) {\n-\t\tmy $t = $dirent->{$d}->kind;\n-\t\tif ($t == $SVN::Node::dir) {\n-\t\t\tmy $i = libsvn_traverse($gui, $cwd, $d, $rev,\n-\t\t\t                        $files, $untracked);\n-\t\t\tif ($i) {\n-\t\t\t\t$nr += $i;\n-\t\t\t} else {\n-\t\t\t\t$untracked->{empty}->{\"$cwd/$d\"} = 1;\n-\t\t\t}\n-\t\t} elsif ($t == $SVN::Node::file) {\n-\t\t\t$nr++;\n-\t\t\tmy $file = \"$cwd/$d\";\n-\t\t\tif (defined $files) {\n-\t\t\t\tpush @$files, $file;\n-\t\t\t} else {\n-\t\t\t\tlibsvn_get_file($gui, $file, $rev, 'A',\n-\t\t\t\t                $untracked);\n-\t\t\t\tmy ($dir) = ($file =~ m#^(.*?)/?(?:[^/]+)$#);\n-\t\t\t\tdelete $untracked->{empty}->{$dir};\n-\t\t\t}\n-\t\t}\n-\t}\n-\t$pool->clear;\n-\t$nr;\n-}\n-\n sub libsvn_traverse_ignore {\n \tmy ($fh, $path, $r) = @_;\n \t$path =~ s#^/+##g;\n@@ -2488,8 +2339,8 @@ sub libsvn_find_parent_branch {\n \t\tprint STDERR \"Found branch parent: ($GIT_SVN) $parent\\n\";\n \t\tcommand_noisy('read-tree', $parent);\n \t\tunless (libsvn_can_do_switch()) {\n-\t\t\treturn libsvn_fetch_full($parent, $paths, $rev,\n-\t\t\t\t\t\t$author, $date, $msg);\n+\t\t\treturn _libsvn_new_tree($paths, $rev, $author, $date,\n+\t\t\t                        $msg, [$parent]);\n \t\t}\n \t\t# do_switch works with svn/trunk >= r22312, but that is not\n \t\t# included with SVN 1.4.2 (the latest version at the moment),\n@@ -2514,7 +2365,7 @@ sub libsvn_find_parent_branch {\n \n sub libsvn_get_log {\n \tmy ($ra, @args) = @_;\n-\t$args[4]-- if $args[4] && $_xfer_delta && ! $_follow_parent;\n+\t$args[4]-- if $args[4] && ! $_follow_parent;\n \tif ($SVN::Core::VERSION le '1.2.0') {\n \t\tsplice(@args, 3, 1);\n \t}\n@@ -2525,28 +2376,23 @@ sub libsvn_new_tree {\n \tif (my $log_entry = libsvn_find_parent_branch(@_)) {\n \t\treturn $log_entry;\n \t}\n-\tmy ($paths, $rev, $author, $date, $msg) = @_;\n-\tmy $ut;\n-\tif ($_xfer_delta) {\n-\t\tmy $pool = SVN::Pool->new;\n-\t\tmy $ed = SVN::Git::Fetcher->new({q => $_q});\n-\t\tmy $reporter = $SVN->do_update($rev, '', 1, $ed, $pool);\n-\t\tmy @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();\n-\t\t$reporter->set_path('', $rev, 1, @lock, $pool);\n-\t\t$reporter->finish_report($pool);\n-\t\t$pool->clear;\n-\t\tunless ($ed->{git_commit_ok}) {\n-\t\t\tdie \"SVN connection failed somewhere...\\n\";\n-\t\t}\n-\t\t$ut = $ed;\n-\t} else {\n-\t\t$ut = { empty => {}, dir_prop => {}, file_prop => {} };\n-\t        my ($gui, $ctx) = command_input_pipe(qw/update-index\n-\t                                             -z --index-info/);\n-\t\tlibsvn_traverse($gui, '', $SVN->{svn_path}, $rev, undef, $ut);\n-\t\tcommand_close_pipe($gui, $ctx);\n+\tmy ($paths, $rev, $author, $date, $msg) = @_; # $pool is last\n+\t_libsvn_new_tree($paths, $rev, $author, $date, $msg, []);\n+}\n+\n+sub _libsvn_new_tree {\n+\tmy ($paths, $rev, $author, $date, $msg, $parents) = @_;\n+\tmy $pool = SVN::Pool->new;\n+\tmy $ed = SVN::Git::Fetcher->new({q => $_q});\n+\tmy $reporter = $SVN->do_update($rev, '', 1, $ed, $pool);\n+\tmy @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();\n+\t$reporter->set_path('', $rev, 1, @lock, $pool);\n+\t$reporter->finish_report($pool);\n+\t$pool->clear;\n+\tunless ($ed->{git_commit_ok}) {\n+\t\tdie \"SVN connection failed somewhere...\\n\";\n \t}\n-\tlibsvn_log_entry($rev, $author, $date, $msg, [], $ut);\n+\tlibsvn_log_entry($rev, $author, $date, $msg, $parents, $ed);\n }\n \n sub find_graft_path_commit {\ndiff --git a/t/Makefile b/t/Makefile\nindex 250a190..19e3850 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -23,8 +23,7 @@ clean:\n \n # we can test NO_OPTIMIZE_COMMITS independently of LC_ALL\n full-svn-test:\n-\t$(MAKE) $(TSVN) GIT_SVN_DELTA_FETCH=1 \\\n-\t\t\t\tGIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C\n+\t$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C\n \t$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=0 LC_ALL=en_US.UTF-8\n \n .PHONY: $(T) clean\n-- \n1.4.4.3.gd4ada\n"},{"id":"30429","messageId":"11672973831737-git-send-email-normalperson@yhbt.net","threadId":"6142","inReplyTo":"11672973823960-git-send-email-normalperson@yhbt.net","subject":"[PATCH 2/4] git-svn: print out the SVN library version in --version, too","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-28T09:16:20Z","receivedAt":"2006-12-28T09:16:20Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"This could be useful in finding new problems and helping users\ndebug.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-svn.perl |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 0ef13b2..a772ce8 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -216,7 +216,7 @@ information.\n }\n \n sub version {\n-\tprint \"git-svn version $VERSION\\n\";\n+\tprint \"git-svn version $VERSION (svn $SVN::Core::VERSION)\\n\";\n \texit 0;\n }\n \n-- \n1.4.4.3.gd4ada\n"},{"id":"30431","messageId":"1167297385162-git-send-email-normalperson@yhbt.net","threadId":"6142","inReplyTo":"11672973823960-git-send-email-normalperson@yhbt.net","subject":"[PATCH 3/4] git-svn: verify_ref() should actually --verify","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-28T09:16:21Z","receivedAt":"2006-12-28T09:16:21Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Not sure how I missed this the first time around...\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-svn.perl |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex a772ce8..74a3424 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -1098,7 +1098,8 @@ sub read_uuid {\n \n sub verify_ref {\n \tmy ($ref) = @_;\n-\teval { command_oneline([ 'rev-parse', $ref ], { STDERR => 0 }) };\n+\teval { command_oneline([ 'rev-parse', '--verify', $ref ],\n+\t                       { STDERR => 0 }); };\n }\n \n sub repo_path_split {\n-- \n1.4.4.3.gd4ada\n"},{"id":"30430","messageId":"11672973863687-git-send-email-normalperson@yhbt.net","threadId":"6142","inReplyTo":"11672973823960-git-send-email-normalperson@yhbt.net","subject":"[PATCH 4/4] git-svn: sort multi-init output","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-28T09:16:22Z","receivedAt":"2006-12-28T09:16:22Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"This looks a bit more pleasant for users.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-svn.perl |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 74a3424..b28c5bb 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -2481,7 +2481,7 @@ sub libsvn_ls_fullurl {\n \tmy $pool = SVN::Pool->new;\n \tmy $r = defined $_revision ? $_revision : $ra->get_latest_revnum;\n \tmy ($dirent, undef, undef) = $ra->get_dir('', $r, $pool);\n-\tforeach my $d (keys %$dirent) {\n+\tforeach my $d (sort keys %$dirent) {\n \t\tif ($dirent->{$d}->kind == $SVN::Node::dir) {\n \t\t\tpush @ret, \"$d/\"; # add '/' for compat with cli svn\n \t\t}\n-- \n1.4.4.3.gd4ada\n"}]}