CVS patchsets are imported with timestamps having an offset of +0000 (UTC). The cvs-authors file is already used to translate the CVS username to full name and email in the corresponding commit. Extend this file to support an optional timezone for calculating a user- specific timestamp offset. Signed-off-by: Chris Rorvick <chris@xxxxxxxxxxx> --- Cleaned up unit tests and added more detail to documentation. Unit test is inherently platform dependent due to dependency on zoneinfo database. Is there a way to improve this situation? Documentation/git-cvsimport.txt | 8 +- git-cvsimport.perl | 22 ++- t/t9604-cvsimport-timestamps.sh | 71 ++++++++++ t/t9604/cvsroot/.gitattributes | 1 + t/t9604/cvsroot/CVSROOT/.gitignore | 2 + t/t9604/cvsroot/module/a,v | 265 +++++++++++++++++++++++++++++++++++++ 6 files changed, 362 insertions(+), 7 deletions(-) create mode 100755 t/t9604-cvsimport-timestamps.sh create mode 100644 t/t9604/cvsroot/.gitattributes create mode 100644 t/t9604/cvsroot/CVSROOT/.gitignore create mode 100644 t/t9604/cvsroot/module/a,v diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt index 6695ab3..9ea8bb5 100644 --- a/Documentation/git-cvsimport.txt +++ b/Documentation/git-cvsimport.txt @@ -137,17 +137,19 @@ This option can be used several times to provide several detection regexes. -A <author-conv-file>:: CVS by default uses the Unix username when writing its commit logs. Using this option and an author-conv-file - in this format + maps the name recorded in CVS to author name, e-mail and + and optional timezone: + --------- exon=Andreas Ericsson <ae@xxxxxx> - spawn=Simon Pawn <spawn@xxxxxxxxxxxxx> + spawn=Simon Pawn <spawn@xxxxxxxxxxxxx> America/Chicago --------- + 'git cvsimport' will make it appear as those authors had their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly -all along. +all along. If a timezone is specified, GIT_AUTHOR_DATE will +have the corresponding offset applied. + For convenience, this data is saved to `$GIT_DIR/cvs-authors` each time the '-A' option is provided and read from that same diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 8032f23..ceb119d 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -31,7 +31,7 @@ $SIG{'PIPE'}="IGNORE"; $ENV{'TZ'}="UTC"; our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_R); -my (%conv_author_name, %conv_author_email); +my (%conv_author_name, %conv_author_email, %conv_author_tz); sub usage(;$) { my $msg = shift; @@ -59,6 +59,14 @@ sub read_author_info($) { $conv_author_name{$user} = $2; $conv_author_email{$user} = $3; } + # or with an optional timezone: + # spawn=Simon Pawn <spawn@xxxxxxxxxxxxx> America/Chicago + elsif (m/^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*(\S+?)\s*$/) { + $user = $1; + $conv_author_name{$user} = $2; + $conv_author_email{$user} = $3; + $conv_author_tz{$user} = $4; + } # However, we also read from CVSROOT/users format # to ease migration. elsif (/^(\w+):(['"]?)(.+?)\2\s*$/) { @@ -84,7 +92,9 @@ sub write_author_info($) { die("Failed to open $file for writing: $!"); foreach (keys %conv_author_name) { - print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>\n"; + print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>"; + print $f " $conv_author_tz{$_}" if ($conv_author_tz{$_}); + print $f "\n"; } close ($f); } @@ -795,7 +805,7 @@ sub write_tree () { return $tree; } -my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); +my ($patchset,$date,$author_name,$author_email,$author_tz,$branch,$ancestor,$tag,$logmsg); my (@old,@new,@skipped,%ignorebranch,@commit_revisions); # commits that cvsps cannot place anywhere... @@ -844,7 +854,9 @@ sub commit { } } - my $commit_date = strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)); + $ENV{'TZ'}=$author_tz; + my $commit_date = strftime("%s %z", localtime($date)); + $ENV{'TZ'}="UTC"; $ENV{GIT_AUTHOR_NAME} = $author_name; $ENV{GIT_AUTHOR_EMAIL} = $author_email; $ENV{GIT_AUTHOR_DATE} = $commit_date; @@ -945,12 +957,14 @@ while (<CVS>) { } $state=3; } elsif ($state == 3 and s/^Author:\s+//) { + $author_tz = "UTC"; s/\s+$//; if (/^(.*?)\s+<(.*)>/) { ($author_name, $author_email) = ($1, $2); } elsif ($conv_author_name{$_}) { $author_name = $conv_author_name{$_}; $author_email = $conv_author_email{$_}; + $author_tz = $conv_author_tz{$_} if ($conv_author_tz{$_}); } else { $author_name = $author_email = $_; } diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh new file mode 100755 index 0000000..7e2fe2c --- /dev/null +++ b/t/t9604-cvsimport-timestamps.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +test_description='git cvsimport timestamps' +. ./lib-cvs.sh + +setup_cvs_test_repository t9604 + +test_expect_success 'check timestamps are UTC (TZ=America/Chicago)' ' + + TZ=America/Chicago git cvsimport -p"-x" -C module-1 module && + git cvsimport -p"-x" -C module-1 module && + ( + cd module-1 && + git log --format="%s %ai" + ) >actual-1 && + cat >expect-1 <<-EOF && + Rev 16 2011-11-06 07:00:01 +0000 + Rev 15 2011-11-06 06:59:59 +0000 + Rev 14 2011-03-13 08:00:01 +0000 + Rev 13 2011-03-13 07:59:59 +0000 + Rev 12 2010-12-01 00:00:00 +0000 + Rev 11 2010-11-01 00:00:00 +0000 + Rev 10 2010-10-01 00:00:00 +0000 + Rev 9 2010-09-01 00:00:00 +0000 + Rev 8 2010-08-01 00:00:00 +0000 + Rev 7 2010-07-01 00:00:00 +0000 + Rev 6 2010-06-01 00:00:00 +0000 + Rev 5 2010-05-01 00:00:00 +0000 + Rev 4 2010-04-01 00:00:00 +0000 + Rev 3 2010-03-01 00:00:00 +0000 + Rev 2 2010-02-01 00:00:00 +0000 + Rev 1 2010-01-01 00:00:00 +0000 + EOF + test_cmp actual-1 expect-1 +' + +test_expect_success 'check timestamps with author-specific timezones' ' + + cat >cvs-authors <<-EOF && + user1=User One <user1@xxxxxxxxxx> + user2=User Two <user2@xxxxxxxxxx> America/Chicago + user3=User Three <user3@xxxxxxxxxx> Australia/Sydney + user4=User Four <user4@xxxxxxxxxx> Asia/Shanghai + EOF + git cvsimport -p"-x" -A cvs-authors -C module-2 module && + ( + cd module-2 && + git log --format="%s %ai %an" + ) >actual-2 && + cat >expect-2 <<-EOF && + Rev 16 2011-11-06 01:00:01 -0600 User Two + Rev 15 2011-11-06 01:59:59 -0500 User Two + Rev 14 2011-03-13 03:00:01 -0500 User Two + Rev 13 2011-03-13 01:59:59 -0600 User Two + Rev 12 2010-12-01 08:00:00 +0800 User Four + Rev 11 2010-11-01 11:00:00 +1100 User Three + Rev 10 2010-09-30 19:00:00 -0500 User Two + Rev 9 2010-09-01 00:00:00 +0000 User One + Rev 8 2010-08-01 08:00:00 +0800 User Four + Rev 7 2010-07-01 10:00:00 +1000 User Three + Rev 6 2010-05-31 19:00:00 -0500 User Two + Rev 5 2010-05-01 00:00:00 +0000 User One + Rev 4 2010-04-01 08:00:00 +0800 User Four + Rev 3 2010-03-01 11:00:00 +1100 User Three + Rev 2 2010-01-31 18:00:00 -0600 User Two + Rev 1 2010-01-01 00:00:00 +0000 User One + EOF + test_cmp actual-2 expect-2 +' + +test_done diff --git a/t/t9604/cvsroot/.gitattributes b/t/t9604/cvsroot/.gitattributes new file mode 100644 index 0000000..562b12e --- /dev/null +++ b/t/t9604/cvsroot/.gitattributes @@ -0,0 +1 @@ +* -whitespace diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore new file mode 100644 index 0000000..3bb9b34 --- /dev/null +++ b/t/t9604/cvsroot/CVSROOT/.gitignore @@ -0,0 +1,2 @@ +history +val-tags diff --git a/t/t9604/cvsroot/module/a,v b/t/t9604/cvsroot/module/a,v new file mode 100644 index 0000000..7165de7 --- /dev/null +++ b/t/t9604/cvsroot/module/a,v @@ -0,0 +1,265 @@ +head 1.16; +access; +symbols; +locks; strict; +comment @# @; + + +1.16 +date 2011.11.06.07.00.01; author user2; state Exp; +branches; +next 1.15; + +1.15 +date 2011.11.06.06.59.59; author user2; state Exp; +branches; +next 1.14; + +1.14 +date 2011.03.13.08.00.01; author user2; state Exp; +branches; +next 1.13; + +1.13 +date 2011.03.13.07.59.59; author user2; state Exp; +branches; +next 1.12; + +1.12 +date 2010.12.01.00.00.00; author user4; state Exp; +branches; +next 1.11; + +1.11 +date 2010.11.01.00.00.00; author user3; state Exp; +branches; +next 1.10; + +1.10 +date 2010.10.01.00.00.00; author user2; state Exp; +branches; +next 1.9; + +1.9 +date 2010.09.01.00.00.00; author user1; state Exp; +branches; +next 1.8; + +1.8 +date 2010.08.01.00.00.00; author user4; state Exp; +branches; +next 1.7; + +1.7 +date 2010.07.01.00.00.00; author user3; state Exp; +branches; +next 1.6; + +1.6 +date 2010.06.01.00.00.00; author user2; state Exp; +branches; +next 1.5; + +1.5 +date 2010.05.01.00.00.00; author user1; state Exp; +branches; +next 1.4; + +1.4 +date 2010.04.01.00.00.00; author user4; state Exp; +branches; +next 1.3; + +1.3 +date 2010.03.01.00.00.00; author user3; state Exp; +branches; +next 1.2; + +1.2 +date 2010.02.01.00.00.00; author user2; state Exp; +branches; +next 1.1; + +1.1 +date 2010.01.01.00.00.00; author user1; state Exp; +branches; +next ; + + +desc +@@ + + +1.16 +log +@Rev 16 +@ +text +@Rev 16 +@ + + +1.15 +log +@Rev 15 +@ +text +@d1 1 +a1 1 +Rev 15 +@ + + +1.14 +log +@Rev 14 +@ +text +@d1 1 +a1 1 +Rev 14 +@ + + +1.13 +log +@Rev 13 +@ +text +@d1 1 +a1 1 +Rev 13 +@ + + +1.12 +log +@Rev 12 +@ +text +@d1 1 +a1 1 +Rev 12 +@ + + +1.11 +log +@Rev 11 +@ +text +@d1 1 +a1 1 +Rev 11 +@ + + +1.10 +log +@Rev 10 +@ +text +@d1 1 +a1 1 +Rev 10 +@ + + +1.9 +log +@Rev 9 +@ +text +@d1 1 +a1 1 +Rev 9 +@ + + +1.8 +log +@Rev 8 +@ +text +@d1 1 +a1 1 +Rev 8 +@ + + +1.7 +log +@Rev 7 +@ +text +@d1 1 +a1 1 +Rev 7 +@ + + +1.6 +log +@Rev 6 +@ +text +@d1 1 +a1 1 +Rev 6 +@ + + +1.5 +log +@Rev 5 +@ +text +@d1 1 +a1 1 +Rev 5 +@ + + +1.4 +log +@Rev 4 +@ +text +@d1 1 +a1 1 +Rev 4 +@ + + +1.3 +log +@Rev 3 +@ +text +@d1 1 +a1 1 +Rev 3 +@ + + +1.2 +log +@Rev 2 +@ +text +@d1 1 +a1 1 +Rev 2 +@ + + +1.1 +log +@Rev 1 +@ +text +@d1 1 +a1 1 +Rev 1 +@ + -- 1.8.0.rc1.19.gbecacc0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html