* [PATCH 0/3] Fix a portability issue with git-cvsimport
@ 2013-02-09 21:46 Ben Walton
2013-02-09 21:46 ` [PATCH 1/3] Move Git::SVN::get_tz to Git::get_tz_offset Ben Walton
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Ben Walton @ 2013-02-09 21:46 UTC (permalink / raw)
To: gitster; +Cc: git, Ben Walton
This is my (long overdue) re-roll of the series that fixes a
portability issue with git-cvsimport's use of strftime. It also fixes
a but in the original implementation of get_tz (now get_tz_offset).
I ended up taking taking only part of the implementation suggested by
Junio.
The only usage of get_tz_offset is by git-cvsimport and Git::SVN::Log
currently. There are tests that validate it works currently so I
didn't add anything additional. If the git-cvsimport tests are
removed, there are no tests remaining that exercise the code full as
the SVN tests use UTC times.
Ben Walton (3):
Move Git::SVN::get_tz to Git::get_tz_offset
Fix get_tz_offset to properly handle DST boundary cases
Avoid non-portable strftime format specifiers in git-cvsimport
git-cvsimport.perl | 5 ++++-
perl/Git.pm | 23 +++++++++++++++++++++++
perl/Git/SVN.pm | 12 ++----------
perl/Git/SVN/Log.pm | 8 ++++++--
4 files changed, 35 insertions(+), 13 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] Move Git::SVN::get_tz to Git::get_tz_offset
2013-02-09 21:46 [PATCH 0/3] Fix a portability issue with git-cvsimport Ben Walton
@ 2013-02-09 21:46 ` Ben Walton
2013-02-09 21:46 ` [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases Ben Walton
2013-02-09 21:46 ` [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport Ben Walton
2 siblings, 0 replies; 6+ messages in thread
From: Ben Walton @ 2013-02-09 21:46 UTC (permalink / raw)
To: gitster; +Cc: git, Ben Walton
This function has utility outside of the SVN module for any routine
that needs the equivalent of GNU strftime's %z formatting option.
Move it to the top-level Git.pm so that non-SVN modules don't need to
import the SVN module to use it.
The rename makes the purpose of the function clearer.
Signed-off-by: Ben Walton <bdwalton@gmail.com>
---
perl/Git.pm | 23 +++++++++++++++++++++++
perl/Git/SVN.pm | 12 ++----------
perl/Git/SVN/Log.pm | 8 ++++++--
3 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 931047c..5649bcc 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -59,6 +59,7 @@ require Exporter;
command_bidi_pipe command_close_bidi_pipe
version exec_path html_path hash_object git_cmd_try
remote_refs prompt
+ get_tz_offset
temp_acquire temp_release temp_reset temp_path);
@@ -102,6 +103,7 @@ use Error qw(:try);
use Cwd qw(abs_path cwd);
use IPC::Open2 qw(open2);
use Fcntl qw(SEEK_SET SEEK_CUR);
+use Time::Local qw(timelocal);
}
@@ -511,6 +513,27 @@ C<git --html-path>). Useful mostly only internally.
sub html_path { command_oneline('--html-path') }
+
+=item get_tz_offset ( TIME )
+
+Return the time zone offset from GMT in the form +/-HHMM where HH is
+the number of hours from GMT and MM is the number of minutes. This is
+the equivalent of what strftime("%z", ...) would provide on a GNU
+platform.
+
+If TIME is not supplied, the current local time is used.
+
+=cut
+
+sub get_tz_offset {
+ # some systmes don't handle or mishandle %z, so be creative.
+ my $t = shift || time;
+ my $gm = timelocal(gmtime($t));
+ my $sign = qw( + + - )[ $t <=> $gm ];
+ return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
+}
+
+
=item prompt ( PROMPT , ISPASSWORD )
Query user C<PROMPT> and return answer from user.
diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm
index 490e330..0ebc68a 100644
--- a/perl/Git/SVN.pm
+++ b/perl/Git/SVN.pm
@@ -11,7 +11,6 @@ use Carp qw/croak/;
use File::Path qw/mkpath/;
use File::Copy qw/copy/;
use IPC::Open3;
-use Time::Local;
use Memoize; # core since 5.8.0, Jul 2002
use Memoize::Storable;
use POSIX qw(:signal_h);
@@ -22,6 +21,7 @@ use Git qw(
command_noisy
command_output_pipe
command_close_pipe
+ get_tz_offset
);
use Git::SVN::Utils qw(
fatal
@@ -1311,14 +1311,6 @@ sub get_untracked {
\@out;
}
-sub get_tz {
- # some systmes don't handle or mishandle %z, so be creative.
- my $t = shift || time;
- my $gm = timelocal(gmtime($t));
- my $sign = qw( + + - )[ $t <=> $gm ];
- return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
-}
-
# parse_svn_date(DATE)
# --------------------
# Given a date (in UTC) from Subversion, return a string in the format
@@ -1351,7 +1343,7 @@ sub parse_svn_date {
delete $ENV{TZ};
}
- my $our_TZ = get_tz();
+ my $our_TZ = get_tz_offset();
# This converts $epoch_in_UTC into our local timezone.
my ($sec, $min, $hour, $mday, $mon, $year,
diff --git a/perl/Git/SVN/Log.pm b/perl/Git/SVN/Log.pm
index 3cc1c6f..3f8350a 100644
--- a/perl/Git/SVN/Log.pm
+++ b/perl/Git/SVN/Log.pm
@@ -2,7 +2,11 @@ package Git::SVN::Log;
use strict;
use warnings;
use Git::SVN::Utils qw(fatal);
-use Git qw(command command_oneline command_output_pipe command_close_pipe);
+use Git qw(command
+ command_oneline
+ command_output_pipe
+ command_close_pipe
+ get_tz_offset);
use POSIX qw/strftime/;
use constant commit_log_separator => ('-' x 72) . "\n";
use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
@@ -119,7 +123,7 @@ sub run_pager {
sub format_svn_date {
my $t = shift || time;
require Git::SVN;
- my $gmoff = Git::SVN::get_tz($t);
+ my $gmoff = get_tz_offset($t);
return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases
2013-02-09 21:46 [PATCH 0/3] Fix a portability issue with git-cvsimport Ben Walton
2013-02-09 21:46 ` [PATCH 1/3] Move Git::SVN::get_tz to Git::get_tz_offset Ben Walton
@ 2013-02-09 21:46 ` Ben Walton
2013-02-09 22:58 ` Junio C Hamano
2013-02-09 21:46 ` [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport Ben Walton
2 siblings, 1 reply; 6+ messages in thread
From: Ben Walton @ 2013-02-09 21:46 UTC (permalink / raw)
To: gitster; +Cc: git, Ben Walton
When passed a local time that was on the boundary of a DST change,
get_tz_offset returned a GMT offset that was incorrect (off by one
hour). This is because the time was converted to GMT and then back to
a time stamp via timelocal() which cannot disambiguate boundary cases
as noted in its documentation.
Modify this algorithm, using an approach suggested by Junio C Hamano
that obtains the GMT time stamp by using timegm(localtime()) instead
of timelocal(gmtime()). This avoids the ambigious conversion and
allows a correct time to be returned on every occassion.
Signed-off-by: Ben Walton <bdwalton@gmail.com>
---
perl/Git.pm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 5649bcc..a56d1e7 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -103,7 +103,7 @@ use Error qw(:try);
use Cwd qw(abs_path cwd);
use IPC::Open2 qw(open2);
use Fcntl qw(SEEK_SET SEEK_CUR);
-use Time::Local qw(timelocal);
+use Time::Local qw(timegm);
}
@@ -528,8 +528,8 @@ If TIME is not supplied, the current local time is used.
sub get_tz_offset {
# some systmes don't handle or mishandle %z, so be creative.
my $t = shift || time;
- my $gm = timelocal(gmtime($t));
- my $sign = qw( + + - )[ $t <=> $gm ];
+ my $gm = timegm(localtime($t));
+ my $sign = qw( + + - )[ $gm <=> $t ];
return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport
2013-02-09 21:46 [PATCH 0/3] Fix a portability issue with git-cvsimport Ben Walton
2013-02-09 21:46 ` [PATCH 1/3] Move Git::SVN::get_tz to Git::get_tz_offset Ben Walton
2013-02-09 21:46 ` [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases Ben Walton
@ 2013-02-09 21:46 ` Ben Walton
2013-02-09 22:20 ` Junio C Hamano
2 siblings, 1 reply; 6+ messages in thread
From: Ben Walton @ 2013-02-09 21:46 UTC (permalink / raw)
To: gitster; +Cc: git, Ben Walton
Neither %s or %z are portable strftime format specifiers. There is no
need for %s in git-cvsimport as the supplied time is already in
seconds since the epoch. For %z, use the function get_tz_offset
provided by Git.pm instead.
Signed-off-by: Ben Walton <bdwalton@gmail.com>
---
git-cvsimport.perl | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 0a31ebd..344f120 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -26,6 +26,7 @@ use IO::Socket;
use IO::Pipe;
use POSIX qw(strftime tzset dup2 ENOENT);
use IPC::Open2;
+use Git qw(get_tz_offset);
$SIG{'PIPE'}="IGNORE";
set_timezone('UTC');
@@ -864,7 +865,9 @@ sub commit {
}
set_timezone($author_tz);
- my $commit_date = strftime("%s %z", localtime($date));
+ # $date is in the seconds since epoch format
+ my $tz_offset = get_tz_offset($date);
+ my $commit_date = "$date $tz_offset";
set_timezone('UTC');
$ENV{GIT_AUTHOR_NAME} = $author_name;
$ENV{GIT_AUTHOR_EMAIL} = $author_email;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport
2013-02-09 21:46 ` [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport Ben Walton
@ 2013-02-09 22:20 ` Junio C Hamano
0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2013-02-09 22:20 UTC (permalink / raw)
To: Ben Walton; +Cc: git
Ben Walton <bdwalton@gmail.com> writes:
> Neither %s or %z are portable strftime format specifiers.
Well, at least %z is in POSIX; "Some implementations of strftime(3)
lack support for %z format" is fine, tough.
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases
2013-02-09 21:46 ` [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases Ben Walton
@ 2013-02-09 22:58 ` Junio C Hamano
0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2013-02-09 22:58 UTC (permalink / raw)
To: Ben Walton; +Cc: git
Ben Walton <bdwalton@gmail.com> writes:
> When passed a local time that was on the boundary of a DST change,
> get_tz_offset returned a GMT offset that was incorrect (off by one
> hour). This is because the time was converted to GMT and then back to
> a time stamp via timelocal() which cannot disambiguate boundary cases
> as noted in its documentation.
>
> Modify this algorithm, using an approach suggested by Junio C Hamano
> that obtains the GMT time stamp by using timegm(localtime()) instead
> of timelocal(gmtime()). This avoids the ambigious conversion and
> allows a correct time to be returned on every occassion.
I'll reword the log message a bit to explain why the updated logic
is right and also refer to the message that has the suggestion. o
The implemmentation is a bit dense to my taste, but looks correct (I
had to think about the comparison to come up with the value of the
$sign, though).
Thanks.
> Signed-off-by: Ben Walton <bdwalton@gmail.com>
> ---
> perl/Git.pm | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/perl/Git.pm b/perl/Git.pm
> index 5649bcc..a56d1e7 100644
> --- a/perl/Git.pm
> +++ b/perl/Git.pm
> @@ -103,7 +103,7 @@ use Error qw(:try);
> use Cwd qw(abs_path cwd);
> use IPC::Open2 qw(open2);
> use Fcntl qw(SEEK_SET SEEK_CUR);
> -use Time::Local qw(timelocal);
> +use Time::Local qw(timegm);
> }
>
>
> @@ -528,8 +528,8 @@ If TIME is not supplied, the current local time is used.
> sub get_tz_offset {
> # some systmes don't handle or mishandle %z, so be creative.
> my $t = shift || time;
> - my $gm = timelocal(gmtime($t));
> - my $sign = qw( + + - )[ $t <=> $gm ];
> + my $gm = timegm(localtime($t));
> + my $sign = qw( + + - )[ $gm <=> $t ];
> return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
> }
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-02-09 22:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-09 21:46 [PATCH 0/3] Fix a portability issue with git-cvsimport Ben Walton
2013-02-09 21:46 ` [PATCH 1/3] Move Git::SVN::get_tz to Git::get_tz_offset Ben Walton
2013-02-09 21:46 ` [PATCH 2/3] Fix get_tz_offset to properly handle DST boundary cases Ben Walton
2013-02-09 22:58 ` Junio C Hamano
2013-02-09 21:46 ` [PATCH 3/3] Avoid non-portable strftime format specifiers in git-cvsimport Ben Walton
2013-02-09 22:20 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).