{"thread":{"id":"24502","subject":"[PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","startedAt":"2010-07-25T02:31:14Z","lastAt":"2010-07-26T19:09:45Z","messageCount":9,"participants":["Jonathan Nieder","Eric Wong","Jens Seidel"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"146240","messageId":"20100725023114.GB18606@burratino","threadId":"24502","inReplyTo":"20100427112656.GB16323@merkur.sol.de","subject":"[PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T02:31:14Z","receivedAt":"2010-07-25T02:31:14Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Jens Seidel <jensseidel@users.sf.net>\n\nTweak \"git svn log\" output to more closely match what svn produces.\nIn particular, if Locale::gettext is available, use that to produce\nlocalized output using svn’s translations.\n\nSo now instead of \n\n git:\n r2105 | viktor | 2010-03-19 13:40:54 +0100 (Fr, 19 Mär 2010) | 2 lines\n \n svn:\n r2105 | viktor | 2010-03-19 13:40:54 +0100 (Fr, 19. Mär 2010) | 1 Zeile\n\nwe get the much closer\n\n git:\n r2105 | viktor | 2010-03-19 13:40:54 +0100 (Fr, 19. Mär 2010) | 2 Zeilen\n \n svn:\n r2105 | viktor | 2010-03-19 13:40:54 +0100 (Fr, 19. Mär 2010) | 1 Zeile\n\nand a script for munging to compare logs would only have to fuzz\nout the extra blank lines in git svn’s commit log.\n\n[jn: made Locale::gettext dependency optional; added a test script]\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nJens Seidel wrote at http://bugs.debian.org/578915:\n>> Jens Seidel wrote:\n\n> Ah, git svn ignores any locale, this explains the problem.\n>\n>>> The dot stands for an ordinal number (e.g. \"19.\" == \"19th\").\n>>> Second: \"line(s)\" is not translated. I can workaround by starting git/svn in an\n>>> English locale ...\n>\n> I tried to fix both.\n>\n>>> Third: the git log often contains an addional empty line.\n>\n> This remains open. Probably that can be solved by setting a git config\n> option and resyncing all git svn history from git.\n\nSorry to leave this hanging for so long.  I think it is an improvement\nas is, but I have not tested in the following scenarios:\n\n - Locale::gettext not available\n - subversion not translated\n - subversion translated but not to the current language\n\nAnd the extra blank line at the end of log messages remains unsolved.\n\nThoughts?\n\ndiff --git i/git-svn.perl w/git-svn.perl\nindex c416358..55dc50d 100755\n--- i/git-svn.perl\n+++ w/git-svn.perl\n@@ -45,6 +45,7 @@ sub _req_svn {\n \t}\n }\n my $can_compress = eval { require Compress::Zlib; 1};\n+my $can_localize = eval { require Locale::gettext; 1};\n push @Git::SVN::Ra::ISA, 'SVN::Ra';\n push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';\n push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';\n@@ -5535,7 +5536,14 @@ sub format_svn_date {\n \tmy $gm = timelocal(gmtime($t));\n \tmy $sign = qw( + + - )[ $t <=> $gm ];\n \tmy $gmoff = sprintf(\"%s%02d%02d\", $sign, (gmtime(abs($t - $gm)))[2,1]);\n-\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\", localtime($t));\n+\tmy $format;\n+\tif ($can_localize) {\n+\t\tmy $d = Locale::gettext->domain(\"subversion\");\n+\t\t$format = \"%Y-%m-%d %H:%M:%S $gmoff\" . $d->get(\" (%a, %d %b %Y)\");\n+\t} else {\n+\t\t$format = \"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\";\n+\t}\n+\treturn strftime($format, localtime($t));\n }\n \n sub parse_git_date {\n@@ -5631,9 +5639,16 @@ 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+\tprint \"$c->{a} | \", format_svn_date($c->{t_utc});\n \tmy $nr_line = 0;\n+\tmy $sing_fmt = \" | %d line\";\n+\tmy $plur_fmt = \" | %d lines\";\n \n+\tif ($can_localize) {\n+\t\tmy $d = Locale::gettext->domain(\"subversion\");\n+\t\t$sing_fmt = $d->nget(\" | %d line\", \" | %d lines\", 1);\n+\t\t$plur_fmt = $d->nget(\" | %d line\", \" | %d lines\", 10);\n+\t}\n \tif (my $l = $c->{l}) {\n \t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n \t\t                          && $l->[($#$l - 1)] eq \"\\n\") {\n@@ -5641,20 +5656,23 @@ sub show_commit_normal {\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\tprint sprintf($sing_fmt, 1), \"\\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\tprint sprintf($sing_fmt, $nr_line), \"\\n\";\n \t\t\t} else {\n-\t\t\t\t$nr_line .= ' lines';\n+\t\t\t\tprint sprintf($plur_fmt, $nr_line), \"\\n\";\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\tif ($nr_line == 1) {\n+\t\t\tprint sprintf($sing_fmt, $nr_line), \"\\n\";\n+\t\t} else {\n+\t\t\tprint sprintf($plur_fmt, $nr_line), \"\\n\";\n+\t\t}\n \t\tshow_commit_changed_paths($c);\n \t\tprint \"\\n\";\n \ndiff --git i/t/t9116-git-svn-log.sh w/t/t9116-git-svn-log.sh\nindex 0374a74..586f64b 100755\n--- i/t/t9116-git-svn-log.sh\n+++ w/t/t9116-git-svn-log.sh\n@@ -16,6 +16,7 @@ test_expect_success 'setup repository and import' '\n \t\tdone && \\\n \t\tsvn_cmd import -m test . \"$svnrepo\"\n \t\tcd .. &&\n+\tsvn_cmd checkout \"$svnrepo\"/branches/a checkout &&\n \tgit svn init \"$svnrepo\" -T trunk -b branches -t tags &&\n \tgit svn fetch &&\n \tgit reset --hard trunk &&\n@@ -36,7 +37,38 @@ test_expect_success 'setup repository and import' '\n \tgit commit -a -m spy &&\n \techo try >> README &&\n \tgit commit -a -m try &&\n-\tgit svn dcommit\n+\tgit svn dcommit &&\n+\t(\n+\t\tcd checkout &&\n+\t\tsvn_cmd update\n+\t) &&\n+\n+\tif test -n \"$ORIGINAL_LANG\" && test \"$ORIGINAL_LANG\" != C\n+\tthen\n+\t\ttest_set_prereq NONCLOCALE\n+\tfi\n+\t'\n+\n+test_expect_failure 'log matches svn log' '\n+\tgit reset --hard a &&\n+\t(\n+\t\tcd checkout &&\n+\t\tsvn_cmd log >../expected\n+\t) &&\n+\tgit svn log >actual &&\n+\ttest_cmp expected actual\n+\t'\n+\n+test_expect_failure NONCLOCALE 'log matches svn log, original locale' '\n+\t(\n+\t\tLC_ALL=$ORIGINAL_LANG &&\n+\t\t(\n+\t\t\tcd checkout &&\n+\t\t\tsvn_cmd log >../expected\n+\t\t) &&\n+\t\tgit svn log >actual\n+\t) &&\n+\ttest_cmp expected actual\n \t'\n \n test_expect_success 'run log' \"\ndiff --git i/t/test-lib.sh w/t/test-lib.sh\nindex e5523dd..62aa48c 100644\n--- i/t/test-lib.sh\n+++ w/t/test-lib.sh\n@@ -34,6 +34,9 @@ esac\n # Keep the original TERM for say_color\n ORIGINAL_TERM=$TERM\n \n+# Keep the original locale for tests\n+ORIGINAL_LANG=$LANG\n+\n # For repeatability, reset the environment to known value.\n LANG=C\n LC_ALL=C\n-- \n"},{"id":"146246","messageId":"20100725081057.GA22373@dcvr.yhbt.net","threadId":"24502","inReplyTo":"20100725023114.GB18606@burratino","subject":"Re: [PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-07-25T08:10:57Z","receivedAt":"2010-07-25T08:10:57Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jonathan Nieder <jrnieder@gmail.com> wrote:\n> From: Jens Seidel <jensseidel@users.sf.net>\n> \n> Tweak \"git svn log\" output to more closely match what svn produces.\n> In particular, if Locale::gettext is available, use that to produce\n> localized output using svn’s translations.\n\n<snip>\n\n> [jn: made Locale::gettext dependency optional; added a test script]\n> \n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n> Jens Seidel wrote at http://bugs.debian.org/578915:\n> >> Jens Seidel wrote:\n> \n> > Ah, git svn ignores any locale, this explains the problem.\n> >\n> >>> The dot stands for an ordinal number (e.g. \"19.\" == \"19th\").\n> >>> Second: \"line(s)\" is not translated. I can workaround by starting git/svn in an\n> >>> English locale ...\n> >\n> > I tried to fix both.\n> >\n> >>> Third: the git log often contains an addional empty line.\n>\n> > This remains open. Probably that can be solved by setting a git config\n> > option and resyncing all git svn history from git.\n\nHi Jens, Jonathan,\n\nI just made an additional patch that should solve the problem\n(see my reply to this email).\n\n> Sorry to leave this hanging for so long.  I think it is an improvement\n> as is, but I have not tested in the following scenarios:\n> \n>  - Locale::gettext not available\n>  - subversion not translated\n>  - subversion translated but not to the current language\n> \n> And the extra blank line at the end of log messages remains unsolved.\n> \n> Thoughts?\n\nEverything looks reasonable to me.  gettext should just fall back to the\noriginal string when a translation is not available.\n\nI've squashed the following cleanup on top of Jens' original change:\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 55dc50d..5252722 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -5536,14 +5536,12 @@ sub format_svn_date {\n \tmy $gm = timelocal(gmtime($t));\n \tmy $sign = qw( + + - )[ $t <=> $gm ];\n \tmy $gmoff = sprintf(\"%s%02d%02d\", $sign, (gmtime(abs($t - $gm)))[2,1]);\n-\tmy $format;\n+\tmy $format = \" (%a, %d %b %Y)\";\n \tif ($can_localize) {\n \t\tmy $d = Locale::gettext->domain(\"subversion\");\n-\t\t$format = \"%Y-%m-%d %H:%M:%S $gmoff\" . $d->get(\" (%a, %d %b %Y)\");\n-\t} else {\n-\t\t$format = \"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\";\n+\t\t$format = $d->get($format);\n \t}\n-\treturn strftime($format, localtime($t));\n+\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff$format\", localtime($t));\n }\n \n sub parse_git_date {\n@@ -5646,8 +5644,8 @@ sub show_commit_normal {\n \n \tif ($can_localize) {\n \t\tmy $d = Locale::gettext->domain(\"subversion\");\n-\t\t$sing_fmt = $d->nget(\" | %d line\", \" | %d lines\", 1);\n-\t\t$plur_fmt = $d->nget(\" | %d line\", \" | %d lines\", 10);\n+\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n+\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n \t}\n \tif (my $l = $c->{l}) {\n \t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n-- \nEric Wong\n"},{"id":"146247","messageId":"20100725081344.GB22373@dcvr.yhbt.net","threadId":"24502","inReplyTo":"20100725081057.GA22373@dcvr.yhbt.net","subject":"[PATCH 2/1] git svn: remove extraneous newline from log output","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-07-25T08:13:44Z","receivedAt":"2010-07-25T08:13:44Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"This is to match the output of \"svn log\", which does not\nadd an extra newline before the next log entry.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n\nThe following are pushed to the master git svn repo at\ngit://git.bogomips.org/git-svn   Let me know if everything looks\nalright and I'll ask Junio to pull.\n\n\tEric Wong (1):\n\t      git svn: remove extraneous newline from log output\n\n\tJens Seidel (1):\n\t      git-svn: tweak log format to match \"svn log\" output\n\n git-svn.perl           |    3 +++\n t/t9116-git-svn-log.sh |    4 ++--\n 2 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 5252722..f9b7711 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -5743,6 +5743,9 @@ sub cmd_show_log {\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\tif (@{$c->{l}} && $c->{l}->[-1] eq \"\\n\") {\n+\t\t\t\tpop @{$c->{l}};\n+\t\t\t}\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}}, $_;\ndiff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh\nindex 4394fb2..586f64b 100755\n--- a/t/t9116-git-svn-log.sh\n+++ b/t/t9116-git-svn-log.sh\n@@ -49,7 +49,7 @@ test_expect_success 'setup repository and import' '\n \tfi\n \t'\n \n-test_expect_failure 'log matches svn log' '\n+test_expect_success 'log matches svn log' '\n \tgit reset --hard a &&\n \t(\n \t\tcd checkout &&\n@@ -59,7 +59,7 @@ test_expect_failure 'log matches svn log' '\n \ttest_cmp expected actual\n \t'\n \n-test_expect_failure NONCLOCALE 'log matches svn log, original locale' '\n+test_expect_success NONCLOCALE 'log matches svn log, original locale' '\n \t(\n \t\tLC_ALL=$ORIGINAL_LANG &&\n \t\t(\n-- \nEric Wong\n"},{"id":"146249","messageId":"20100725083708.GB22213@burratino","threadId":"24502","inReplyTo":"20100725081057.GA22373@dcvr.yhbt.net","subject":"Re: [PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T08:37:08Z","receivedAt":"2010-07-25T08:37:08Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Eric Wong wrote:\n\n> @@ -5646,8 +5644,8 @@ sub show_commit_normal {\n>  \n>  \tif ($can_localize) {\n>  \t\tmy $d = Locale::gettext->domain(\"subversion\");\n> -\t\t$sing_fmt = $d->nget(\" | %d line\", \" | %d lines\", 1);\n> -\t\t$plur_fmt = $d->nget(\" | %d line\", \" | %d lines\", 10);\n> +\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n> +\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n\nThis change gives me pause: wouldn’t it be a problem in\nnon-English locales, where $sing_fmt changes before it is\nused to set $plur_fmt?\n\nOf course there is no problem because the code is equivalent to\n\n\t\t$sing_fmt = $d->get($sing_fmt);\n\t\t$plur_fmt = $d->get($plur_fmt);\n\n(or at least Locale::gettext is advertised to work that way.)\n\ndiff --git i/git-svn.perl w/git-svn.perl\nindex 5252722..75e7165 100755\n--- i/git-svn.perl\n+++ w/git-svn.perl\n@@ -5644,8 +5644,8 @@ sub show_commit_normal {\n \n \tif ($can_localize) {\n \t\tmy $d = Locale::gettext->domain(\"subversion\");\n-\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n-\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n+\t\t$sing_fmt = $d->get($sing_fmt);\n+\t\t$plur_fmt = $d->get($plur_fmt);\n \t}\n \tif (my $l = $c->{l}) {\n \t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n-- \n"},{"id":"146250","messageId":"20100725084057.GA23621@dcvr.yhbt.net","threadId":"24502","inReplyTo":"20100725083708.GB22213@burratino","subject":"Re: [PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-07-25T08:40:57Z","receivedAt":"2010-07-25T08:40:57Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Eric Wong wrote:\n> \n> > @@ -5646,8 +5644,8 @@ sub show_commit_normal {\n> >  \n> >  \tif ($can_localize) {\n> >  \t\tmy $d = Locale::gettext->domain(\"subversion\");\n> > -\t\t$sing_fmt = $d->nget(\" | %d line\", \" | %d lines\", 1);\n> > -\t\t$plur_fmt = $d->nget(\" | %d line\", \" | %d lines\", 10);\n> > +\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n> > +\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n> \n> This change gives me pause: wouldn’t it be a problem in\n> non-English locales, where $sing_fmt changes before it is\n> used to set $plur_fmt?\n> \n> Of course there is no problem because the code is equivalent to\n> \n> \t\t$sing_fmt = $d->get($sing_fmt);\n> \t\t$plur_fmt = $d->get($plur_fmt);\n> \n> (or at least Locale::gettext is advertised to work that way.)\n> \n> diff --git i/git-svn.perl w/git-svn.perl\n> index 5252722..75e7165 100755\n> --- i/git-svn.perl\n> +++ w/git-svn.perl\n> @@ -5644,8 +5644,8 @@ sub show_commit_normal {\n>  \n>  \tif ($can_localize) {\n>  \t\tmy $d = Locale::gettext->domain(\"subversion\");\n> -\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n> -\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n> +\t\t$sing_fmt = $d->get($sing_fmt);\n> +\t\t$plur_fmt = $d->get($plur_fmt);\n>  \t}\n>  \tif (my $l = $c->{l}) {\n>  \t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n\nThanks Jonathan, that looks much better.  I'll squash that on top\nJens' first patch.\n\n-- \nEric Wong\n"},{"id":"146254","messageId":"20100725090943.GA1998@merkur.sol.de","threadId":"24502","inReplyTo":"20100725084057.GA23621@dcvr.yhbt.net","subject":"Re: [PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Jens Seidel","fromEmail":"jensseidel@users.sf.net","sentAt":"2010-07-25T09:09:46Z","receivedAt":"2010-07-25T09:09:46Z","isPatch":true,"sender":{"key":"jensseidel@users.sf.net","avatar":null},"body":"On Sun, Jul 25, 2010 at 08:40:57AM +0000, Eric Wong wrote:\n> Jonathan Nieder <jrnieder@gmail.com> wrote:\n> > diff --git i/git-svn.perl w/git-svn.perl\n> > index 5252722..75e7165 100755\n> > --- i/git-svn.perl\n> > +++ w/git-svn.perl\n> > @@ -5644,8 +5644,8 @@ sub show_commit_normal {\n> >  \n> >  \tif ($can_localize) {\n> >  \t\tmy $d = Locale::gettext->domain(\"subversion\");\n> > -\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n> > -\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n> > +\t\t$sing_fmt = $d->get($sing_fmt);\n> > +\t\t$plur_fmt = $d->get($plur_fmt);\n> >  \t}\n> >  \tif (my $l = $c->{l}) {\n> >  \t\twhile ($l->[$#$l] eq \"\\n\" && $#$l > 0\n> \n> Thanks Jonathan, that looks much better.  I'll squash that on top\n> Jens' first patch.\n\nNo, this is still wrong, we have to use $d->nget as some languages can have\nmultiple plural forms. Russian e.g. has two: one if the last digit ends with\n2-4 and a second one if it ends with 5-9. Exact rule:\n\"Plural-Forms:  nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 &&\nn%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\\n\"\n\nThat's why it's wrong to use $plur_fmt at all (and also \"10\" from above\nmakes no sense). Let's use:\n$d->nget(\" | %d line\", \" | %d lines\", $nr_line), $nr_line)\nwhere $nr_line is the variable.\n\nSorry for not providing a patch now but I need more time ... I suggest one\nof you try it again and I check it :-)\n\nJens\n"},{"id":"146305","messageId":"20100725173549.GA7930@merkur.sol.de","threadId":"24502","inReplyTo":"20100725081344.GB22373@dcvr.yhbt.net","subject":"Re: [PATCH 2/1] git svn: remove extraneous newline from log output","fromName":"Jens Seidel","fromEmail":"jensseidel@users.sf.net","sentAt":"2010-07-25T17:35:56Z","receivedAt":"2010-07-25T17:35:56Z","isPatch":true,"sender":{"key":"jensseidel@users.sf.net","avatar":null},"body":"Hi Eric,\n\nOn Sun, Jul 25, 2010 at 08:13:44AM +0000, Eric Wong wrote:\n> This is to match the output of \"svn log\", which does not\n> add an extra newline before the next log entry.\n\nthanks for the patch but it doesn't work in the general case.\n\nI attached a sample Subversion repository dump where the output of\ngit svn log and svn log still differs by empty lines.\n\nI also noticed the following error:\nCan't use an undefined value as an ARRAY reference at                                                                                            \n/usr/lib/git-core/git-svn line 5717, <$fh> line 53.\n\nI'm not sure whether I introduced this error once I patched\ngit-svn ...\nThe affected line is the second one in:\n           } elsif (/^${esc_color}    (git-svn-id:.+)$/o) {\n                        if (@{$c->{l}} && $c->{l}->[-1] eq \"\\n\") {\n                                pop @{$c->{l}};\n                        }\n(is -1 valid?)\n\nJens \n\n\n------------------------------------------------------------------------\nr5 | jens | 2010-07-25 19:08:18 +0200 (So, 25. Jul 2010) | 4 lines\n\n2 trailing newlines\n\n\n\n------------------------------------------------------------------------\nr4 | jens | 2010-07-25 19:07:42 +0200 (So, 25. Jul 2010) | 3 lines\n\ntrailing newline\n\n\n------------------------------------------------------------------------\nr3 | jens | 2010-07-25 19:06:58 +0200 (So, 25. Jul 2010) | 3 lines\n\none linebreak\nline 2\n\n------------------------------------------------------------------------\nr2 | jens | 2010-07-25 19:06:05 +0200 (So, 25. Jul 2010) | 1 line\n\nlinebreak\n------------------------------------------------------------------------\nr1 | jens | 2010-07-25 19:05:21 +0200 (So, 25. Jul 2010) | 1 line\n\n\n------------------------------------------------------------------------\n\n\n------------------------------------------------------------------------\nr5 | jens | 2010-07-25 19:08:18 +0200 (So, 25. Jul 2010) | 2 lines\n\n2 trailing newlines\n\n------------------------------------------------------------------------\nr4 | jens | 2010-07-25 19:07:42 +0200 (So, 25. Jul 2010) | 2 lines\n\ntrailing newline\n\n------------------------------------------------------------------------\nr3 | jens | 2010-07-25 19:06:58 +0200 (So, 25. Jul 2010) | 3 lines\n\none linebreak\nline 2\n\n------------------------------------------------------------------------\nr2 | jens | 2010-07-25 19:06:05 +0200 (So, 25. Jul 2010) | 1 line\n\nlinebreak\nCan't use an undefined value as an ARRAY reference at\n/usr/lib/git-core/git-svn line 5717, <$fh> line 53.\n\n\nSVN-fs-dump-format-version: 2\n\nUUID: 83f09cc9-4635-489b-9736-9fad07b44175\n\nRevision-number: 0\nProp-content-length: 56\nContent-length: 56\n\nK 8\nsvn:date\nV 27\n2010-07-25T17:03:46.899612Z\nPROPS-END\n\nRevision-number: 1\nProp-content-length: 98\nContent-length: 98\n\nK 7\nsvn:log\nV 0\n\nK 10\nsvn:author\nV 4\njens\nK 8\nsvn:date\nV 27\n2010-07-25T17:05:21.869208Z\nPROPS-END\n\nNode-path: file\nNode-kind: file\nNode-action: add\nProp-content-length: 10\nText-content-length: 0\nText-content-md5: d41d8cd98f00b204e9800998ecf8427e\nContent-length: 10\n\nPROPS-END\n\n\nRevision-number: 2\nProp-content-length: 107\nContent-length: 107\n\nK 7\nsvn:log\nV 9\nlinebreak\nK 10\nsvn:author\nV 4\njens\nK 8\nsvn:date\nV 27\n2010-07-25T17:06:05.643604Z\nPROPS-END\n\nNode-path: file\nNode-kind: file\nNode-action: change\nText-content-length: 13\nText-content-md5: dcf4e97bd1c01e863bf8989b23429f9c\nContent-length: 13\n\nno linebreak\n\n\nRevision-number: 3\nProp-content-length: 120\nContent-length: 120\n\nK 7\nsvn:log\nV 21\none linebreak\nline 2\n\nK 10\nsvn:author\nV 4\njens\nK 8\nsvn:date\nV 27\n2010-07-25T17:06:58.264468Z\nPROPS-END\n\nNode-path: file\nNode-kind: file\nNode-action: change\nText-content-length: 21\nText-content-md5: 4e70c8b04910e92f9cc7fbd6424352f0\nContent-length: 21\n\none linebreak\nline 2\n\n\nRevision-number: 4\nProp-content-length: 117\nContent-length: 117\n\nK 7\nsvn:log\nV 18\ntrailing newline\n\n\nK 10\nsvn:author\nV 4\njens\nK 8\nsvn:date\nV 27\n2010-07-25T17:07:42.901800Z\nPROPS-END\n\nNode-path: file\nNode-kind: file\nNode-action: change\nText-content-length: 19\nText-content-md5: b20aeff36821448c3bc3c85942bc1fc5\nContent-length: 19\n\ntrailing newline\n\n\n\n\nRevision-number: 5\nProp-content-length: 121\nContent-length: 121\n\nK 7\nsvn:log\nV 22\n2 trailing newlines\n\n\n\nK 10\nsvn:author\nV 4\njens\nK 8\nsvn:date\nV 27\n2010-07-25T17:08:18.343554Z\nPROPS-END\n\nNode-path: file\nNode-kind: file\nNode-action: change\nText-content-length: 23\nText-content-md5: e1314ce7619ef512653071d690dbd789\nContent-length: 23\n\n2 trailing newlines\n\n\n\n\n\n"},{"id":"146311","messageId":"20100725175237.GB7930@merkur.sol.de","threadId":"24502","inReplyTo":"20100725090943.GA1998@merkur.sol.de","subject":"Re: [PATCH/WIP] git-svn: tweak log format to match \"svn log\" output","fromName":"Jens Seidel","fromEmail":"jensseidel@users.sf.net","sentAt":"2010-07-25T17:52:39Z","receivedAt":"2010-07-25T17:52:39Z","isPatch":true,"sender":{"key":"jensseidel@users.sf.net","avatar":null},"body":"On Sun, Jul 25, 2010 at 11:09:46AM +0200, Jens Seidel wrote:\n> No, this is still wrong, we have to use $d->nget as some languages can have\n> multiple plural forms. Russian e.g. has two: one if the last digit ends with\n> 2-4 and a second one if it ends with 5-9. Exact rule:\n> \"Plural-Forms:  nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 &&\n> n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\\n\"\n> \n> That's why it's wrong to use $plur_fmt at all (and also \"10\" from above\n> makes no sense). Let's use:\n> $d->nget(\" | %d line\", \" | %d lines\", $nr_line), $nr_line)\n> where $nr_line is the variable.\n> \n> Sorry for not providing a patch now but I need more time ... I suggest one\n> of you try it again and I check it :-)\n\nHere is a new patch:\n\n(Please check the last stanza, Jonathan introduced $nr_line for the\noutput where 1 was used before. I reverted it.)\n\nSince the partial patches get difficult to handle I attached also the\ncombined patch which includes everything from this thread.\n\nAnd a further minor issue. The current locale for the test is extracted from\n$LANG. It's possible that this variable isn't set but another one such as\nLC_MESSAGES. So the test doesn't determine the locale but $LANG :-))\n\ncommit 239c97380df384162ebe8399754d072300d8b52f\nAuthor: Jens Seidel <jensseidel@users.sf.net>\nDate:   Sun Jul 25 18:35:28 2010 +0200\n\n    Proper use of plural forms\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex f9b7711..71c2c9a 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -5639,14 +5639,22 @@ sub show_commit_normal {\n \tprint \"$c->{c} | \" if $show_commit;\n \tprint \"$c->{a} | \", format_svn_date($c->{t_utc});\n \tmy $nr_line = 0;\n-\tmy $sing_fmt = \" | %d line\";\n-\tmy $plur_fmt = \" | %d lines\";\n \n-\tif ($can_localize) {\n-\t\tmy $d = Locale::gettext->domain(\"subversion\");\n-\t\t$sing_fmt = $d->nget($sing_fmt, $plur_fmt, 1);\n-\t\t$plur_fmt = $d->nget($sing_fmt, $plur_fmt, 10);\n-\t}\n+\t# returns \" | $1 lines\" properly translated\n+\tlocal *get_line_msg = sub {\n+\t\tmy $n = shift;\n+\t\tif ($can_localize) {\n+\t\t\tmy $d = Locale::gettext->domain(\"subversion\");\n+\t\t\treturn sprintf($d->nget(\" | %d line\", \" | %d lines\", $n), $n);\n+\t\t} else {\n+\t\t\tif ($n == 1) {\n+\t\t\t\treturn \" | 1 line\";\n+\t\t\t} else {\n+\t\t\t\treturn \" | \" . $n . \" lines\";\n+\t\t\t}\n+\t\t}\n+\t};\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@@ -5654,23 +5662,15 @@ sub show_commit_normal {\n \t\t}\n \t\t$nr_line = scalar @$l;\n \t\tif (!$nr_line) {\n-\t\t\tprint sprintf($sing_fmt, 1), \"\\n\\n\\n\";\n+\t\t\tprint get_line_msg(1), \"\\n\\n\\n\"; \n \t\t} else {\n-\t\t\tif ($nr_line == 1) {\n-\t\t\t\tprint sprintf($sing_fmt, $nr_line), \"\\n\";\n-\t\t\t} else {\n-\t\t\t\tprint sprintf($plur_fmt, $nr_line), \"\\n\";\n-\t\t\t}\n+\t\t\tprint get_line_msg($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\tif ($nr_line == 1) {\n-\t\t\tprint sprintf($sing_fmt, $nr_line), \"\\n\";\n-\t\t} else {\n-\t\t\tprint sprintf($plur_fmt, $nr_line), \"\\n\";\n-\t\t}\n+\t\tprint get_line_msg(1), \"\\n\";\n \t\tshow_commit_changed_paths($c);\n \t\tprint \"\\n\";\n \n\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex c416358..71c2c9a 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -45,6 +45,7 @@ sub _req_svn {\n \t}\n }\n my $can_compress = eval { require Compress::Zlib; 1};\n+my $can_localize = eval { require Locale::gettext; 1};\n push @Git::SVN::Ra::ISA, 'SVN::Ra';\n push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';\n push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';\n@@ -5535,7 +5536,12 @@ sub format_svn_date {\n \tmy $gm = timelocal(gmtime($t));\n \tmy $sign = qw( + + - )[ $t <=> $gm ];\n \tmy $gmoff = sprintf(\"%s%02d%02d\", $sign, (gmtime(abs($t - $gm)))[2,1]);\n-\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)\", localtime($t));\n+\tmy $format = \" (%a, %d %b %Y)\";\n+\tif ($can_localize) {\n+\t\tmy $d = Locale::gettext->domain(\"subversion\");\n+\t\t$format = $d->get($format);\n+\t}\n+\treturn strftime(\"%Y-%m-%d %H:%M:%S $gmoff$format\", localtime($t));\n }\n \n sub parse_git_date {\n@@ -5631,9 +5637,24 @@ 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+\tprint \"$c->{a} | \", format_svn_date($c->{t_utc});\n \tmy $nr_line = 0;\n \n+\t# returns \" | $1 lines\" properly translated\n+\tlocal *get_line_msg = sub {\n+\t\tmy $n = shift;\n+\t\tif ($can_localize) {\n+\t\t\tmy $d = Locale::gettext->domain(\"subversion\");\n+\t\t\treturn sprintf($d->nget(\" | %d line\", \" | %d lines\", $n), $n);\n+\t\t} else {\n+\t\t\tif ($n == 1) {\n+\t\t\t\treturn \" | 1 line\";\n+\t\t\t} else {\n+\t\t\t\treturn \" | \" . $n . \" lines\";\n+\t\t\t}\n+\t\t}\n+\t};\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@@ -5641,20 +5662,15 @@ sub show_commit_normal {\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\tprint get_line_msg(1), \"\\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\tprint get_line_msg($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\tprint get_line_msg(1), \"\\n\";\n \t\tshow_commit_changed_paths($c);\n \t\tprint \"\\n\";\n \n@@ -5727,6 +5743,9 @@ sub cmd_show_log {\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\tif (@{$c->{l}} && $c->{l}->[-1] eq \"\\n\") {\n+\t\t\t\tpop @{$c->{l}};\n+\t\t\t}\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}}, $_;\ndiff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh\nindex 0374a74..586f64b 100755\n--- a/t/t9116-git-svn-log.sh\n+++ b/t/t9116-git-svn-log.sh\n@@ -16,6 +16,7 @@ test_expect_success 'setup repository and import' '\n \t\tdone && \\\n \t\tsvn_cmd import -m test . \"$svnrepo\"\n \t\tcd .. &&\n+\tsvn_cmd checkout \"$svnrepo\"/branches/a checkout &&\n \tgit svn init \"$svnrepo\" -T trunk -b branches -t tags &&\n \tgit svn fetch &&\n \tgit reset --hard trunk &&\n@@ -36,7 +37,38 @@ test_expect_success 'setup repository and import' '\n \tgit commit -a -m spy &&\n \techo try >> README &&\n \tgit commit -a -m try &&\n-\tgit svn dcommit\n+\tgit svn dcommit &&\n+\t(\n+\t\tcd checkout &&\n+\t\tsvn_cmd update\n+\t) &&\n+\n+\tif test -n \"$ORIGINAL_LANG\" && test \"$ORIGINAL_LANG\" != C\n+\tthen\n+\t\ttest_set_prereq NONCLOCALE\n+\tfi\n+\t'\n+\n+test_expect_success 'log matches svn log' '\n+\tgit reset --hard a &&\n+\t(\n+\t\tcd checkout &&\n+\t\tsvn_cmd log >../expected\n+\t) &&\n+\tgit svn log >actual &&\n+\ttest_cmp expected actual\n+\t'\n+\n+test_expect_success NONCLOCALE 'log matches svn log, original locale' '\n+\t(\n+\t\tLC_ALL=$ORIGINAL_LANG &&\n+\t\t(\n+\t\t\tcd checkout &&\n+\t\t\tsvn_cmd log >../expected\n+\t\t) &&\n+\t\tgit svn log >actual\n+\t) &&\n+\ttest_cmp expected actual\n \t'\n \n test_expect_success 'run log' \"\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex e5523dd..62aa48c 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -34,6 +34,9 @@ esac\n # Keep the original TERM for say_color\n ORIGINAL_TERM=$TERM\n \n+# Keep the original locale for tests\n+ORIGINAL_LANG=$LANG\n+\n # For repeatability, reset the environment to known value.\n LANG=C\n LC_ALL=C\n"},{"id":"146422","messageId":"20100726190945.GA2727@dcvr.yhbt.net","threadId":"24502","inReplyTo":"20100725173549.GA7930@merkur.sol.de","subject":"Re: [PATCH 2/1] git svn: remove extraneous newline from log output","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-07-26T19:09:45Z","receivedAt":"2010-07-26T19:09:45Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jens Seidel <jensseidel@users.sf.net> wrote:\n> Hi Eric,\n> \n> On Sun, Jul 25, 2010 at 08:13:44AM +0000, Eric Wong wrote:\n> > This is to match the output of \"svn log\", which does not\n> > add an extra newline before the next log entry.\n> \n> thanks for the patch but it doesn't work in the general case.\n> \n> I attached a sample Subversion repository dump where the output of\n> git svn log and svn log still differs by empty lines.\n> \n> I also noticed the following error:\n> Can't use an undefined value as an ARRAY reference at                                                                                            \n> /usr/lib/git-core/git-svn line 5717, <$fh> line 53.\n> \n> I'm not sure whether I introduced this error once I patched\n> git-svn ...\n> The affected line is the second one in:\n>            } elsif (/^${esc_color}    (git-svn-id:.+)$/o) {\n>                         if (@{$c->{l}} && $c->{l}->[-1] eq \"\\n\") {\n>                                 pop @{$c->{l}};\n>                         }\n> (is -1 valid?)\n\nYes, -1 is valid but $c->{l} may not exist at that point..\n\nBut I had forgotten about a similar piece of code in the\n\"show_commit_normal\" subroutine which does a similar job:\n\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\nThis is partially because SVN doesn't enforce a trailing \"\\n\" in\ncommit messages (unlike \"git commit\"), so we always append one\nwhen we fetch and add \"\\ngit-svn-id: ...\\n\".  But then we also\nneed to take noMetadata users into account, too.\n\nI'll let you ponder issues with this since you appear to care more than\nI do about completely matching SVN output :)\n\n\nFor what it's worth, over the years, nobody ever \"outed\" me as a git-svn\nuser in SVN projects when I shared log output.  Some folks worked with\nfor years in the same offices and never made indication to knowing I\nused git-svn (even after they started using it themselves).\n\n-- \nEric Wong\n"}]}