https://gcc.gnu.org/g:dbd927be10e2daf0c995f43cd28cf1d1883cac42
commit dbd927be10e2daf0c995f43cd28cf1d1883cac42 Author: Tobias Burnus <tbur...@baylibre.com> Date: Thu May 15 00:34:05 2025 +0000 git_update_version.py: Support vendor-branch version bumps contrib/ChangeLog: * gcc-changelog/git_repository.py (parse_git_revisions): Optional exclude_branch_name argument * gcc-changelog/git_update_version.py: Add --suffix, --exclude-branch and --last-commit to handle vendor branches. Diff: --- contrib/gcc-changelog/git_repository.py | 7 +++- contrib/gcc-changelog/git_update_version.py | 54 +++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/contrib/gcc-changelog/git_repository.py b/contrib/gcc-changelog/git_repository.py index 2b2efffe77af..dc658af83b9b 100755 --- a/contrib/gcc-changelog/git_repository.py +++ b/contrib/gcc-changelog/git_repository.py @@ -31,7 +31,8 @@ except ImportError: from git_commit import GitCommit, GitInfo, decode_path -def parse_git_revisions(repo_path, revisions, ref_name=None): +def parse_git_revisions(repo_path, revisions, ref_name=None, + exclude_branch_name=None): repo = Repo(repo_path) def commit_to_info(commit): @@ -67,6 +68,8 @@ def parse_git_revisions(repo_path, revisions, ref_name=None): except ValueError: return None + exclude_branch = (repo.commit(exclude_branch_name) + if exclude_branch_name is not None else None) parsed_commits = [] if '..' in revisions: commits = list(repo.iter_commits(revisions)) @@ -74,6 +77,8 @@ def parse_git_revisions(repo_path, revisions, ref_name=None): commits = [repo.commit(revisions)] for commit in commits: + if exclude_branch is not None and repo.is_ancestor(commit, exclude_branch): + continue git_commit = GitCommit(commit_to_info(commit.hexsha), commit_to_info_hook=commit_to_info, ref_name=ref_name) diff --git a/contrib/gcc-changelog/git_update_version.py b/contrib/gcc-changelog/git_update_version.py index 8e36c7458367..ec5951ca2686 100755 --- a/contrib/gcc-changelog/git_update_version.py +++ b/contrib/gcc-changelog/git_update_version.py @@ -23,6 +23,8 @@ import datetime import logging import os import re +import shutil +import sys from git import Repo @@ -62,14 +64,14 @@ def read_timestamp(path): return f.read() -def prepend_to_changelog_files(repo, folder, git_commit, add_to_git): +def prepend_to_changelog_files(repo, folder, git_commit, add_to_git, suffix): if not git_commit.success: logging.info(f"While processing {git_commit.info.hexsha}:") for error in git_commit.errors: logging.info(error) raise AssertionError() for entry, output in git_commit.to_changelog_entries(use_commit_ts=True): - full_path = os.path.join(folder, entry, 'ChangeLog') + full_path = os.path.join(folder, entry, 'ChangeLog' + suffix) logging.info('writing to %s' % full_path) if os.path.exists(full_path): with open(full_path) as f: @@ -89,7 +91,10 @@ active_refs = ['master', 'releases/gcc-12', 'releases/gcc-13', 'releases/gcc-14'] parser = argparse.ArgumentParser(description='Update DATESTAMP and generate ' - 'ChangeLog entries') + 'ChangeLog entries', + epilog='For vendor branches, only; e.g: -s .suffix ' + '-x releases/gcc-15 -l ' + '`git log -1 --pretty=format:%H --grep "Vendor Bump"`') parser.add_argument('-g', '--git-path', default='.', help='Path to git repository') parser.add_argument('-p', '--push', action='store_true', @@ -102,18 +107,31 @@ parser.add_argument('-c', '--current', action='store_true', help='Modify current branch (--push argument is ignored)') parser.add_argument('-i', '--ignore', action='append', help='list of commits to ignore') +# Useful only for vendor branches +parser.add_argument('-s', '--suffix', default="", + help='suffix for the ChangeLog and DATESTAMP files') +parser.add_argument('-l', '--last-commit', + help='hash of the last DATESTAMP commit') +parser.add_argument('-x', '--exclude-branch', + help='commits to be ignored if in this branch') args = parser.parse_args() repo = Repo(args.git_path) origin = repo.remotes['origin'] -def update_current_branch(ref_name=None): +def update_current_branch(ref_name=None, suffix="", last_commit_ref=None, + exclude_branch=None): commit = repo.head.commit commit_count = 1 + last_commit = (repo.commit(last_commit_ref) + if last_commit_ref is not None else None) while commit: - if (commit.author.email == 'gccad...@gcc.gnu.org' - and commit.message.strip() == 'Daily bump.'): + if last_commit is not None: + if last_commit == commit: + break + elif (commit.author.email == 'gccad...@gcc.gnu.org' + and commit.message.strip() == 'Daily bump.'): break # We support merge commits but only with 2 parensts assert len(commit.parents) <= 2 @@ -122,6 +140,12 @@ def update_current_branch(ref_name=None): logging.info('%d revisions since last Daily bump' % commit_count) datestamp_path = os.path.join(args.git_path, 'gcc/DATESTAMP') + if suffix != "": + if not os.path.exists(datestamp_path + suffix): + logging.info('Create DATESTAMP%s by copying DATESTAMP' % suffix) + shutil.copyfile(datestamp_path, datestamp_path + suffix) + datestamp_path += suffix + if (read_timestamp(datestamp_path) != current_timestamp or args.dry_mode or args.current): head = repo.head.commit @@ -131,11 +155,12 @@ def update_current_branch(ref_name=None): if len(head.parents) == 2: head = head.parents[1] commits = parse_git_revisions(args.git_path, '%s..%s' - % (commit.hexsha, head.hexsha), ref_name) + % (commit.hexsha, head.hexsha), ref_name, + exclude_branch) commits = [c for c in commits if c.info.hexsha not in ignored_commits] for git_commit in reversed(commits): prepend_to_changelog_files(repo, args.git_path, git_commit, - not args.dry_mode) + not args.dry_mode, args.suffix) if args.dry_mode: diff = repo.git.diff('HEAD') patch = os.path.join(args.dry_mode, @@ -168,8 +193,17 @@ if args.ignore is not None: if args.current: logging.info('=== Working on the current branch ===') - update_current_branch() + if args.suffix != "" and args.last_commit is None: + logging.error('--suffix requires --last-commit') + sys.exit(1) + update_current_branch(None, args.suffix, args.last_commit, + args.exclude_branch) else: + if args.suffix != "" or args.last_commit is not None \ + or update_current_branch is not None: + logging.error('--suffix, --last-commit and --exclude-branch ' + 'require --current') + sys.exit(1) for ref in origin.refs: assert ref.name.startswith('origin/') name = ref.name[len('origin/'):] @@ -182,7 +216,7 @@ else: branch.checkout() origin.pull(rebase=True) logging.info('branch pulled and checked out') - update_current_branch(name) + update_current_branch(name, args.suffix) assert not repo.index.diff(None) logging.info('branch is done') logging.info('')