hppa: Fix handling of unscaled index addresses on HP-UX
[official-gcc.git] / contrib / gcc-changelog / git_update_version.py
blobec06fc965f8aff79a976ed9520aabab9ef9160ae
1 #!/usr/bin/env python3
3 # Copyright (C) 2020-2024 Free Software Foundation, Inc.
5 # This file is part of GCC.
7 # GCC is free software; you can redistribute it and/or modify it under
8 # the terms of the GNU General Public License as published by the Free
9 # Software Foundation; either version 3, or (at your option) any later
10 # version.
12 # GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 # for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GCC; see the file COPYING3. If not see
19 # <http://www.gnu.org/licenses/>.
21 import argparse
22 import datetime
23 import logging
24 import os
25 import re
27 from git import Repo
29 from git_repository import parse_git_revisions
31 current_timestamp = datetime.datetime.now().strftime('%Y%m%d\n')
33 # Skip the following commits, they cannot be correctly processed
34 ignored_commits = {
35 'c2be82058fb40f3ae891c68d185ff53e07f14f45',
36 '04a040d907a83af54e0a98bdba5bfabc0ef4f700',
37 '2e96b5f14e4025691b57d2301d71aa6092ed44bc',
38 '3ab5c8cd03d92bf4ec41e351820349d92fbc40c4',
39 '86d8e0c0652ef5236a460b75c25e4f7093cc0651',
40 'e4cba49413ca429dc82f6aa2e88129ecb3fdd943',
41 '1957bedf29a1b2cc231972aba680fe80199d5498',
42 '040e5b0edbca861196d9e2ea2af5e805769c8d5d',
43 '8057f9aa1f7e70490064de796d7a8d42d446caf8',
44 '109f1b28fc94c93096506e3df0c25e331cef19d0',
45 '39f81924d88e3cc197fc3df74204c9b5e01e12f7'}
47 FORMAT = '%(asctime)s:%(levelname)s:%(name)s:%(message)s'
48 logging.basicConfig(level=logging.INFO, format=FORMAT,
49 handlers=[
50 logging.FileHandler('/tmp/git_update_version.txt'),
51 logging.StreamHandler()
55 def read_timestamp(path):
56 with open(path) as f:
57 return f.read()
60 def prepend_to_changelog_files(repo, folder, git_commit, add_to_git):
61 if not git_commit.success:
62 logging.info(f"While processing {git_commit.info.hexsha}:")
63 for error in git_commit.errors:
64 logging.info(error)
65 raise AssertionError()
66 for entry, output in git_commit.to_changelog_entries(use_commit_ts=True):
67 full_path = os.path.join(folder, entry, 'ChangeLog')
68 logging.info('writing to %s' % full_path)
69 if os.path.exists(full_path):
70 with open(full_path) as f:
71 content = f.read()
72 else:
73 content = ''
74 with open(full_path, 'w+') as f:
75 f.write(output)
76 if content:
77 f.write('\n\n')
78 f.write(content)
79 if add_to_git:
80 repo.git.add(full_path)
83 active_refs = ['master',
84 'releases/gcc-12', 'releases/gcc-13', 'releases/gcc-14']
86 parser = argparse.ArgumentParser(description='Update DATESTAMP and generate '
87 'ChangeLog entries')
88 parser.add_argument('-g', '--git-path', default='.',
89 help='Path to git repository')
90 parser.add_argument('-p', '--push', action='store_true',
91 help='Push updated active branches')
92 parser.add_argument('-d', '--dry-mode',
93 help='Generate patch for ChangeLog entries and do it'
94 ' even if DATESTAMP is unchanged; folder argument'
95 ' is expected')
96 parser.add_argument('-c', '--current', action='store_true',
97 help='Modify current branch (--push argument is ignored)')
98 parser.add_argument('-i', '--ignore', action='append',
99 help='list of commits to ignore')
100 args = parser.parse_args()
102 repo = Repo(args.git_path)
103 origin = repo.remotes['origin']
106 def update_current_branch(ref_name=None):
107 commit = repo.head.commit
108 commit_count = 1
109 while commit:
110 if (commit.author.email == 'gccadmin@gcc.gnu.org'
111 and commit.message.strip() == 'Daily bump.'):
112 break
113 # We support merge commits but only with 2 parensts
114 assert len(commit.parents) <= 2
115 commit = commit.parents[-1]
116 commit_count += 1
118 logging.info('%d revisions since last Daily bump' % commit_count)
119 datestamp_path = os.path.join(args.git_path, 'gcc/DATESTAMP')
120 if (read_timestamp(datestamp_path) != current_timestamp
121 or args.dry_mode or args.current):
122 head = repo.head.commit
123 # if HEAD is a merge commit, start with second parent
124 # (branched that is being merged into the current one)
125 assert len(head.parents) <= 2
126 if len(head.parents) == 2:
127 head = head.parents[1]
128 commits = parse_git_revisions(args.git_path, '%s..%s'
129 % (commit.hexsha, head.hexsha), ref_name)
130 commits = [c for c in commits if c.info.hexsha not in ignored_commits]
131 for git_commit in reversed(commits):
132 prepend_to_changelog_files(repo, args.git_path, git_commit,
133 not args.dry_mode)
134 if args.dry_mode:
135 diff = repo.git.diff('HEAD')
136 patch = os.path.join(args.dry_mode,
137 branch.name.split('/')[-1] + '.patch')
138 with open(patch, 'w+') as f:
139 f.write(diff)
140 logging.info('branch diff written to %s' % patch)
141 repo.git.checkout(force=True)
142 else:
143 # update timestamp
144 logging.info('DATESTAMP will be changed:')
145 with open(datestamp_path, 'w+') as f:
146 f.write(current_timestamp)
147 repo.git.add(datestamp_path)
148 if not args.current:
149 repo.index.commit('Daily bump.')
150 logging.info('commit is done')
151 if args.push:
152 try:
153 repo.git.push('origin', branch)
154 logging.info('branch is pushed')
155 except Exception:
156 logging.exception('git push failed')
157 else:
158 logging.info('DATESTAMP unchanged')
160 if args.ignore is not None:
161 for item in args.ignore:
162 ignored_commits.update(set(i for i in re.split(r'\s*,\s*|\s+', item)))
164 if args.current:
165 logging.info('=== Working on the current branch ===')
166 update_current_branch()
167 else:
168 for ref in origin.refs:
169 assert ref.name.startswith('origin/')
170 name = ref.name[len('origin/'):]
171 if name in active_refs:
172 if name in repo.branches:
173 branch = repo.branches[name]
174 else:
175 branch = repo.create_head(name, ref).set_tracking_branch(ref)
176 logging.info('=== Working on: %s ===' % branch)
177 branch.checkout()
178 origin.pull(rebase=True)
179 logging.info('branch pulled and checked out')
180 update_current_branch(name)
181 assert not repo.index.diff(None)
182 logging.info('branch is done')
183 logging.info('')