mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add a bunch of useful scripts for planning releases.
(cherry picked from commit ac7c192e1b)
This commit is contained in:
committed by
Antonio Sanchez
parent
0f80c3d7e5
commit
4f240eee3f
128
scripts/git_commit_mrs_and_issues.py
Normal file
128
scripts/git_commit_mrs_and_issues.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""Search for MRs and issues related to a list of commits."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
|
||||
def find_cherry_pick_source(commit_hash: str):
|
||||
"""
|
||||
For a given commit hash, find the original commit it was cherry-picked from.
|
||||
|
||||
Args:
|
||||
commit_hash: The commit hash to inspect.
|
||||
|
||||
Returns:
|
||||
The full hash of the original commit if found, otherwise None.
|
||||
"""
|
||||
try:
|
||||
# Use 'git show' to get the full commit message for the given hash.
|
||||
# The '-s' flag suppresses the diff output.
|
||||
# The '--format=%B' flag prints only the raw commit body/message.
|
||||
commit_message = subprocess.check_output(
|
||||
["git", "show", "-s", "--format=%B", commit_hash.strip()],
|
||||
text=True,
|
||||
stderr=subprocess.PIPE,
|
||||
).strip()
|
||||
|
||||
# This regex looks for the specific line Git adds during a cherry-pick.
|
||||
# It captures the full 40-character SHA-1 hash.
|
||||
cherry_pick_pattern = re.compile(
|
||||
r"\(cherry picked from commit ([a-f0-9]{40})\)"
|
||||
)
|
||||
|
||||
# Search the entire commit message for the pattern.
|
||||
match = cherry_pick_pattern.search(commit_message)
|
||||
|
||||
if match:
|
||||
# If a match is found, return the captured group (the original commit hash).
|
||||
return match.group(1)
|
||||
else:
|
||||
return None
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
# This error occurs if the git command fails, e.g., for an invalid hash.
|
||||
print(
|
||||
f"Error processing commit '{commit_hash.strip()}': {e.stderr.strip()}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return None
|
||||
except FileNotFoundError:
|
||||
# This error occurs if the 'git' command itself isn't found.
|
||||
print(
|
||||
"Error: 'git' command not found. Please ensure Git is installed and in your PATH.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to read commit hashes from stdin and process them.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="A script to download all MRs from GitLab matching specified criteria."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--merge_requests_file",
|
||||
type=str,
|
||||
required=True,
|
||||
help="JSON file containing all the merge request information extracted via the GitLab API.",
|
||||
)
|
||||
|
||||
# E.g. git log --pretty=%H 3e819d83bf52abda16bb53565f6801df40d071f1..3.4.1
|
||||
parser.add_argument(
|
||||
"--commits",
|
||||
required=True,
|
||||
help="List of commits, '-' for stdin.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
mrs = []
|
||||
with open(args.merge_requests_file, "r") as file:
|
||||
mrs = json.load(file)
|
||||
mrs_by_commit = {}
|
||||
|
||||
if args.commits == "-":
|
||||
commit_hashes = sys.stdin.readlines()
|
||||
else:
|
||||
with open(args.commits, "r") as file:
|
||||
commit_hashes = file.readlines()
|
||||
|
||||
# Arrange commits by SHA.
|
||||
for mr in mrs:
|
||||
for key in ["sha", "merge_commit_sha", "squash_commit_sha"]:
|
||||
sha = mr[key]
|
||||
if sha:
|
||||
mrs_by_commit[sha] = mr
|
||||
|
||||
# Find the MRs and issues related to each commit.
|
||||
info = {}
|
||||
for sha in commit_hashes:
|
||||
sha = sha.strip()
|
||||
if not sha:
|
||||
continue
|
||||
|
||||
# If a cherry-pick, extract the original hash.
|
||||
sha = find_cherry_pick_source(sha) or sha
|
||||
mr = mrs_by_commit.get(sha)
|
||||
|
||||
commit_info = {}
|
||||
if mr:
|
||||
commit_info["merge_request"] = mr["iid"]
|
||||
commit_info["related_issues"] = [
|
||||
issue["iid"] for issue in mr["related_issues"]
|
||||
]
|
||||
commit_info["closes_issues"] = [
|
||||
issue["iid"] for issue in mr["closes_issues"]
|
||||
]
|
||||
|
||||
info[sha] = commit_info
|
||||
|
||||
print(json.dumps(info, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user