{"thread":{"id":"17159","subject":"[PATCH/RFC] git-svn: Add --convert-timezone option","startedAt":"2009-01-14T00:45:44Z","lastAt":"2009-01-19T03:46:08Z","messageCount":6,"participants":["Pete Harlan","Eric Wong","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"100347","messageId":"496D35B8.70203@pcharlan.com","threadId":"17159","inReplyTo":null,"subject":"[PATCH/RFC] git-svn: Add --convert-timezone option","fromName":"Pete Harlan","fromEmail":"pgit@pcharlan.com","sentAt":"2009-01-14T00:45:44Z","receivedAt":"2009-01-14T00:45:44Z","isPatch":true,"sender":{"key":"pgit@pcharlan.com","avatar":null},"body":"By default git svn stores timestamps of fetched commits in\nSubversion's UTC format, to facilitate interoperating with a\nSubversion repository.\n\nIf you're using git svn to convert a repository to Git and aren't\ninterested in pushing Git commits back to Subversion, you can use this\noption to store timestamps of fetched commits as though they were made\nin the local timezone of the host on which git svn is run.  This makes\nthe times and timezones of a resulting \"git log\" agree with what \"svn\nlog\" shows for the same repository.\n\nSigned-off-by: Pete Harlan <pgit@pcharlan.com>\n---\n\nThis is a patch I've had floating around for a while.  I haven't\nsubmitted it before because I find the solution ungainly.  There has\nto be a better way to convert from one timezone to the other, but I\ndidn't run across it and now that I've converted away from Subversion\nI'm sort of done thinking about it.  I'm submitting it now because\neven in its current state it would have saved me some headache.\n\nAlso, I'm not sure I'm correct when asserting that converting\ntimezones like this will break Subversion interoperability.  Eric, if\nthat isn't true then I can remove that claim and resubmit.  If\nconverting timezones breaks nothing, then maybe it could even be the\ndefault.\n\nOne improvement that I didn't bother to make would be to convert to\ndifferent local timezones based on author.  This change uses the\ntimezone of the machine running git-svn, which in my case was fine.\nUsing per-author timezones would be nice, but since parse_svn_date()\ndoesn't already know which author the date is associated with it would\nbe a more intrusive change.\n\nMy primary motivation in this was to reduce transition shock among our\ndevelopment team.  The fewer ways \"git log\" looks unhelpfully\ndifferent than the old \"svn log\" the better; converting all commit\ntimes into GMT wasn't going to look friendly.\n\nComments welcome.\n\n--Pete\n\n Documentation/git-svn.txt              |    8 ++++\n contrib/completion/git-completion.bash |    2 +-\n git-svn.perl                           |   56 ++++++++++++++++++++++++++++++-\n 3 files changed, 63 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 8d0c421..8811bf0 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -92,6 +92,14 @@ COMMANDS\n \t.git/config file may be specified as an optional command-line\n \targument.\n\n+--convert-timezones;;\n+\tStore Git commit times in the local timezone instead of UTC.  This\n+\tmakes 'git-log' (even without --date=local) show the same times\n+\tthat `svn log` would in the local timezone.\n+\n+This breaks interoperability with SVN, but may be cosmetically\n+desirable when converting a repository from SVN to Git.\n+\n 'clone'::\n \tRuns 'init' and 'fetch'.  It will automatically create a\n \tdirectory based on the basename of the URL passed to it;\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8ec782d..597ef3d 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1560,7 +1560,7 @@ _git_svn ()\n \t\t\t--follow-parent --authors-file= --repack=\n \t\t\t--no-metadata --use-svm-props --use-svnsync-props\n \t\t\t--log-window-size= --no-checkout --quiet\n-\t\t\t--repack-flags --user-log-author $remote_opts\n+\t\t\t--repack-flags --user-log-author --convert-timezones $remote_opts\n \t\t\t\"\n \t\tlocal init_opts=\"\n \t\t\t--template= --shared= --trunk= --tags=\ndiff --git a/git-svn.perl b/git-svn.perl\nindex ad01e18..c2f600d 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit,\n \t$_version, $_fetch_all, $_no_rebase,\n \t$_merge, $_strategy, $_dry_run, $_local,\n \t$_prefix, $_no_checkout, $_url, $_verbose,\n-\t$_git_format, $_commit_url, $_tag);\n+\t$_git_format, $_commit_url, $_tag, $_convert_timezones);\n $Git::SVN::_follow_parent = 1;\n my %remote_opts = ( 'username=s' => \\$Git::SVN::Prompt::_username,\n                     'config-dir=s' => \\$Git::SVN::Ra::config_dir,\n@@ -84,6 +84,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n \t\t   \\$Git::SVN::_repack_flags,\n \t\t'use-log-author' => \\$Git::SVN::_use_log_author,\n \t\t'add-author-from' => \\$Git::SVN::_add_author_from,\n+\t\t'convert-timezones' => \\$_convert_timezones,\n \t\t%remote_opts );\n\n my ($_trunk, $_tags, $_branches, $_stdlayout);\n@@ -2526,12 +2527,63 @@ sub get_untracked {\n \t\\@out;\n }\n\n+# parse_svn_date(DATE)\n+# --------------------\n+# Given a date (in UTC) from Subversion, return a string in the format\n+# \"<TZ Offset> <local date/time>\" that Git will use.\n+#\n+# By default the parsed date will be in UTC for interoperating with\n+# Subversion, but if $_convert_timezones is true we'll convert it to\n+# the local timezone instead.\n sub parse_svn_date {\n \tmy $date = shift || return '+0000 1970-01-01 00:00:00';\n \tmy ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\\d{4})\\-(\\d\\d)\\-(\\d\\d)T\n \t                                    (\\d\\d)\\:(\\d\\d)\\:(\\d\\d).\\d+Z$/x) or\n \t                                 croak \"Unable to parse date: $date\\n\";\n-\t\"+0000 $Y-$m-$d $H:$M:$S\";\n+\tmy $parsed_date;    # Set next.\n+\n+\tif ($_convert_timezones) {\n+\t\t# Translate the Subversion datetime to an epoch time.\n+\t\t# We need to switch ourselves to $date's timezone,\n+\t\t# UTC, for this.\n+\t\tmy $oldEnvTZ = $ENV{TZ};\n+\t\t$ENV{TZ} = 'UTC';\n+\n+\t\tmy $epochUTC =\n+\t\t    POSIX::strftime ('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);\n+\n+\t\t# Determine our local timezone (including DST) at the\n+\t\t# time of $epochUTC.  $Git::SVN::Log::TZ stored the\n+\t\t# value of TZ, if any, at the time we were run.\n+\t\tif (defined $Git::SVN::Log::TZ) {\n+\t\t\t$ENV{TZ} = $Git::SVN::Log::TZ;\n+\t\t} else {\n+\t\t\tdelete $ENV{TZ};\n+\t\t}\n+\n+\t\tmy $ourTZ =\n+\t\t    POSIX::strftime ('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);\n+\n+\t\t# This converts $epochUTC into our local timezone.\n+\t\tmy ($sec, $min, $hour, $mday, $mon, $year,\n+\t\t    $wday, $yday, $isdst) = localtime ($epochUTC);\n+\n+\t\t$parsed_date = sprintf ('%s %04d-%02d-%02d %02d:%02d:%02d',\n+\t\t\t\t\t$ourTZ, $year + 1900, $mon + 1,\n+\t\t\t\t\t$mday, $hour, $min, $sec);\n+\n+\t\t# Reset us to the timezone in effect when we entered\n+\t\t# this routine.\n+\t\tif (defined $oldEnvTZ) {\n+\t\t\t$ENV{TZ} = $oldEnvTZ;\n+\t\t} else {\n+\t\t\tdelete $ENV{TZ};\n+\t\t}\n+\t} else {\n+\t\t$parsed_date = \"+0000 $Y-$m-$d $H:$M:$S\";\n+\t}\n+\n+\treturn $parsed_date;\n }\n\n sub check_author {\n-- \n1.6.1.77.g56257\n"},{"id":"100816","messageId":"20090117103711.GB29598@dcvr.yhbt.net","threadId":"17159","inReplyTo":"496D35B8.70203@pcharlan.com","subject":"Re: [PATCH/RFC] git-svn: Add --convert-timezone option","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2009-01-17T10:37:11Z","receivedAt":"2009-01-17T10:37:11Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Pete Harlan <pgit@pcharlan.com> wrote:\n> By default git svn stores timestamps of fetched commits in\n> Subversion's UTC format, to facilitate interoperating with a\n> Subversion repository.\n> \n> If you're using git svn to convert a repository to Git and aren't\n> interested in pushing Git commits back to Subversion, you can use this\n> option to store timestamps of fetched commits as though they were made\n> in the local timezone of the host on which git svn is run.  This makes\n> the times and timezones of a resulting \"git log\" agree with what \"svn\n> log\" shows for the same repository.\n> \n> Signed-off-by: Pete Harlan <pgit@pcharlan.com>\n> ---\n> \n> This is a patch I've had floating around for a while.  I haven't\n> submitted it before because I find the solution ungainly.  There has\n> to be a better way to convert from one timezone to the other, but I\n> didn't run across it and now that I've converted away from Subversion\n> I'm sort of done thinking about it.  I'm submitting it now because\n> even in its current state it would have saved me some headache.\n> \n> Also, I'm not sure I'm correct when asserting that converting\n> timezones like this will break Subversion interoperability.  Eric, if\n> that isn't true then I can remove that claim and resubmit.  If\n> converting timezones breaks nothing, then maybe it could even be the\n> default.\n\nHi,\n\nIt'll break interoperability between multiple users of git-svn\ntracking the same repo.  But several options already allow for\nthis (authors file, noMetdata, ...), so I'm fine with it as long\nas it's optional.\n\n> One improvement that I didn't bother to make would be to convert to\n> different local timezones based on author.  This change uses the\n> timezone of the machine running git-svn, which in my case was fine.\n> Using per-author timezones would be nice, but since parse_svn_date()\n> doesn't already know which author the date is associated with it would\n> be a more intrusive change.\n\nCould be an interesting idea, but on the other hand I doubt many people\nwould bother configuring the authors-file for it.\n\nOn a side note, for the total conversions I've done, I've found it\neasier/faster/more bandwidth efficient to just forgo authors-file\nentirely and use git-filter-branch after-the-fact.\n\n> My primary motivation in this was to reduce transition shock among our\n> development team.  The fewer ways \"git log\" looks unhelpfully\n> different than the old \"svn log\" the better; converting all commit\n> times into GMT wasn't going to look friendly.\n> \n> Comments welcome.\n\nMy usual coding style nits apply (pretty much git (and Linux kernel)\nstandard coding style things, too).\n\nNo space between \"function(arguments)\".\n\nlower_snake_case, especially for local variables.  mixedCase requires\nmore effort to read IMO.\n\nMore comments inline...\n\n> --Pete\n> \n>  Documentation/git-svn.txt              |    8 ++++\n>  contrib/completion/git-completion.bash |    2 +-\n>  git-svn.perl                           |   56 ++++++++++++++++++++++++++++++-\n>  3 files changed, 63 insertions(+), 3 deletions(-)\n> \n> diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\n> index 8d0c421..8811bf0 100644\n> --- a/Documentation/git-svn.txt\n> +++ b/Documentation/git-svn.txt\n> @@ -92,6 +92,14 @@ COMMANDS\n>  \t.git/config file may be specified as an optional command-line\n>  \targument.\n> \n> +--convert-timezones;;\n\nIs it \"timezone\" or \"timezones\" here?  I think \"convert-timezone\" is\nmore correct since we only use the local timezone, not different\nones for each author.  On the other hand, maybe \"--localtime\" is\nan even better name for this option...\n\nAny other opinions out there?\n\n> +\tStore Git commit times in the local timezone instead of UTC.  This\n> +\tmakes 'git-log' (even without --date=local) show the same times\n> +\tthat `svn log` would in the local timezone.\n> +\n> +This breaks interoperability with SVN, but may be cosmetically\n> +desirable when converting a repository from SVN to Git.\n\nAgain, this only breaks interoperability with other users of git-svn\nusing the default configuration on the same repo.\n\n>  'clone'::\n>  \tRuns 'init' and 'fetch'.  It will automatically create a\n>  \tdirectory based on the basename of the URL passed to it;\n> diff --git a/git-svn.perl b/git-svn.perl\n> index ad01e18..c2f600d 100755\n> --- a/git-svn.perl\n> +++ b/git-svn.perl\n> @@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit,\n>  \t$_version, $_fetch_all, $_no_rebase,\n>  \t$_merge, $_strategy, $_dry_run, $_local,\n>  \t$_prefix, $_no_checkout, $_url, $_verbose,\n> -\t$_git_format, $_commit_url, $_tag);\n> +\t$_git_format, $_commit_url, $_tag, $_convert_timezones);\n\nNot easy to tell (and apologies for that) but this new variable probably\nbelongs in the Git::SVN namespace.  I really need to find some time to\nreorganize and split out the source to git-svn.\n\n>  $Git::SVN::_follow_parent = 1;\n>  my %remote_opts = ( 'username=s' => \\$Git::SVN::Prompt::_username,\n>                      'config-dir=s' => \\$Git::SVN::Ra::config_dir,\n> @@ -84,6 +84,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n>  \t\t   \\$Git::SVN::_repack_flags,\n>  \t\t'use-log-author' => \\$Git::SVN::_use_log_author,\n>  \t\t'add-author-from' => \\$Git::SVN::_add_author_from,\n> +\t\t'convert-timezones' => \\$_convert_timezones,\n>  \t\t%remote_opts );\n> \n>  my ($_trunk, $_tags, $_branches, $_stdlayout);\n> @@ -2526,12 +2527,63 @@ sub get_untracked {\n>  \t\\@out;\n>  }\n> \n> +# parse_svn_date(DATE)\n> +# --------------------\n> +# Given a date (in UTC) from Subversion, return a string in the format\n> +# \"<TZ Offset> <local date/time>\" that Git will use.\n> +#\n> +# By default the parsed date will be in UTC for interoperating with\n> +# Subversion, but if $_convert_timezones is true we'll convert it to\n> +# the local timezone instead.\n>  sub parse_svn_date {\n>  \tmy $date = shift || return '+0000 1970-01-01 00:00:00';\n>  \tmy ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\\d{4})\\-(\\d\\d)\\-(\\d\\d)T\n>  \t                                    (\\d\\d)\\:(\\d\\d)\\:(\\d\\d).\\d+Z$/x) or\n>  \t                                 croak \"Unable to parse date: $date\\n\";\n> -\t\"+0000 $Y-$m-$d $H:$M:$S\";\n> +\tmy $parsed_date;    # Set next.\n> +\n> +\tif ($_convert_timezones) {\n> +\t\t# Translate the Subversion datetime to an epoch time.\n> +\t\t# We need to switch ourselves to $date's timezone,\n> +\t\t# UTC, for this.\n> +\t\tmy $oldEnvTZ = $ENV{TZ};\n> +\t\t$ENV{TZ} = 'UTC';\n> +\n> +\t\tmy $epochUTC =\n> +\t\t    POSIX::strftime ('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);\n> +\n> +\t\t# Determine our local timezone (including DST) at the\n> +\t\t# time of $epochUTC.  $Git::SVN::Log::TZ stored the\n> +\t\t# value of TZ, if any, at the time we were run.\n> +\t\tif (defined $Git::SVN::Log::TZ) {\n> +\t\t\t$ENV{TZ} = $Git::SVN::Log::TZ;\n> +\t\t} else {\n> +\t\t\tdelete $ENV{TZ};\n> +\t\t}\n> +\n> +\t\tmy $ourTZ =\n> +\t\t    POSIX::strftime ('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);\n> +\n> +\t\t# This converts $epochUTC into our local timezone.\n> +\t\tmy ($sec, $min, $hour, $mday, $mon, $year,\n> +\t\t    $wday, $yday, $isdst) = localtime ($epochUTC);\n> +\n> +\t\t$parsed_date = sprintf ('%s %04d-%02d-%02d %02d:%02d:%02d',\n> +\t\t\t\t\t$ourTZ, $year + 1900, $mon + 1,\n> +\t\t\t\t\t$mday, $hour, $min, $sec);\n\nThere's probably a reason you didn't use strftime here, or is there?\nThe stock Perl time/date handling functions have always frightened me,\nso I'll just trust the (+|-) (1|1900) things are correct :)\n\n-- \nEric Wong\n"},{"id":"100915","messageId":"4972A896.5050205@pcharlan.com","threadId":"17159","inReplyTo":"20090117103711.GB29598@dcvr.yhbt.net","subject":"Re: [PATCH/RFC] git-svn: Add --convert-timezone option","fromName":"Pete Harlan","fromEmail":"pgit@pcharlan.com","sentAt":"2009-01-18T03:57:10Z","receivedAt":"2009-01-18T03:57:10Z","isPatch":true,"sender":{"key":"pgit@pcharlan.com","avatar":null},"body":"Eric Wong wrote:\n> Pete Harlan <pgit@pcharlan.com> wrote:\n>> By default git svn stores timestamps of fetched commits in\n>> Subversion's UTC format, to facilitate interoperating with a\n>> Subversion repository.\n>>\n>> If you're using git svn to convert a repository to Git and aren't\n>> interested in pushing Git commits back to Subversion, you can use this\n>> option to store timestamps of fetched commits as though they were made\n>> in the local timezone of the host on which git svn is run.  This makes\n>> the times and timezones of a resulting \"git log\" agree with what \"svn\n>> log\" shows for the same repository.\n>>\n>> Signed-off-by: Pete Harlan <pgit@pcharlan.com>\n>> ---\n>>\n>> This is a patch I've had floating around for a while.  I haven't\n>> submitted it before because I find the solution ungainly.  There has\n>> to be a better way to convert from one timezone to the other, but I\n>> didn't run across it and now that I've converted away from Subversion\n>> I'm sort of done thinking about it.  I'm submitting it now because\n>> even in its current state it would have saved me some headache.\n>>\n>> Also, I'm not sure I'm correct when asserting that converting\n>> timezones like this will break Subversion interoperability.  Eric, if\n>> that isn't true then I can remove that claim and resubmit.  If\n>> converting timezones breaks nothing, then maybe it could even be the\n>> default.\n> \n> Hi,\n> \n> It'll break interoperability between multiple users of git-svn\n> tracking the same repo.  But several options already allow for\n> this (authors file, noMetdata, ...), so I'm fine with it as long\n> as it's optional.\n\nThank you for your review.  I'll comment here and then followup with a\nreplacement patch.\n\n>> One improvement that I didn't bother to make would be to convert to\n>> different local timezones based on author.  This change uses the\n>> timezone of the machine running git-svn, which in my case was fine.\n>> Using per-author timezones would be nice, but since parse_svn_date()\n>> doesn't already know which author the date is associated with it would\n>> be a more intrusive change.\n> \n> Could be an interesting idea, but on the other hand I doubt many people\n> would bother configuring the authors-file for it.\n> \n> On a side note, for the total conversions I've done, I've found it\n> easier/faster/more bandwidth efficient to just forgo authors-file\n> entirely and use git-filter-branch after-the-fact.\n\nInteresting.  When I was using git-svn I was new enough to Git that I\nwasn't aware of filter-branch.\n\n>> My primary motivation in this was to reduce transition shock among our\n>> development team.  The fewer ways \"git log\" looks unhelpfully\n>> different than the old \"svn log\" the better; converting all commit\n>> times into GMT wasn't going to look friendly.\n>>\n>> Comments welcome.\n> \n> My usual coding style nits apply (pretty much git (and Linux kernel)\n> standard coding style things, too).\n> \n> No space between \"function(arguments)\".\n> \n> lower_snake_case, especially for local variables.  mixedCase requires\n> more effort to read IMO.\n\nThanks; I'm sorry you had to point these things out.  Hopefully fixed\nin the followup patch.\n\n> More comments inline...\n> \n>> --Pete\n>>\n>>  Documentation/git-svn.txt              |    8 ++++\n>>  contrib/completion/git-completion.bash |    2 +-\n>>  git-svn.perl                           |   56 ++++++++++++++++++++++++++++++-\n>>  3 files changed, 63 insertions(+), 3 deletions(-)\n>>\n>> diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\n>> index 8d0c421..8811bf0 100644\n>> --- a/Documentation/git-svn.txt\n>> +++ b/Documentation/git-svn.txt\n>> @@ -92,6 +92,14 @@ COMMANDS\n>>  \t.git/config file may be specified as an optional command-line\n>>  \targument.\n>>\n>> +--convert-timezones;;\n> \n> Is it \"timezone\" or \"timezones\" here?  I think \"convert-timezone\" is\n> more correct since we only use the local timezone, not different\n> ones for each author.  On the other hand, maybe \"--localtime\" is\n> an even better name for this option...\n> \n> Any other opinions out there?\n\nI liked your \"--localtime\" suggestion, and used that in v2.  I\noriginally chose plural for \"timzeones\" because it converts between\ntwo timezones, and there are two timestamps associated with each\ncommit (even if they're the same, in git-svn).  But singular would\nhave made just as much sense, and at one point it was singular.\n\n>> +\tStore Git commit times in the local timezone instead of UTC.  This\n>> +\tmakes 'git-log' (even without --date=local) show the same times\n>> +\tthat `svn log` would in the local timezone.\n>> +\n>> +This breaks interoperability with SVN, but may be cosmetically\n>> +desirable when converting a repository from SVN to Git.\n> \n> Again, this only breaks interoperability with other users of git-svn\n> using the default configuration on the same repo.\n\nThanks, fixed in v2.\n\n>>  'clone'::\n>>  \tRuns 'init' and 'fetch'.  It will automatically create a\n>>  \tdirectory based on the basename of the URL passed to it;\n>> diff --git a/git-svn.perl b/git-svn.perl\n>> index ad01e18..c2f600d 100755\n>> --- a/git-svn.perl\n>> +++ b/git-svn.perl\n>> @@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit,\n>>  \t$_version, $_fetch_all, $_no_rebase,\n>>  \t$_merge, $_strategy, $_dry_run, $_local,\n>>  \t$_prefix, $_no_checkout, $_url, $_verbose,\n>> -\t$_git_format, $_commit_url, $_tag);\n>> +\t$_git_format, $_commit_url, $_tag, $_convert_timezones);\n> \n> Not easy to tell (and apologies for that) but this new variable probably\n> belongs in the Git::SVN namespace.  I really need to find some time to\n> reorganize and split out the source to git-svn.\n\nI moved it into Git::SVN for v2, though I admit to not having a good\ngrasp of the big picture about what belongs where.\n\n>>  $Git::SVN::_follow_parent = 1;\n>>  my %remote_opts = ( 'username=s' => \\$Git::SVN::Prompt::_username,\n>>                      'config-dir=s' => \\$Git::SVN::Ra::config_dir,\n>> @@ -84,6 +84,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n>>  \t\t   \\$Git::SVN::_repack_flags,\n>>  \t\t'use-log-author' => \\$Git::SVN::_use_log_author,\n>>  \t\t'add-author-from' => \\$Git::SVN::_add_author_from,\n>> +\t\t'convert-timezones' => \\$_convert_timezones,\n>>  \t\t%remote_opts );\n>>\n>>  my ($_trunk, $_tags, $_branches, $_stdlayout);\n>> @@ -2526,12 +2527,63 @@ sub get_untracked {\n>>  \t\\@out;\n>>  }\n>>\n>> +# parse_svn_date(DATE)\n>> +# --------------------\n>> +# Given a date (in UTC) from Subversion, return a string in the format\n>> +# \"<TZ Offset> <local date/time>\" that Git will use.\n>> +#\n>> +# By default the parsed date will be in UTC for interoperating with\n>> +# Subversion, but if $_convert_timezones is true we'll convert it to\n>> +# the local timezone instead.\n>>  sub parse_svn_date {\n>>  \tmy $date = shift || return '+0000 1970-01-01 00:00:00';\n>>  \tmy ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\\d{4})\\-(\\d\\d)\\-(\\d\\d)T\n>>  \t                                    (\\d\\d)\\:(\\d\\d)\\:(\\d\\d).\\d+Z$/x) or\n>>  \t                                 croak \"Unable to parse date: $date\\n\";\n>> -\t\"+0000 $Y-$m-$d $H:$M:$S\";\n>> +\tmy $parsed_date;    # Set next.\n>> +\n>> +\tif ($_convert_timezones) {\n>> +\t\t# Translate the Subversion datetime to an epoch time.\n>> +\t\t# We need to switch ourselves to $date's timezone,\n>> +\t\t# UTC, for this.\n>> +\t\tmy $oldEnvTZ = $ENV{TZ};\n>> +\t\t$ENV{TZ} = 'UTC';\n>> +\n>> +\t\tmy $epochUTC =\n>> +\t\t    POSIX::strftime ('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);\n>> +\n>> +\t\t# Determine our local timezone (including DST) at the\n>> +\t\t# time of $epochUTC.  $Git::SVN::Log::TZ stored the\n>> +\t\t# value of TZ, if any, at the time we were run.\n>> +\t\tif (defined $Git::SVN::Log::TZ) {\n>> +\t\t\t$ENV{TZ} = $Git::SVN::Log::TZ;\n>> +\t\t} else {\n>> +\t\t\tdelete $ENV{TZ};\n>> +\t\t}\n>> +\n>> +\t\tmy $ourTZ =\n>> +\t\t    POSIX::strftime ('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);\n>> +\n>> +\t\t# This converts $epochUTC into our local timezone.\n>> +\t\tmy ($sec, $min, $hour, $mday, $mon, $year,\n>> +\t\t    $wday, $yday, $isdst) = localtime ($epochUTC);\n>> +\n>> +\t\t$parsed_date = sprintf ('%s %04d-%02d-%02d %02d:%02d:%02d',\n>> +\t\t\t\t\t$ourTZ, $year + 1900, $mon + 1,\n>> +\t\t\t\t\t$mday, $hour, $min, $sec);\n> \n> There's probably a reason you didn't use strftime here, or is there?\n\nIf you mean why couldn't I have saved an sprintf by using the previous\nstrftime call to format this data at the same time I got the timzeone,\nit's because strftime doesn't convert the time into the local\ntimezone.  It just passes back the same values that you pass in.\n\n> The stock Perl time/date handling functions have always frightened me,\n> so I'll just trust the (+|-) (1|1900) things are correct :)\n\n:) I tested it pretty well...\n\n--\nPete Harlan\npgit@pcharlan.com\n"},{"id":"100917","messageId":"4972ABA6.7060207@pcharlan.com","threadId":"17159","inReplyTo":"4972A896.5050205@pcharlan.com","subject":"[PATCH v2] git-svn: Add --localtime option to \"fetch\"","fromName":"Pete Harlan","fromEmail":"pgit@pcharlan.com","sentAt":"2009-01-18T04:10:14Z","receivedAt":"2009-01-18T04:10:14Z","isPatch":true,"sender":{"key":"pgit@pcharlan.com","avatar":null},"body":"By default git-svn stores timestamps of fetched commits in\nSubversion's UTC format.  Passing --localtime to fetch will convert\nthem to the timezone of the server on which git-svn is run.\n\nThis makes the timestamps of a resulting \"git log\" agree with what\n\"svn log\" shows for the same repository.\n\nSigned-off-by: Pete Harlan <pgit@pcharlan.com>\n---\n\nChanges to v2 after feedback from Eric Wong:\n\n1. \"--convert-timezones\" renamed to \"--localtime\".\n\n2. Removed warnings about breaking interoperability with Subversion,\n   because the option doesn't do that.  Instead warn about\n   interoperability with other git-svn users cloning from the same\n   repository if they don't all use or not use --localtime.\n\n3. Move config variable into Git::SVN namespace.\n\n4. Better conformance to coding guidelines.\n\n Documentation/git-svn.txt              |   11 ++++++\n contrib/completion/git-completion.bash |    2 +-\n git-svn.perl                           |   54 ++++++++++++++++++++++++++++++-\n 3 files changed, 64 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 8d0c421..63d2f5e 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -92,6 +92,17 @@ COMMANDS\n \t.git/config file may be specified as an optional command-line\n \targument.\n\n+--localtime;;\n+\tStore Git commit times in the local timezone instead of UTC.  This\n+\tmakes 'git-log' (even without --date=local) show the same times\n+\tthat `svn log` would in the local timezone.\n+\n+This doesn't interfere with interoperating with the Subversion\n+repository you cloned from, but if you wish for your local Git\n+repository to be able to interoperate with someone else's local Git\n+repository, either don't use this option or you should both use it in\n+the same local timezone.\n+\n 'clone'::\n \tRuns 'init' and 'fetch'.  It will automatically create a\n \tdirectory based on the basename of the URL passed to it;\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f8b845a..c9d2c02 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1575,7 +1575,7 @@ _git_svn ()\n \t\t\t--follow-parent --authors-file= --repack=\n \t\t\t--no-metadata --use-svm-props --use-svnsync-props\n \t\t\t--log-window-size= --no-checkout --quiet\n-\t\t\t--repack-flags --user-log-author $remote_opts\n+\t\t\t--repack-flags --user-log-author --localtime $remote_opts\n \t\t\t\"\n \t\tlocal init_opts=\"\n \t\t\t--template= --shared= --trunk= --tags=\ndiff --git a/git-svn.perl b/git-svn.perl\nindex ad01e18..0adc8db 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -84,6 +84,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n \t\t   \\$Git::SVN::_repack_flags,\n \t\t'use-log-author' => \\$Git::SVN::_use_log_author,\n \t\t'add-author-from' => \\$Git::SVN::_add_author_from,\n+\t\t'localtime' => \\$Git::SVN::_localtime,\n \t\t%remote_opts );\n\n my ($_trunk, $_tags, $_branches, $_stdlayout);\n@@ -1364,7 +1365,7 @@ use constant rev_map_fmt => 'NH40';\n use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent\n             $_repack $_repack_flags $_use_svm_props $_head\n             $_use_svnsync_props $no_reuse_existing $_minimize_url\n-\t    $_use_log_author $_add_author_from/;\n+\t    $_use_log_author $_add_author_from $_localtime/;\n use Carp qw/croak/;\n use File::Path qw/mkpath/;\n use File::Copy qw/copy/;\n@@ -2526,12 +2527,61 @@ sub get_untracked {\n \t\\@out;\n }\n\n+# parse_svn_date(DATE)\n+# --------------------\n+# Given a date (in UTC) from Subversion, return a string in the format\n+# \"<TZ Offset> <local date/time>\" that Git will use.\n+#\n+# By default the parsed date will be in UTC; if $Git::SVN::_localtime\n+# is true we'll convert it to the local timezone instead.\n sub parse_svn_date {\n \tmy $date = shift || return '+0000 1970-01-01 00:00:00';\n \tmy ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\\d{4})\\-(\\d\\d)\\-(\\d\\d)T\n \t                                    (\\d\\d)\\:(\\d\\d)\\:(\\d\\d).\\d+Z$/x) or\n \t                                 croak \"Unable to parse date: $date\\n\";\n-\t\"+0000 $Y-$m-$d $H:$M:$S\";\n+\tmy $parsed_date;    # Set next.\n+\n+\tif ($Git::SVN::_localtime) {\n+\t\t# Translate the Subversion datetime to an epoch time.\n+\t\t# Begin by switching ourselves to $date's timezone, UTC.\n+\t\tmy $old_env_TZ = $ENV{TZ};\n+\t\t$ENV{TZ} = 'UTC';\n+\n+\t\tmy $epoch_in_UTC =\n+\t\t    POSIX::strftime('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);\n+\n+\t\t# Determine our local timezone (including DST) at the\n+\t\t# time of $epoch_in_UTC.  $Git::SVN::Log::TZ stored the\n+\t\t# value of TZ, if any, at the time we were run.\n+\t\tif (defined $Git::SVN::Log::TZ) {\n+\t\t\t$ENV{TZ} = $Git::SVN::Log::TZ;\n+\t\t} else {\n+\t\t\tdelete $ENV{TZ};\n+\t\t}\n+\n+\t\tmy $our_TZ =\n+\t\t    POSIX::strftime('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);\n+\n+\t\t# This converts $epoch_in_UTC into our local timezone.\n+\t\tmy ($sec, $min, $hour, $mday, $mon, $year,\n+\t\t    $wday, $yday, $isdst) = localtime($epoch_in_UTC);\n+\n+\t\t$parsed_date = sprintf('%s %04d-%02d-%02d %02d:%02d:%02d',\n+\t\t\t\t       $our_TZ, $year + 1900, $mon + 1,\n+\t\t\t\t       $mday, $hour, $min, $sec);\n+\n+\t\t# Reset us to the timezone in effect when we entered\n+\t\t# this routine.\n+\t\tif (defined $old_env_TZ) {\n+\t\t\t$ENV{TZ} = $old_env_TZ;\n+\t\t} else {\n+\t\t\tdelete $ENV{TZ};\n+\t\t}\n+\t} else {\n+\t\t$parsed_date = \"+0000 $Y-$m-$d $H:$M:$S\";\n+\t}\n+\n+\treturn $parsed_date;\n }\n\n sub check_author {\n-- \n1.6.1.77.g953e7\n"},{"id":"101073","messageId":"20090119004318.GA5128@untitled","threadId":"17159","inReplyTo":"4972ABA6.7060207@pcharlan.com","subject":"Re: [PATCH v2] git-svn: Add --localtime option to \"fetch\"","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2009-01-19T00:43:18Z","receivedAt":"2009-01-19T00:43:18Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Pete Harlan <pgit@pcharlan.com> wrote:\n> By default git-svn stores timestamps of fetched commits in\n> Subversion's UTC format.  Passing --localtime to fetch will convert\n> them to the timezone of the server on which git-svn is run.\n> \n> This makes the timestamps of a resulting \"git log\" agree with what\n> \"svn log\" shows for the same repository.\n> \n> Signed-off-by: Pete Harlan <pgit@pcharlan.com>\n\nThanks Peter,\n\nAcked-by: Eric Wong <normalperson@yhbt.net>\n\n> ---\n> \n> Changes to v2 after feedback from Eric Wong:\n> \n> 1. \"--convert-timezones\" renamed to \"--localtime\".\n> \n> 2. Removed warnings about breaking interoperability with Subversion,\n>    because the option doesn't do that.  Instead warn about\n>    interoperability with other git-svn users cloning from the same\n>    repository if they don't all use or not use --localtime.\n> \n> 3. Move config variable into Git::SVN namespace.\n> \n> 4. Better conformance to coding guidelines.\n> \n>  Documentation/git-svn.txt              |   11 ++++++\n>  contrib/completion/git-completion.bash |    2 +-\n>  git-svn.perl                           |   54 ++++++++++++++++++++++++++++++-\n>  3 files changed, 64 insertions(+), 3 deletions(-)\n> \n> diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\n> index 8d0c421..63d2f5e 100644\n> --- a/Documentation/git-svn.txt\n> +++ b/Documentation/git-svn.txt\n> @@ -92,6 +92,17 @@ COMMANDS\n>  \t.git/config file may be specified as an optional command-line\n>  \targument.\n> \n> +--localtime;;\n> +\tStore Git commit times in the local timezone instead of UTC.  This\n> +\tmakes 'git-log' (even without --date=local) show the same times\n> +\tthat `svn log` would in the local timezone.\n> +\n> +This doesn't interfere with interoperating with the Subversion\n> +repository you cloned from, but if you wish for your local Git\n> +repository to be able to interoperate with someone else's local Git\n> +repository, either don't use this option or you should both use it in\n> +the same local timezone.\n> +\n>  'clone'::\n>  \tRuns 'init' and 'fetch'.  It will automatically create a\n>  \tdirectory based on the basename of the URL passed to it;\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index f8b845a..c9d2c02 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -1575,7 +1575,7 @@ _git_svn ()\n>  \t\t\t--follow-parent --authors-file= --repack=\n>  \t\t\t--no-metadata --use-svm-props --use-svnsync-props\n>  \t\t\t--log-window-size= --no-checkout --quiet\n> -\t\t\t--repack-flags --user-log-author $remote_opts\n> +\t\t\t--repack-flags --user-log-author --localtime $remote_opts\n>  \t\t\t\"\n>  \t\tlocal init_opts=\"\n>  \t\t\t--template= --shared= --trunk= --tags=\n> diff --git a/git-svn.perl b/git-svn.perl\n> index ad01e18..0adc8db 100755\n> --- a/git-svn.perl\n> +++ b/git-svn.perl\n> @@ -84,6 +84,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n>  \t\t   \\$Git::SVN::_repack_flags,\n>  \t\t'use-log-author' => \\$Git::SVN::_use_log_author,\n>  \t\t'add-author-from' => \\$Git::SVN::_add_author_from,\n> +\t\t'localtime' => \\$Git::SVN::_localtime,\n>  \t\t%remote_opts );\n> \n>  my ($_trunk, $_tags, $_branches, $_stdlayout);\n> @@ -1364,7 +1365,7 @@ use constant rev_map_fmt => 'NH40';\n>  use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent\n>              $_repack $_repack_flags $_use_svm_props $_head\n>              $_use_svnsync_props $no_reuse_existing $_minimize_url\n> -\t    $_use_log_author $_add_author_from/;\n> +\t    $_use_log_author $_add_author_from $_localtime/;\n>  use Carp qw/croak/;\n>  use File::Path qw/mkpath/;\n>  use File::Copy qw/copy/;\n> @@ -2526,12 +2527,61 @@ sub get_untracked {\n>  \t\\@out;\n>  }\n> \n> +# parse_svn_date(DATE)\n> +# --------------------\n> +# Given a date (in UTC) from Subversion, return a string in the format\n> +# \"<TZ Offset> <local date/time>\" that Git will use.\n> +#\n> +# By default the parsed date will be in UTC; if $Git::SVN::_localtime\n> +# is true we'll convert it to the local timezone instead.\n>  sub parse_svn_date {\n>  \tmy $date = shift || return '+0000 1970-01-01 00:00:00';\n>  \tmy ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\\d{4})\\-(\\d\\d)\\-(\\d\\d)T\n>  \t                                    (\\d\\d)\\:(\\d\\d)\\:(\\d\\d).\\d+Z$/x) or\n>  \t                                 croak \"Unable to parse date: $date\\n\";\n> -\t\"+0000 $Y-$m-$d $H:$M:$S\";\n> +\tmy $parsed_date;    # Set next.\n> +\n> +\tif ($Git::SVN::_localtime) {\n> +\t\t# Translate the Subversion datetime to an epoch time.\n> +\t\t# Begin by switching ourselves to $date's timezone, UTC.\n> +\t\tmy $old_env_TZ = $ENV{TZ};\n> +\t\t$ENV{TZ} = 'UTC';\n> +\n> +\t\tmy $epoch_in_UTC =\n> +\t\t    POSIX::strftime('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);\n> +\n> +\t\t# Determine our local timezone (including DST) at the\n> +\t\t# time of $epoch_in_UTC.  $Git::SVN::Log::TZ stored the\n> +\t\t# value of TZ, if any, at the time we were run.\n> +\t\tif (defined $Git::SVN::Log::TZ) {\n> +\t\t\t$ENV{TZ} = $Git::SVN::Log::TZ;\n> +\t\t} else {\n> +\t\t\tdelete $ENV{TZ};\n> +\t\t}\n> +\n> +\t\tmy $our_TZ =\n> +\t\t    POSIX::strftime('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);\n> +\n> +\t\t# This converts $epoch_in_UTC into our local timezone.\n> +\t\tmy ($sec, $min, $hour, $mday, $mon, $year,\n> +\t\t    $wday, $yday, $isdst) = localtime($epoch_in_UTC);\n> +\n> +\t\t$parsed_date = sprintf('%s %04d-%02d-%02d %02d:%02d:%02d',\n> +\t\t\t\t       $our_TZ, $year + 1900, $mon + 1,\n> +\t\t\t\t       $mday, $hour, $min, $sec);\n> +\n> +\t\t# Reset us to the timezone in effect when we entered\n> +\t\t# this routine.\n> +\t\tif (defined $old_env_TZ) {\n> +\t\t\t$ENV{TZ} = $old_env_TZ;\n> +\t\t} else {\n> +\t\t\tdelete $ENV{TZ};\n> +\t\t}\n> +\t} else {\n> +\t\t$parsed_date = \"+0000 $Y-$m-$d $H:$M:$S\";\n> +\t}\n> +\n> +\treturn $parsed_date;\n>  }\n> \n>  sub check_author {\n> -- \n> 1.6.1.77.g953e7\n"},{"id":"101092","messageId":"7vbpu4rm9r.fsf@gitster.siamese.dyndns.org","threadId":"17159","inReplyTo":"20090119004318.GA5128@untitled","subject":"Re: [PATCH v2] git-svn: Add --localtime option to \"fetch\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-01-19T03:46:08Z","receivedAt":"2009-01-19T03:46:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks, both.\n"}]}