Last active
October 13, 2021 10:39
-
-
Save alfredodeza/252d66dbf4a5c36cfb7b1cb3c0faf445 to your computer and use it in GitHub Desktop.
Append a "Resolves: {tracker}#{ticket-id}" to commit messages based on branch names
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
This is a prepare-commit-msg hook that fill append commit messages with:: | |
Resolves: {TRACKER}#{TICKET-ID} | |
For example a RedHat BZ 0001 would look like:: | |
Correct the syntax error | |
Signed-off-by: Alfredo Deza <adeza@redhat.com> | |
Resolves: rhbz#0001 | |
The requirement is to branch with the right identifier. For the above example | |
the branch name would need to be: rhbz-0001 | |
This hook will split on `-` and use all lower casing to transform the branch | |
into the "Resolves" line. | |
Copy this file to $GITREPOSITORY/.git/hooks/prepare-commit-msg | |
and mark it executable. | |
""" | |
import subprocess | |
import sys | |
import os | |
def which(executable): | |
locations = ( | |
'/usr/local/bin', | |
'/bin', | |
'/usr/bin', | |
'/usr/local/sbin', | |
'/usr/sbin', | |
'/sbin', | |
) | |
for location in locations: | |
executable_path = os.path.join(location, executable) | |
if os.path.exists(executable_path): | |
return executable_path | |
GIT = which('git') | |
def branch_name(): | |
try: | |
name = subprocess.check_output( | |
[GIT, "symbolic-ref", "HEAD"], | |
stderr=subprocess.STDOUT) | |
except Exception as err: | |
if 'fatal: ref HEAD is not a symbolic ref' in err.output: | |
# we are in a rebase or detached head state | |
return '' | |
# This looks like: refs/heads/12345678/my-cool-feature | |
# if we ever get a branch that has '/' in it we are going to have | |
# some issues. | |
return name.split('/')[-1] | |
parts = name.split('/') | |
if len(parts) != 4: | |
raise ValueError("Branch name has '/' in it which is not allowed") | |
branch = parts[-1] | |
return branch | |
def prepend_commit_msg(branch): | |
"""Prepend the commit message with `text`""" | |
msgfile = sys.argv[1] | |
with open(msgfile) as f: | |
contents = f.read() | |
if not branch: | |
return contents | |
try: | |
prefix, ticket_id = branch.split('-') | |
ticket_id = int(ticket_id) | |
except ValueError: | |
# We used to raise here, but if cherry-picking to a different branch | |
# that doesn't comply it would break preventing the cherry-pick. So we | |
# print out the warning, but end up returning the contents. | |
print 'skipping commit msg change: Branch name "%s" does not follow required format: {tracker}-{ID}' % branch # NOQA | |
return contents | |
if prefix == 'wip': | |
# Skip "wip" branches, ie "work in progress" | |
return contents | |
resolves_line = "\nResolves: %s#%s" % (prefix.lower(), ticket_id) | |
with open(msgfile, 'a') as f: | |
# Don't append if it's already there | |
if resolves_line not in contents: | |
f.write(resolves_line) | |
def main(): | |
branch = branch_name().strip().strip('\n') | |
prepend_commit_msg(branch) | |
if __name__ == '__main__': | |
main() |
Can you revise this gist?
Additionally, decode()
is required. These 2 things fix the py2-3 compatibility issues:
name = subprocess.check_output(
[GIT, "symbolic-ref", "HEAD"],
stderr=subprocess.STDOUT)
+ if isinstance(name, bytes):
+ name = name.decode()
This probably can't be a gist anymore and should be an actual repository. Will make some updates to this. Thanks for the hints
@alfredodeza what do you think about merging this into https://github.com/red-hat-storage/downstream-cherry-picker ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Had a
SyntaxError: Missing parentheses in call to 'print'
when runningdownstream-cherry-pick
in my Fedora 29 py3 environment, and fixed it withfuturize -w0 prepare-commit-msg
(trivial fix though):