2

I'm running from the terminal in OSX, and given a git log format like:

* 58dbb08 Joe Blogs 5 weeks ago | [ABC-123] Commit message contents 
* 5a9c5e1 Jane Doe 3 weeks ago | Commit Contents with XYZ-987 jira ticket number
* 6070ee0 Some Person 3 weeks ago | Commit which references [MNO-456, MNO-999]

I'd like to generate a list in the CLI (using git log, grep, sort, sed) on OSX which would print out the log in such a format:

  58dbb08 │ ABC-123
  5a9c5e1 │ XYZ-987
  6070ee0 │ MNO-456, MNO-999
──────────│──────────────────────
   ꜛ sha  │  ꜛ jira tickets

The purpose is so our QA can extract a list of Jira Tickets which were referenced inside of git commits, and then easily find the associated commit/ticket by looking through the list

I've got little experience in sedand having difficulties understanding the ways of extracting and replacing patterns, then printing only the matched patterns. I've read the docs, but some of the language is unfamiliar considering I rarely touch unix/regex, and I couldn't decipher how to extract multiple patterns and replace un-matched strings.


What I'm working with currently;

git log --oneline 7.2.0..HEAD | 
    grep -iEo "([a-f0-9]{7})(.*[a-zA-Z0-9]{2,6}-[0-9]{1,4})+" | 
    sort -u | 
    sed -n "s/\([a-zA-Z0-9]\{2,7\}-[0-9]\{1,4\}\)/, \1 /pg"

which gets me to;

58dbb08 Joe Blogs 5 weeks ago | [, ABC-123
5a9c5e1 Jane Doe 3 weeks ago | Commit Contents with , XYZ-987 
6070ee0 Some Person 3 weeks ago | Commit which references [, MNO-456 , , MNO-999

which is close, but I can't get rid of the stuff I don't need

1 Answer 1

1

So, I punished my little brain, pushed and came up with an ugly solution.

I don't think it's the best, so I'd still appreciate/accept any help and improvements!

git log 7.2.0..HEAD --oneline | 
    grep -iEo "([a-f0-9]{7})(.*[a-zA-Z0-9]{2,6}-[0-9]{1,4})+" | 
    sort -u | 
    sed -E $'s/([a-f0-9]{7}|[a-zA-Z0-9]{2,7}-[0-9]{1,4})/ \\\n\\1\\\n/g' | 
    grep -iEo "([a-f0-9]{7}|[a-zA-Z0-9]{2,6}-[0-9]{1,4})+" | 
    tr '\n' ' ' | 
    sed -E $'s/([a-f0-9]{7})/\\\n\\1 →/g' | 
    sed -E 's/([a-zA-Z0-9]{2,7}-[0-9]{1,4})/\1,/g' | 
    sed -E 's/(..)$//'

this command splits the matched expressions across multiple lines using sedto insert some \n, then it greps the expressions I need, again, and only keeps them. Then finally it goes back and replaces those \n with the and , characters respectively, then trimming the last ,.

I end up with:

58dbb08 → ABC-123
5a9c5e1 → XYZ-987
6070ee0 → MNO-456, MNO-999

I find this to be decently fast on a log size of less than 200 commits... it's purpose is for helping to generate some issue-lists in the release notes, so it shouldn't be much more than that. But again; any speed/quality improvements are well received!

1
  • Most (all?) sed versions allow to chain several commands, so you could write e.g. sed -E -e 's/one/two/g' -e 's/three/four/g', to do the replacements in one go. That saves a few command runs. Or you could write the mangling in Perl, that allows you to use more familiar program logic (variables, conditionals, and so on).
    – vonbrand
    Feb 10, 2020 at 3:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.