diff options
author | George Burgess IV <gbiv@google.com> | 2020-01-10 14:07:45 -0800 |
---|---|---|
committer | George Burgess <gbiv@chromium.org> | 2020-01-11 19:14:02 +0000 |
commit | f414196425a688d7e37b49d47a7a5b4cbdee9148 (patch) | |
tree | 0462e4bdb1c8df4cd225f5b8a338f561984a22fa | |
parent | 70e8bc6297046a2a55a9135a247cb72a0a251e6e (diff) | |
download | toolchain-utils-f414196425a688d7e37b49d47a7a5b4cbdee9148.tar.gz |
git_llvm_rev: handle merge commits more gracefully
llvm grew a relatively large merge commit recently, which broke this
script noticeably.
There's analysis of why this happened in the bug. tl;dr is that
`rev-parse ${sha}~${N}` and `rev-list --count` don't do the same thing
without extra flags.
BUG=chromium:1041016
TEST=Unit tests. A few random runs in my LLVM tree.
Change-Id: I393d1ada842b5f19846d961b403641bc958b191f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1995315
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>
Tested-by: George Burgess <gbiv@chromium.org>
-rwxr-xr-x | llvm_tools/git_llvm_rev.py | 24 | ||||
-rwxr-xr-x | llvm_tools/git_llvm_rev_test.py | 21 |
2 files changed, 42 insertions, 3 deletions
diff --git a/llvm_tools/git_llvm_rev.py b/llvm_tools/git_llvm_rev.py index c8f8a89d..793b56f9 100755 --- a/llvm_tools/git_llvm_rev.py +++ b/llvm_tools/git_llvm_rev.py @@ -129,7 +129,13 @@ def translate_sha_to_rev(llvm_config: LLVMConfig, sha_or_ref: str) -> Rev: if merge_base == base_llvm_sha: result = check_output( - ['git', 'rev-list', '--count', f'{base_llvm_sha}..{sha}'], + [ + 'git', + 'rev-list', + '--count', + '--first-parent', + f'{base_llvm_sha}..{sha}', + ], cwd=llvm_config.dir, ) count = int(result.strip()) @@ -145,7 +151,13 @@ def translate_sha_to_rev(llvm_config: LLVMConfig, sha_or_ref: str) -> Rev: return Rev(branch='master', number=merge_base_number) distance_from_base = check_output( - ['git', 'rev-list', '--count', f'{merge_base}..{sha}'], + [ + 'git', + 'rev-list', + '--count', + '--first-parent', + f'{merge_base}..{sha}', + ], cwd=llvm_config.dir, ) @@ -283,7 +295,13 @@ def translate_rev_to_sha(llvm_config: LLVMConfig, rev: Rev) -> str: commit_number = number - base_revision_number revs_between_str = check_output( - ['git', 'rev-list', '--count', f'{base_sha}..{branch_head_sha}'], + [ + 'git', + 'rev-list', + '--count', + '--first-parent', + f'{base_sha}..{branch_head_sha}', + ], cwd=llvm_config.dir, ) revs_between = int(revs_between_str.strip()) diff --git a/llvm_tools/git_llvm_rev_test.py b/llvm_tools/git_llvm_rev_test.py index ebb654ff..06b83cd1 100755 --- a/llvm_tools/git_llvm_rev_test.py +++ b/llvm_tools/git_llvm_rev_test.py @@ -4,6 +4,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +"""Tests for git_llvm_rev.""" + +from __future__ import print_function + import os import sys import unittest @@ -21,6 +25,7 @@ def get_llvm_config() -> git_llvm_rev.LLVMConfig: class Test(unittest.TestCase): + """Test cases for git_llvm_rev.""" def rev_to_sha_with_round_trip(self, rev: git_llvm_rev.Rev) -> str: config = get_llvm_config() @@ -66,6 +71,22 @@ class Test(unittest.TestCase): self.assertIn('Try updating your tree?', str(r.exception)) + def test_merge_commits_count_as_one_commit_crbug1041079(self) -> None: + # This CL merged _a lot_ of commits in. Verify a few hand-computed + # properties about it. + merge_sha_rev_number = 4496 + git_llvm_rev.base_llvm_revision + sha = self.rev_to_sha_with_round_trip( + git_llvm_rev.Rev(branch='master', number=merge_sha_rev_number)) + self.assertEqual(sha, '0f0d0ed1c78f1a80139a1f2133fad5284691a121') + + sha = self.rev_to_sha_with_round_trip( + git_llvm_rev.Rev(branch='master', number=merge_sha_rev_number - 1)) + self.assertEqual(sha, '6f635f90929da9545dd696071a829a1a42f84b30') + + sha = self.rev_to_sha_with_round_trip( + git_llvm_rev.Rev(branch='master', number=merge_sha_rev_number + 1)) + self.assertEqual(sha, '199700a5cfeedf227619f966aa3125cef18bc958') + # NOTE: The below tests have _zz_ in their name as an optimization. Iterating # on a quick test is painful when these larger tests come before it and take # 7secs to run. Python's unittest module guarantees tests are run in |