From a6695810bb193a83ec31d0471b9594af43d1a464 Mon Sep 17 00:00:00 2001 From: Andrii Shyshkalov Date: Tue, 6 Dec 2016 17:47:09 +0100 Subject: [PATCH] git cl replacing gnumbd: set correct committer timestamp. BUG=642493 R=sergiyb@chromium.org Change-Id: I5d8588f2b6f30368188aecab2d2c462a11aa6883 Reviewed-on: https://chromium-review.googlesource.com/414369 Commit-Queue: Andrii Shyshkalov Reviewed-by: Sergiy Byelozyorov Reviewed-by: Michael Achenbach Reviewed-by: Robbie Iannucci --- git_cl.py | 26 ++++++++++++++++++++++++-- tests/git_cl_test.py | 15 ++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/git_cl.py b/git_cl.py index 4b91f5d55..5a81169bf 100755 --- a/git_cl.py +++ b/git_cl.py @@ -228,6 +228,26 @@ def _git_set_branch_config_value(key, value, branch=None, **kwargs): RunGit(args, **kwargs) +def _get_committer_timestamp(commit): + """Returns unix timestamp as integer of a committer in a commit. + + Commit can be whatever git show would recognize, such as HEAD, sha1 or ref. + """ + # Git also stores timezone offset, but it only affects visual display, + # actual point in time is defined by this timestamp only. + return int(RunGit(['show', '-s', '--format=%ct', commit]).strip()) + + +def _git_amend_head(message, committer_timestamp): + """Amends commit with new message and desired committer_timestamp. + + Sets committer timezone to UTC. + """ + env = os.environ.copy() + env['GIT_COMMITTER_DATE'] = '%d+0000' % committer_timestamp + return RunGit(['commit', '--amend', '-m', message], env=env) + + def add_git_similarity(parser): parser.add_option( '--similarity', metavar='SIM', type=int, action='store', @@ -4501,8 +4521,10 @@ def SendUpstream(parser, args, cmd): parent_msg = RunGit(['show', '-s', '--format=%B', merge_base]).strip() commit_desc.update_with_git_number_footers(merge_base, parent_msg, branch) - # TODO(tandrii): timestamp handling is missing here. - RunGitSilent(['commit', '--amend', '-m', commit_desc.description]) + # Ensure timestamps are monotonically increasing. + timestamp = max(1 + _get_committer_timestamp(merge_base), + _get_committer_timestamp('HEAD')) + _git_amend_head(commit_desc.description, timestamp) change_desc = ChangeDescription(commit_desc.description) # If gnumbd is sitll ON and we ultimately push to branch with # pending_prefix, gnumbd will modify footers we've just inserted with diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py index 8c397ec02..9177b55d6 100755 --- a/tests/git_cl_test.py +++ b/tests/git_cl_test.py @@ -1066,9 +1066,17 @@ class TestGitCl(TestCase): git_cl.main(['land']) def test_land_rietveld_git_numberer(self): - self._land_rietveld_common() + self._land_rietveld_common(debug_stdout=False) self.mock(git_cl, 'ShouldGenerateGitNumberFooters', lambda *a: self._mocked_call(['ShouldGenerateGitNumberFooters'])) + + # Special mocks to check validity of timestamp. + original_git_amend_head = git_cl._git_amend_head + def _git_amend_head_mock(msg, tstamp): + self._mocked_call(['git_amend_head committer timestamp', tstamp]) + return original_git_amend_head(msg, tstamp) + self.mock(git_cl, '_git_amend_head', _git_amend_head_mock) + self.calls += [ ((['git', 'config', 'rietveld.pending-ref-prefix'],), CERR1), ((['ShouldGenerateGitNumberFooters'],), True), @@ -1078,7 +1086,12 @@ class TestGitCl(TestCase): '\n' 'Cr-Commit-Position: refs/heads/master@{#543}\n' 'Cr-Branched-From: refs/svn/2014@{#2208}'), + ((['git', 'show', '-s', '--format=%ct', 'fake_ancestor_sha'],), + '1480022355'), # Committer's unix timestamp. + ((['git', 'show', '-s', '--format=%ct', 'HEAD'],), + '1480024000'), + ((['git_amend_head committer timestamp', 1480024000],), None), ((['git', 'commit', '--amend', '-m', 'Issue: 123\n\nR=john@chromium.org\n' '\n'