am: use gmtime() to parse mercurial patch date
authorPaul Tan <pyokagan@gmail.com>
Mon, 15 Jun 2015 11:08:12 +0000 (19:08 +0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Jun 2015 19:34:11 +0000 (12:34 -0700)
An example of the line in a mercurial patch that specifies the date of
the commit would be:

# Date 1433753301 25200

where the first number is the number of seconds since the unix epoch (in
UTC), and the second number is the offset of the timezone, in second s
west of UTC (negative if the timezone is east of UTC).

git-am uses localtime() to break down the first number into its
components (year, month, day, hours, minutes, seconds etc.). However,
the returned components are relative to the user's time zone. As a
result, if the user's time zone does not match the time zone specified
in the patch, the resulting commit will have the wrong author date.

Fix this by using gmtime() instead, which uses UTC instead of the user's
time zone.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-am.sh
t/t4150-am.sh
index 1f4c09e3d434646ebd3b53d1a151a1fb916dffa9..5eec11d5f09c50a83553a8ea5ad763f0d2e44feb 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -343,11 +343,11 @@ split_patches () {
                                elsif (/^\# User /) { s/\# User/From:/ ; print ; }
                                elsif (/^\# Date /) {
                                        my ($hashsign, $str, $time, $tz) = split ;
-                                       $tz = sprintf "%+05d", (0-$tz)/36;
+                                       $tz_str = sprintf "%+05d", (0-$tz)/36;
                                        print "Date: " .
                                              strftime("%a, %d %b %Y %H:%M:%S ",
-                                                      localtime($time))
-                                             . "$tz\n";
+                                                      gmtime($time-$tz))
+                                             . "$tz_str\n";
                                } elsif (/^\# /) { next ; }
                                else {
                                        print "\n", $_ ;
index 7aad8f8e5c10b8dfc223828bceb14f25418b5d31..4beb4b389413e06bd00a884c76c84fe5da2c78c0 100755 (executable)
@@ -122,6 +122,19 @@ test_expect_success setup '
                echo "# This series applies on GIT commit $(git rev-parse first)" &&
                echo "patch"
        } >stgit-series/series &&
+       {
+               echo "# HG changeset patch" &&
+               echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
+               echo "# Date $test_tick 25200" &&
+               echo "#      $(git show --pretty="%aD" -s second)" &&
+               echo "# Node ID $_z40" &&
+               echo "# Parent  $_z40" &&
+               cat msg &&
+               echo &&
+               echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
+               echo &&
+               git diff-tree --no-commit-id -p second
+       } >patch1-hg.eml &&
 
 
        sed -n -e "3,\$p" msg >file &&
@@ -236,6 +249,16 @@ test_expect_success 'am applies stgit series' '
        test_cmp_rev second^ HEAD^
 '
 
+test_expect_success 'am applies hg patch' '
+       rm -fr .git/rebase-apply &&
+       git checkout -f first &&
+       git am patch1-hg.eml &&
+       test_path_is_missing .git/rebase-apply &&
+       git diff --exit-code second &&
+       test_cmp_rev second HEAD &&
+       test_cmp_rev second^ HEAD^
+'
+
 test_expect_success 'setup: new author and committer' '
        GIT_AUTHOR_NAME="Another Thor" &&
        GIT_AUTHOR_EMAIL="a.thor@example.com" &&