Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run command on git log output per commit using bash

On our project we use git commit messages to add certain metadata to our commits. Most obvious ones are JIRA ids but there are more. What I am trying to do is to process commit messages to extract this data and do something with it but am having trouble with how to run a script per one message and not per line. For example here is what I am trying to do:

# Extract JIRA issue ids for last 5 commits
git log --format=format:%B --no-merges -n5 | while read line ; do echo $line | grep -oP "(?<=JIRA: )[^ ]+"; done

#Output 
456
128
756

this does work in this case but the problem is that using while here is run per line and not per one message of log output so grep is ran too many times. This becomes a problem when I try to do something like:

 # Extract JIRA issue id and Gerrit change id from last 5 commits
 git log --format=format:%B --no-merges -n5 | while read line ; do echo $line | grep -oP "(?<=Change-Id: )[^ ]+|(?<=JIRA: )[^ ]+"; done

#Output
Ida3e220cdfa80ace5164109916fb5015d7aaaaaa
Ic4eed79f8acf5bf56f848bf543168e4ac9aaaaaa
456
I51dc621df6f54539f05053f6e036cc97a7aaaaaa
128
Ic04fa3de9b5e453358292bc7b965139707aaaaaa
756
I453a99155dacdc693ee28f248e92a6ccc8aaaaaa

As you can see each match from grep is printed on seperate lien but I would like to get output in the format:

Change-Id JIRA

Ida3e220cdfa80ace5164109916fb5015d7aaaaaa
Ida3e220cdfa80ace5164109916fb5015d7aaaaaa 128 Ic04fa3de9b5e453358292bc7b965139707aaaaaa 756

Do note that some commits don't have Jira Id and this should be reflected by empty string or " " like shown for first commit.

I also tried using

# Extract JIRA ids using bash function and xargs
git log --format=format:%B --no-merges -n5 | xargs -L1 gitLogExtractJIRA

But this gives me the "xargs: gitLogExtractJIRA: No such file or directory" error

I also looked into using https://git-scm.com/docs/git-for-each-ref especially the --shell subcommand but think it is not applicable in this case since I am iterating over log messages not refs. I might be wrong on this thou since I haven't used for-each-ref much.

So my question is how to run a bash function (or inline group of commands) per one message of git log output and not per line?

like image 331
Igor Čordaš Avatar asked Dec 08 '25 15:12

Igor Čordaš


1 Answers

It's not an answer to the general question of running commands on each message in the output, but for the specific issue at hand, git log can extract the required meta-information using git-interpret-trailers. It can extract lines that follow the format "key:value", and add them to the log message

If your commit message looks like this:

Commit message subject

This is an example commit message.
Change-Id: I123123y51241
Jira: J-123

Then you could use something like:

$ git log --format="%(trailers:key=Change-Id,separator=%x2C,valueonly) %(trailers:key=Jira,separator=%x2C,valueonly)" -n1
> I123123y51241 J-123

See the section on trailers in https://git-scm.com/docs/git-log for further information.

like image 150
sonicwave Avatar answered Dec 11 '25 05:12

sonicwave



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!