git-cvsimport: allow author-specific timezones
authorChris Rorvick <chris@rorvick.com>
Wed, 17 Oct 2012 03:53:29 +0000 (22:53 -0500)
committerJunio C Hamano <gitster@pobox.com>
Wed, 17 Oct 2012 05:23:18 +0000 (22:23 -0700)
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@rorvick.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-cvsimport.txt
git-cvsimport.perl
t/t9604-cvsimport-timestamps.sh [new file with mode: 0755]
t/t9604/cvsroot/.gitattributes [new file with mode: 0644]
t/t9604/cvsroot/CVSROOT/.gitignore [new file with mode: 0644]
t/t9604/cvsroot/module/a,v [new file with mode: 0644]

index 6695ab3b4b93aa7c5829f89ceff936de48e9bc78..98d9881d7e891e4728c09f6536c3506b3688d145 100644 (file)
@@ -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
+       optional timezone:
 +
 ---------
        exon=Andreas Ericsson <ae@op5.se>
-       spawn=Simon Pawn <spawn@frog-pond.org>
+       spawn=Simon Pawn <spawn@frog-pond.org> 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
index 8032f23202ff9a1e8e0fd2a6745021fb8f1fcf71..ceb119d89104648c37bf0bcd770acadf796cd9d1 100755 (executable)
@@ -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@frog-pond.org> 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 (executable)
index 0000000..1fd5142
--- /dev/null
@@ -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=CST6CDT)' '
+
+       TZ=CST6CDT 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 2006-10-29 07:00:01 +0000
+       Rev 15 2006-10-29 06:59:59 +0000
+       Rev 14 2006-04-02 08:00:01 +0000
+       Rev 13 2006-04-02 07:59:59 +0000
+       Rev 12 2005-12-01 00:00:00 +0000
+       Rev 11 2005-11-01 00:00:00 +0000
+       Rev 10 2005-10-01 00:00:00 +0000
+       Rev  9 2005-09-01 00:00:00 +0000
+       Rev  8 2005-08-01 00:00:00 +0000
+       Rev  7 2005-07-01 00:00:00 +0000
+       Rev  6 2005-06-01 00:00:00 +0000
+       Rev  5 2005-05-01 00:00:00 +0000
+       Rev  4 2005-04-01 00:00:00 +0000
+       Rev  3 2005-03-01 00:00:00 +0000
+       Rev  2 2005-02-01 00:00:00 +0000
+       Rev  1 2005-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@domain.org>
+       user2=User Two <user2@domain.org> CST6CDT
+       user3=User Three <user3@domain.org> EST5EDT
+       user4=User Four <user4@domain.org> MST7MDT
+       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 2006-10-29 01:00:01 -0600 User Two
+       Rev 15 2006-10-29 01:59:59 -0500 User Two
+       Rev 14 2006-04-02 03:00:01 -0500 User Two
+       Rev 13 2006-04-02 01:59:59 -0600 User Two
+       Rev 12 2005-11-30 17:00:00 -0700 User Four
+       Rev 11 2005-10-31 19:00:00 -0500 User Three
+       Rev 10 2005-09-30 19:00:00 -0500 User Two
+       Rev  9 2005-09-01 00:00:00 +0000 User One
+       Rev  8 2005-07-31 18:00:00 -0600 User Four
+       Rev  7 2005-06-30 20:00:00 -0400 User Three
+       Rev  6 2005-05-31 19:00:00 -0500 User Two
+       Rev  5 2005-05-01 00:00:00 +0000 User One
+       Rev  4 2005-03-31 17:00:00 -0700 User Four
+       Rev  3 2005-02-28 19:00:00 -0500 User Three
+       Rev  2 2005-01-31 18:00:00 -0600 User Two
+       Rev  1 2005-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 (file)
index 0000000..562b12e
--- /dev/null
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore
new file mode 100644 (file)
index 0000000..3bb9b34
--- /dev/null
@@ -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 (file)
index 0000000..80658c3
--- /dev/null
@@ -0,0 +1,264 @@
+head   1.16;
+access;
+symbols;
+locks; strict;
+comment        @# @;
+
+
+1.16
+date   2006.10.29.07.00.01;    author user2;   state Exp;
+branches;
+next   1.15;
+
+1.15
+date   2006.10.29.06.59.59;    author user2;   state Exp;
+branches;
+next   1.14;
+
+1.14
+date   2006.04.02.08.00.01;    author user2;   state Exp;
+branches;
+next   1.13;
+
+1.13
+date   2006.04.02.07.59.59;    author user2;   state Exp;
+branches;
+next   1.12;
+
+1.12
+date   2005.12.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.11;
+
+1.11
+date   2005.11.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.10;
+
+1.10
+date   2005.10.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.9;
+
+1.9
+date   2005.09.01.00.00.00;    author user1;   state Exp;
+branches;
+next   1.8;
+
+1.8
+date   2005.08.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.7;
+
+1.7
+date   2005.07.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.6;
+
+1.6
+date   2005.06.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.5;
+
+1.5
+date   2005.05.01.00.00.00;    author user1;   state Exp;
+branches;
+next   1.4;
+
+1.4
+date   2005.04.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.3;
+
+1.3
+date   2005.03.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.2;
+
+1.2
+date   2005.02.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.1;
+
+1.1
+date   2005.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
+@