DMCApps
DMCApps

Reputation: 2168

Git hook to update commit message with data from an API

I am attempting to update a git commit with details from our ticketing API. I would like to grab the title of the ticket number that the developer adds to a git commit and update the commit with that title.

e.g.

git add /some/file

git commit -am "#[id]
Did some work
Other stuff I Did"

At this point I would like to get the Id they used, call my API in bash and then append to the commit the title so the resulting commit message is actually "#[id] Ticket Title".

I am wondering what hook I can use to do this. I'm not looking to get help on how to write the hook but more so what git hook I would use and if I need to alter the commit after it's made (say I need to do it on post commit). What would the git commit --amend look like?

Thanks in advance

Upvotes: 1

Views: 2382

Answers (3)

Lovato
Lovato

Reputation: 2310

This does not solve directly your problem, but perhaps it can help in implementing the suggestions listed above.

I wrote a small tool to help git hooks management.

https://pypi.org/project/hooks4git/

Upvotes: 1

kelvin
kelvin

Reputation: 1614

As mentioned, you can use git hooks to manipulate the commit message.

I don't believe I can use either of those as I need the user to enter message.

The commit-msg hook fires after the user writes the message and exits the editor but before the commit is made.

From the githooks man page:

commit-msg
    This hook is invoked by git-commit(1) and git-merge(1), and can be
    bypassed with the --no-verify option. It takes a single parameter, the
    name of the file that holds the proposed commit log message. Exiting
    with a non-zero status causes the command to abort.

    The hook is allowed to edit the message file in place, and can be used
    to normalize the message into some project standard format. It can also
    be used to refuse the commit after inspecting the message file.

    The default commit-msg hook, when enabled, detects duplicate
    "Signed-off-by" lines, and aborts the commit if one is found.

So to replace the title of the message, you could use something like this:

#!/bin/sh

file="$1"
ticket_id="$(sed -E -ne '1s/^#([0-9]+)/\1/p' <"$file")"
ticket_title="$(call_my_api "ticket_id")"

sed -i.bak -e "1s/.*/#$ticket_id $ticket_title/" "$file"

Note: The suffix (e.g: .bak) is required for portability.


Even though that works, I would recommend against it, or when asking for an overview of the branch, git log --oneline would give you this:

#123 Foo is returning error 418
#123 Foo is returning error 418
#123 Foo is returning error 418
#123 Foo is returning error 418
#123 Foo is returning error 418

This would be specially bad on a branch with dozens of commits related to one ticket.

Instead, you could leave the commit message title to describe what the commit does, and merely append the ticket title to the end of the message:

#!/bin/sh

file="$1"
ticket_id="$(sed -E -ne '1s/^#\[([0-9]+)\]/\1/p' <"$file")"
ticket_title="$(call_my_api "ticket_id")"

printf -- '\n%s\n' "$ticket_title" >>"$file"

Our team generally uses part of the ticket title in the commit message body to add some context and it works well enough.


Update: Found a similar attempt (but based on the branch name instead):

How to provide a prepared git commit message?

Upvotes: 0

phd
phd

Reputation: 94541

You can choose between prepare-commit-msg and commit-msg. The former is called before git commit opens an editor to edit commit message, the latter is called after. Both are supposed to edit the message file (the path to it passed as the first parameter) in place. The first one is always called, the second can be bypassed with git commit --no-verify. Error code on exit aborts commit.

Upvotes: 3

Related Questions