{"thread":{"id":"4459","subject":"[PATCH 3/5] git-svn: eol_cp corner-case fixes","startedAt":"2006-06-11T07:03:40Z","lastAt":"2006-06-11T07:03:45Z","messageCount":6,"participants":["Eric Wong"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"21578","messageId":"11500094252972-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":null,"subject":"[PATCH] git-svn: bug fixes (some resends)","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:40Z","receivedAt":"2006-06-11T07:03:40Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"\n[PATCH 1/5] git-svn: t0000: add -f flag to checkout\n[PATCH 2/5] git-svn: fix handling of filenames with embedded '@'\n\tThese two are resends, patch 2 only affects 1.1.0-pre.\n\n[PATCH 3/5] git-svn: eol_cp corner-case fixes\n\tKinda urgent (but only affects 1.1.0-pre)\n\n[PATCH 4/5] git-svn: restore original LC_ALL setting (or unset) for commit\n\tFor people that want to commit UTF-8 commit messages.\n\n[PATCH 5/5] git-svn: don't allow commit if svn tree is not current\n\tExtra sanity check, just in case.\n"},{"id":"21577","messageId":"11500094271080-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":"11500094252972-git-send-email-normalperson@yhbt.net","subject":"[PATCH 1/5] git-svn: t0000: add -f flag to checkout","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:41Z","receivedAt":"2006-06-11T07:03:41Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Some changes to the latest git.git made this test croak.  So\nwe'll always just force everything when using a new branch.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n contrib/git-svn/t/t0000-contrib-git-svn.sh |   10 +++++-----\n 1 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh\nindex 8b3a0d9..a07fbad 100644\n--- a/contrib/git-svn/t/t0000-contrib-git-svn.sh\n+++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh\n@@ -32,7 +32,7 @@ test_expect_success \\\n \n \n name='try a deep --rmdir with a commit'\n-git checkout -b mybranch remotes/git-svn\n+git checkout -f -b mybranch remotes/git-svn\n mv dir/a/b/c/d/e/file dir/file\n cp dir/file file\n git update-index --add --remove dir/a/b/c/d/e/file dir/file file\n@@ -58,7 +58,7 @@ test_expect_code 1 \"$name\" \\\n \n name='detect node change from directory to file #1'\n rm -rf dir $GIT_DIR/index\n-git checkout -b mybranch2 remotes/git-svn\n+git checkout -f -b mybranch2 remotes/git-svn\n mv bar/zzz zzz\n rm -rf bar\n mv zzz bar\n@@ -73,7 +73,7 @@ test_expect_code 1 \"$name\" \\\n \n name='detect node change from file to directory #2'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch3 remotes/git-svn\n+git checkout -f -b mybranch3 remotes/git-svn\n rm bar/zzz\n git-update-index --remove bar/zzz\n mkdir bar/zzz\n@@ -88,7 +88,7 @@ test_expect_code 1 \"$name\" \\\n \n name='detect node change from directory to file #2'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch4 remotes/git-svn\n+git checkout -f -b mybranch4 remotes/git-svn\n rm -rf dir\n git update-index --remove -- dir/file\n touch dir\n@@ -103,7 +103,7 @@ test_expect_code 1 \"$name\" \\\n \n name='remove executable bit from a file'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch5 remotes/git-svn\n+git checkout -f -b mybranch5 remotes/git-svn\n chmod -x exec.sh\n git update-index exec.sh\n git commit -m \"$name\"\n-- \n1.3.3.g2dc7b-dirty\n"},{"id":"21579","messageId":"11500094281515-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":"11500094271080-git-send-email-normalperson@yhbt.net","subject":"[PATCH 2/5] git-svn: fix handling of filenames with embedded '@'","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:42Z","receivedAt":"2006-06-11T07:03:42Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"svn has trouble parsing files with embedded '@' characters.  For\nexample,\n\n  svn propget svn:keywords foo@bar.c\n  svn: Syntax error parsing revision 'bar.c'\n\nI asked about this on #svn and the workaround suggested was to append\nan explicit revision specifier:\n\n  svn propget svn:keywords foo@bar.c@BASE\n\nThis patch appends '@BASE' to the filename in all calls to 'svn\npropget'.\n\nPatch originally by Seth Falcon <sethfalcon@gmail.com>\nSeth: signoff?\n\n[ew: Made to work with older svn that don't support peg revisions]\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n contrib/git-svn/git-svn.perl |   17 +++++++++++++----\n 1 files changed, 13 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex aac8779..7ed11ef 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -34,7 +34,7 @@ my $sha1_short = qr/[a-f\\d]{4,40}/;\n my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,\n \t$_find_copies_harder, $_l, $_version, $_upgrade, $_authors);\n my (@_branch_from, %tree_map, %users);\n-my $_svn_co_url_revs;\n+my ($_svn_co_url_revs, $_svn_pg_peg_revs);\n \n my %fc_opts = ( 'no-ignore-externals' => \\$_no_ignore_ext,\n \t\t'branch|b=s' => \\@_branch_from,\n@@ -336,7 +336,7 @@ sub show_ignore {\n \tmy %ign;\n \tFile::Find::find({wanted=>sub{if(lstat $_ && -d _ && -d \"$_/.svn\"){\n \t\ts#^\\./##;\n-\t\t@{$ign{$_}} = safe_qx(qw(svn propget svn:ignore),$_);\n+\t\t@{$ign{$_}} = svn_propget_base('svn:ignore', $_);\n \t\t}}, no_chdir=>1},'.');\n \n \tprint \"\\n# /\\n\";\n@@ -859,7 +859,7 @@ sub sys { system(@_) == 0 or croak $? }\n \n sub eol_cp {\n \tmy ($from, $to) = @_;\n-\tmy $es = safe_qx(qw/svn propget svn:eol-style/, $to);\n+\tmy $es = svn_propget_base('svn:eol-style', $to);\n \topen my $rfd, '<', $from or croak $!;\n \tbinmode $rfd or croak $!;\n \topen my $wfd, '>', $to or croak $!;\n@@ -897,7 +897,7 @@ sub do_update_index {\n \twhile (my $x = <$p>) {\n \t\tchomp $x;\n \t\tif (!$no_text_base && lstat $x && ! -l _ &&\n-\t\t\t\tsafe_qx(qw/svn propget svn:keywords/,$x)) {\n+\t\t\t\tsvn_propget_base('svn:keywords', $x)) {\n \t\t\tmy $mode = -x _ ? 0755 : 0644;\n \t\t\tmy ($v,$d,$f) = File::Spec->splitpath($x);\n \t\t\tmy $tb = File::Spec->catfile($d, '.svn', 'tmp',\n@@ -1135,6 +1135,9 @@ sub svn_compat_check {\n \tif (grep /usage: checkout URL\\[\\@REV\\]/,@co_help) {\n \t\t$_svn_co_url_revs = 1;\n \t}\n+\tif (grep /\\[TARGET\\[\\@REV\\]\\.\\.\\.\\]/, `svn propget -h`) {\n+\t\t$_svn_pg_peg_revs = 1;\n+\t}\n \n \t# I really, really hope nobody hits this...\n \tunless (grep /stop-on-copy/, (safe_qx(qw(svn log -h)))) {\n@@ -1214,6 +1217,12 @@ sub load_authors {\n \tclose $authors or croak $!;\n }\n \n+sub svn_propget_base {\n+\tmy ($p, $f) = @_;\n+\t$f .= '@BASE' if $_svn_pg_peg_revs;\n+\treturn safe_qx(qw/svn propget/, $p, $f);\n+}\n+\n __END__\n \n Data structures:\n-- \n1.3.3.g2dc7b-dirty\n"},{"id":"21576","messageId":"11500094292561-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":"11500094281515-git-send-email-normalperson@yhbt.net","subject":"[PATCH 3/5] git-svn: eol_cp corner-case fixes","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:43Z","receivedAt":"2006-06-11T07:03:43Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"If we read the maximum size of our buffer into $buf, and the\nlast character is '\\015', there's a chance that the character is\n'\\012', which means our regex won't work correctly.  At the\nworst case, this could introduce an extra newline into the code.\nWe'll now read an extra character if we see '\\015' is the last\ncharacter in $buf.\n\nWe also forgot to recalculate the length of $buf after doing the\nnewline substitution, causing some files to appeare truncated.\nWe'll do that now and force byte semantics in length() for good\nmeasure.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n contrib/git-svn/git-svn.perl |   15 +++++++++++----\n 1 files changed, 11 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex 7ed11ef..8d2e7f7 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -866,19 +866,26 @@ sub eol_cp {\n \tbinmode $wfd or croak $!;\n \n \tmy $eol = $EOL{$es} or undef;\n-\tif ($eol) {\n-\t\tprint  \"$eol: $from => $to\\n\";\n-\t}\n \tmy $buf;\n+\tuse bytes;\n \twhile (1) {\n \t\tmy ($r, $w, $t);\n \t\tdefined($r = sysread($rfd, $buf, 4096)) or croak $!;\n \t\treturn unless $r;\n-\t\t$buf =~ s/(?:\\015|\\012|\\015\\012)/$eol/gs if $eol;\n+\t\tif ($eol) {\n+\t\t\tif ($buf =~ /\\015$/) {\n+\t\t\t\tmy $c;\n+\t\t\t\tdefined($r = sysread($rfd,$c,1)) or croak $!;\n+\t\t\t\t$buf .= $c if $r > 0;\n+\t\t\t}\n+\t\t\t$buf =~ s/(?:\\015\\012|\\015|\\012)/$eol/gs;\n+\t\t\t$r = length($buf);\n+\t\t}\n \t\tfor ($w = 0; $w < $r; $w += $t) {\n \t\t\t$t = syswrite($wfd, $buf, $r - $w, $w) or croak $!;\n \t\t}\n \t}\n+\tno bytes;\n }\n \n sub do_update_index {\n-- \n1.3.3.g2dc7b-dirty\n"},{"id":"21581","messageId":"11500094313384-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":"11500094292561-git-send-email-normalperson@yhbt.net","subject":"[PATCH 4/5] git-svn: restore original LC_ALL setting (or unset) for commit","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:44Z","receivedAt":"2006-06-11T07:03:44Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"svn forces UTF-8 for commit messages, and with LC_ALL set to 'C'\nit is unable to determine encoding of the git commit message.\n\nNow we'll just assume the user has set LC_* correctly for\nthe commit message they're using.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n contrib/git-svn/git-svn.perl |   34 +++++++++++++++++++++++-----------\n 1 files changed, 23 insertions(+), 11 deletions(-)\n\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex 8d2e7f7..8bc3d69 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -14,6 +14,7 @@ use Cwd qw/abs_path/;\n $GIT_DIR = abs_path($ENV{GIT_DIR} || '.git');\n $ENV{GIT_DIR} = $GIT_DIR;\n \n+my $LC_ALL = $ENV{LC_ALL};\n # make sure the svn binary gives consistent output between locales and TZs:\n $ENV{TZ} = 'UTC';\n $ENV{LC_ALL} = 'C';\n@@ -704,23 +705,34 @@ sub svn_commit_tree {\n \tmy ($oneline) = ($log_msg{msg} =~ /([^\\n\\r]+)/);\n \tprint \"Committing $commit: $oneline\\n\";\n \n+\tif (defined $LC_ALL) {\n+\t\t$ENV{LC_ALL} = $LC_ALL;\n+\t} else {\n+\t\tdelete $ENV{LC_ALL};\n+\t}\n \tmy @ci_output = safe_qx(qw(svn commit -F),$commit_msg);\n-\tmy ($committed) = grep(/^Committed revision \\d+\\./,@ci_output);\n+\t$ENV{LC_ALL} = 'C';\n \tunlink $commit_msg;\n-\tdefined $committed or croak\n+\tmy ($committed) = ($ci_output[$#ci_output] =~ /(\\d+)/);\n+\tif (!defined $committed) {\n+\t\tmy $out = join(\"\\n\",@ci_output);\n+\t\tprint STDERR \"W: Trouble parsing \\`svn commit' output:\\n\\n\",\n+\t\t\t\t$out, \"\\n\\nAssuming English locale...\";\n+\t\t($committed) = ($out =~ /^Committed revision \\d+\\./sm);\n+\t\tdefined $committed or die \" FAILED!\\n\",\n \t\t\t\"Commit output failed to parse committed revision!\\n\",\n-\t\t\tjoin(\"\\n\",@ci_output),\"\\n\";\n-\tmy ($rev_committed) = ($committed =~ /^Committed revision (\\d+)\\./);\n+\t\tprint STDERR \" OK\\n\";\n+\t}\n \n \tmy @svn_up = qw(svn up);\n \tpush @svn_up, '--ignore-externals' unless $_no_ignore_ext;\n-\tif ($rev_committed == ($svn_rev + 1)) {\n-\t\tpush @svn_up, \"-r$rev_committed\";\n+\tif ($committed == ($svn_rev + 1)) {\n+\t\tpush @svn_up, \"-r$committed\";\n \t\tsys(@svn_up);\n \t\tmy $info = svn_info('.');\n \t\tmy $date = $info->{'Last Changed Date'} or die \"Missing date\\n\";\n-\t\tif ($info->{'Last Changed Rev'} != $rev_committed) {\n-\t\t\tcroak \"$info->{'Last Changed Rev'} != $rev_committed\\n\"\n+\t\tif ($info->{'Last Changed Rev'} != $committed) {\n+\t\t\tcroak \"$info->{'Last Changed Rev'} != $committed\\n\"\n \t\t}\n \t\tmy ($Y,$m,$d,$H,$M,$S,$tz) = ($date =~\n \t\t\t\t\t/(\\d{4})\\-(\\d\\d)\\-(\\d\\d)\\s\n@@ -728,16 +740,16 @@ sub svn_commit_tree {\n \t\t\t\t\t or croak \"Failed to parse date: $date\\n\";\n \t\t$log_msg{date} = \"$tz $Y-$m-$d $H:$M:$S\";\n \t\t$log_msg{author} = $info->{'Last Changed Author'};\n-\t\t$log_msg{revision} = $rev_committed;\n+\t\t$log_msg{revision} = $committed;\n \t\t$log_msg{msg} .= \"\\n\";\n \t\tmy $parent = file_to_s(\"$REV_DIR/$svn_rev\");\n \t\tgit_commit(\\%log_msg, $parent, $commit);\n-\t\treturn $rev_committed;\n+\t\treturn $committed;\n \t}\n \t# resync immediately\n \tpush @svn_up, \"-r$svn_rev\";\n \tsys(@svn_up);\n-\treturn fetch(\"$rev_committed=$commit\")->{revision};\n+\treturn fetch(\"$committed=$commit\")->{revision};\n }\n \n # read the entire log into a temporary file (which is removed ASAP)\n-- \n1.3.3.g2dc7b-dirty\n"},{"id":"21580","messageId":"1150009432591-git-send-email-normalperson@yhbt.net","threadId":"4459","inReplyTo":"11500094313384-git-send-email-normalperson@yhbt.net","subject":"[PATCH 5/5] git-svn: don't allow commit if svn tree is not current","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-06-11T07:03:45Z","receivedAt":"2006-06-11T07:03:45Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"If new revisions are fetched, that implies we haven't merged,\nacked, or nacked them yet, and attempting to write the tree\nwe're committing means we'd silently clobber the newly fetched\nchanges.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n contrib/git-svn/git-svn.perl |   11 +++++++++--\n 1 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex 8bc3d69..72129de 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -309,9 +309,16 @@ sub commit {\n \t}\n \tchomp @revs;\n \n-\tfetch();\n-\tchdir $SVN_WC or croak $!;\n+\tchdir $SVN_WC or croak \"Unable to chdir $SVN_WC: $!\\n\";\n \tmy $info = svn_info('.');\n+\tmy $fetched = fetch();\n+\tif ($info->{Revision} != $fetched->{revision}) {\n+\t\tprint STDERR \"There are new revisions that were fetched \",\n+\t\t\t\t\"and need to be merged (or acknowledged) \",\n+\t\t\t\t\"before committing.\\n\";\n+\t\texit 1;\n+\t}\n+\t$info = svn_info('.');\n \tread_uuid($info);\n \tmy $svn_current_rev =  $info->{'Last Changed Rev'};\n \tforeach my $c (@revs) {\n-- \n1.3.3.g2dc7b-dirty\n"}]}