aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Burgess IV <gbiv@google.com>2020-01-10 14:07:45 -0800
committerGeorge Burgess <gbiv@chromium.org>2020-01-11 19:14:02 +0000
commitf414196425a688d7e37b49d47a7a5b4cbdee9148 (patch)
tree0462e4bdb1c8df4cd225f5b8a338f561984a22fa
parent70e8bc6297046a2a55a9135a247cb72a0a251e6e (diff)
downloadtoolchain-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-xllvm_tools/git_llvm_rev.py24
-rwxr-xr-xllvm_tools/git_llvm_rev_test.py21
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