Hi Sandra, hello world,
Sandra Loosemore wrote:
I have created the devel/omp/gcc-15 (aka "OG15") branch, ...
For previous branches we'd been using ChangeLog.omp files paralleling
the normal ChangeLog files, that were updated manually and committed
with the corresponding patch. In preparing the current patch set,
though, I found that
...
corresponding ChangeLog.omp patch hunks.
...
It seems like the easiest solution is just to extend the mechanism used
to manage ChangeLogs automatically on master and release branches, which
is what the attached patch attempts to do.
It seems to me as if your approach causes merge issues. Namely, as
git_update_version.py updates DATESTAMP and ChangeLog, there is a
clash with the updates to the same files on the GCC 15 branch, when
merging.
Additionally, I am not really sure that nightly bumps, updating usually
only the DATESTAMP, are really useful.
How about the attached patch? With it, running
./contrib/gcc-changelog/git_update_version.py \
--suffix '.omp' -c \
--exclude-branch=origin/releases/gcc-15 \
--last-commit=0b76b58a5875d519f95a5af661fb64e42a42ed8e
works where --last-commit could be, e.g.,
git log -1 --pretty=format:%H --grep "ChangeLog.omp Bump"
This could be wrapped in some script to (e.g. committed to this
the branch of interest) to handle the arguments and, possibly,
commit - with the possibility to skip commits if only
DATESTAMP<suffix> has changed.
This could then be run manually - or as someone's cronjob.
* * *
What do you - and anyone else - think about this approach?
Or about the original one? Or has yet another good alternative
or additional idea?
Tobias
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.
contrib/gcc-changelog/git_repository.py | 7 +++-
contrib/gcc-changelog/git_update_version.py | 55 +++++++++++++++++++++++------
2 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/contrib/gcc-changelog/git_repository.py b/contrib/gcc-changelog/git_repository.py
index 2b2efffe77a..dc658af83b9 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 8e36c745836..4412c974791 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,
@@ -162,14 +187,24 @@ def update_current_branch(ref_name=None):
else:
logging.info('DATESTAMP unchanged')
+
if args.ignore is not None:
for item in args.ignore:
ignored_commits.update(set(i for i in re.split(r'\s*,\s*|\s+', item)))
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 +217,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('')