am: use gmtime() to parse mercurial patch date

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>

Paul Tan committed Jun 15, 2015 at 19:08 UTC e9dfe253fd489ea171e0478147aeb6eab91dab75
2 files changed +26 -3
git-am.sh
+3 -3
@@ -343,11 +343,11 @@ split_patches () {
343 elsif (/^\# User /) { s/\# User/From:/ ; print ; }
344 elsif (/^\# Date /) {
345 my ($hashsign, $str, $time, $tz) = split ;
346 - $tz = sprintf "%+05d", (0-$tz)/36;
346 + $tz_str = sprintf "%+05d", (0-$tz)/36;
347 print "Date: " .
348 strftime("%a, %d %b %Y %H:%M:%S ",
349 - localtime($time))
350 - . "$tz\n";
349 + gmtime($time-$tz))
350 + . "$tz_str\n";
351 } elsif (/^\# /) { next ; }
352 else {
353 print "\n", $_ ;
t/t4150-am.sh
+23
@@ -122,6 +122,19 @@ test_expect_success setup '
122 echo "# This series applies on GIT commit $(git rev-parse first)" &&
123 echo "patch"
124 } >stgit-series/series &&
125 + {
126 + echo "# HG changeset patch" &&
127 + echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
128 + echo "# Date $test_tick 25200" &&
129 + echo "# $(git show --pretty="%aD" -s second)" &&
130 + echo "# Node ID $_z40" &&
131 + echo "# Parent $_z40" &&
132 + cat msg &&
133 + echo &&
134 + echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
135 + echo &&
136 + git diff-tree --no-commit-id -p second
137 + } >patch1-hg.eml &&
138
139
140 sed -n -e "3,\$p" msg >file &&
@@ -236,6 +249,16 @@ test_expect_success 'am applies stgit series' '
249 test_cmp_rev second^ HEAD^
250 '
251
252 +test_expect_success 'am applies hg patch' '
253 + rm -fr .git/rebase-apply &&
254 + git checkout -f first &&
255 + git am patch1-hg.eml &&
256 + test_path_is_missing .git/rebase-apply &&
257 + git diff --exit-code second &&
258 + test_cmp_rev second HEAD &&
259 + test_cmp_rev second^ HEAD^
260 +'
261 +
262 test_expect_success 'setup: new author and committer' '
263 GIT_AUTHOR_NAME="Another Thor" &&
264 GIT_AUTHOR_EMAIL="a.thor@example.com" &&