]>
git.ipfire.org Git - thirdparty/gcc.git/blob - contrib/gcc-changelog/git_update_version.py
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
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
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/>.
28 from git_repository
import parse_git_revisions
30 current_timestamp
= datetime
.datetime
.now().strftime('%Y%m%d\n')
32 # Skip the following commits, they cannot be correctly processed
34 'c2be82058fb40f3ae891c68d185ff53e07f14f45',
35 '04a040d907a83af54e0a98bdba5bfabc0ef4f700',
36 '2e96b5f14e4025691b57d2301d71aa6092ed44bc',
37 '3ab5c8cd03d92bf4ec41e351820349d92fbc40c4',
38 '86d8e0c0652ef5236a460b75c25e4f7093cc0651',
39 'e4cba49413ca429dc82f6aa2e88129ecb3fdd943',
40 '1957bedf29a1b2cc231972aba680fe80199d5498',
41 '040e5b0edbca861196d9e2ea2af5e805769c8d5d',
42 '8057f9aa1f7e70490064de796d7a8d42d446caf8')
44 FORMAT
= '%(asctime)s:%(levelname)s:%(name)s:%(message)s'
45 logging
.basicConfig(level
=logging
.INFO
, format
=FORMAT
,
47 logging
.FileHandler('/tmp/git_update_version.txt'),
48 logging
.StreamHandler()
52 def read_timestamp(path
):
57 def prepend_to_changelog_files(repo
, folder
, git_commit
, add_to_git
):
58 if not git_commit
.success
:
59 for error
in git_commit
.errors
:
61 raise AssertionError()
62 for entry
, output
in git_commit
.to_changelog_entries(use_commit_ts
=True):
63 full_path
= os
.path
.join(folder
, entry
, 'ChangeLog')
64 logging
.info('writing to %s' % full_path
)
65 if os
.path
.exists(full_path
):
66 with
open(full_path
) as f
:
70 with
open(full_path
, 'w+') as f
:
76 repo
.git
.add(full_path
)
79 active_refs
= ['master',
80 'releases/gcc-11', 'releases/gcc-12', 'releases/gcc-13']
82 parser
= argparse
.ArgumentParser(description
='Update DATESTAMP and generate '
84 parser
.add_argument('-g', '--git-path', default
='.',
85 help='Path to git repository')
86 parser
.add_argument('-p', '--push', action
='store_true',
87 help='Push updated active branches')
88 parser
.add_argument('-d', '--dry-mode',
89 help='Generate patch for ChangeLog entries and do it'
90 ' even if DATESTAMP is unchanged; folder argument'
92 parser
.add_argument('-c', '--current', action
='store_true',
93 help='Modify current branch (--push argument is ignored)')
94 args
= parser
.parse_args()
96 repo
= Repo(args
.git_path
)
97 origin
= repo
.remotes
['origin']
100 def update_current_branch(ref_name
):
101 commit
= repo
.head
.commit
104 if (commit
.author
.email
== 'gccadmin@gcc.gnu.org'
105 and commit
.message
.strip() == 'Daily bump.'):
107 # We support merge commits but only with 2 parensts
108 assert len(commit
.parents
) <= 2
109 commit
= commit
.parents
[-1]
112 logging
.info('%d revisions since last Daily bump' % commit_count
)
113 datestamp_path
= os
.path
.join(args
.git_path
, 'gcc/DATESTAMP')
114 if (read_timestamp(datestamp_path
) != current_timestamp
115 or args
.dry_mode
or args
.current
):
116 head
= repo
.head
.commit
117 # if HEAD is a merge commit, start with second parent
118 # (branched that is being merged into the current one)
119 assert len(head
.parents
) <= 2
120 if len(head
.parents
) == 2:
121 head
= head
.parents
[1]
122 commits
= parse_git_revisions(args
.git_path
, '%s..%s'
123 % (commit
.hexsha
, head
.hexsha
), ref_name
)
124 commits
= [c
for c
in commits
if c
.info
.hexsha
not in IGNORED_COMMITS
]
125 for git_commit
in reversed(commits
):
126 prepend_to_changelog_files(repo
, args
.git_path
, git_commit
,
129 diff
= repo
.git
.diff('HEAD')
130 patch
= os
.path
.join(args
.dry_mode
,
131 branch
.name
.split('/')[-1] + '.patch')
132 with
open(patch
, 'w+') as f
:
134 logging
.info('branch diff written to %s' % patch
)
135 repo
.git
.checkout(force
=True)
138 logging
.info('DATESTAMP will be changed:')
139 with
open(datestamp_path
, 'w+') as f
:
140 f
.write(current_timestamp
)
141 repo
.git
.add(datestamp_path
)
143 repo
.index
.commit('Daily bump.')
144 logging
.info('commit is done')
147 repo
.git
.push('origin', branch
)
148 logging
.info('branch is pushed')
150 logging
.exception('git push failed')
152 logging
.info('DATESTAMP unchanged')
156 logging
.info('=== Working on the current branch ===')
157 update_current_branch()
159 for ref
in origin
.refs
:
160 assert ref
.name
.startswith('origin/')
161 name
= ref
.name
[len('origin/'):]
162 if name
in active_refs
:
163 if name
in repo
.branches
:
164 branch
= repo
.branches
[name
]
166 branch
= repo
.create_head(name
, ref
).set_tracking_branch(ref
)
167 logging
.info('=== Working on: %s ===' % branch
)
169 origin
.pull(rebase
=True)
170 logging
.info('branch pulled and checked out')
171 update_current_branch(name
)
172 assert not repo
.index
.diff(None)
173 logging
.info('branch is done')