Intro

In this blog post, we will explore a complex Git command and dissect its components to understand its functionality. The command combines various Git operations to retrieve specific information about Git branches, commits, and associated pull requests.

Note: some CI/CD tools provide a native support to build a nice looking changelog, but here I wanted to show how you can achieve the same by your own command.

Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
git fetch --all \
  && git branch -a --sort=-committerdate | \
  grep 'release' -m2 | \
  tr '\n' '\0' | \ 
  xargs -t bash -c 'git log $0..$1 --first-parent --pretty=format:"%s %C(bold blue)<%an>%C(reset)"' | \
  ggrep -Pio '(?<=\(#)\d*' | \
  sort | \
  tr '\n' '\0' | \
  xargs -0 -n1 gh pr view | \
  grep -E 'author:|title:|url:|jira|WM-' | \
  sed 's/author:[[:space:]]/ - /' | \
  sed 's/title:[[:space:]]/* /' | \
  sed 's/url:[[:space:]]/ - /' | \
  tr -d '\n' | \
  sed 's/*/\n*/g';

Lets brake down this script into several parts:

git fetch --all: This command fetches all remote branches and their associated commits, ensuring that your local repository is up to date with the remote repository.

git branch -a --sort=-committerdate: This command lists all branches, including remote branches, in descending order based on the commit date. It provides a comprehensive view of the branches available.

grep 'release' -m2: This command filters the branch list to include only those branches containing the word ‘release’ and limits the output to the first two matches.

tr '\n' '\0': This command replaces newline characters with null characters. It is used to format the output in a way that can be efficiently processed by subsequent commands.

xargs -t bash -c 'git log $0..$1 --first-parent --pretty=format:"%s %C(bold blue)<%an>%C(reset)"': This command invokes a shell command for each input line, which in this case is the pair of branches obtained from the previous command. It executes git log to retrieve the commit history between the two branches, displaying the commit message, author name, and formatting it with colors.

ggrep -Pio '(?<=\(#)\d*': This command uses Perl-compatible regular expressions to extract the numeric part following a ‘#’ symbol. It identifies the pull request numbers associated with the commits.

Note that I used an additional tool ggrep on Mac (brew install ggrep) to make it work.

sort: This command sorts the extracted pull request numbers in ascending order.

tr '\n' '\0': This command replaces newline characters with null characters, similar to step 4.

xargs -0 -n1 gh pr view: This command invokes the GitHub CLI (gh - brew install gh) to view the details of each pull request specified by the pull request numbers obtained in step 6. It displays information such as the pull request author, title, URL, and related references.

grep -E 'author:|title:|url:|jira': This command filters the output to include only lines containing the specified patterns: author:, title:, url: and jira. This narrows down the information to relevant details.

sed 's/author:[[:space:]]/ - /' | sed 's/title:[[:space:]]/* /' | sed 's/url:[[:space:]]/ - /': These commands replace specific patterns with desired separators (’-’, ‘*’, and ‘-’) to enhance readability and presentation of the output.

tr -d '\n': This command removes any remaining newline characters, ensuring the final output is a single line.

sed 's/*/\n*/g': This command replaces ‘*’ symbols with newline characters, separating each pull request’s information, making it easier to read.

Result

This is what I get by running this script:

1
2
3
4
5
6
7
bash -c git log $0..$1 --first-parent --pretty=format:"%s %C(bold blue)<%an>%C(reset)" remotes/origin/release/2 remotes/origin/release/1

* [#1234] Include a warp engine - user-Alice - https://github.com/Example-Organization/MegaRepo/pull/123
* [#1236] Reduce noise in error logs. - user-Bob - https://github.com/Example-Organization/MegaRepo/pull/126
* [#1238] Fix all the problems in the universe - user-Alice - https://github.com/Example-Organization/MegaRepo/pull/128
* [#1242] Reduce loglevel to Warning - user-Alice - https://github.com/Example-Organization/MegaRepo/pull/142
* [patch/#1255] Ooops.. we droped the prod - user-Bob - https://github.com/Example-Organization/MegaRepo/pull/155

Summary

The provided command is a powerful combination of Git operations and command-line tools. It fetches all remote branches, sorts them by commit date, filters branches with ‘release’ in their name, retrieves commit history between specific branches, extracts associated pull request numbers, sorts them, and finally displays relevant details such as the pull request author, title, and URL. The command allows for efficient monitoring of releases and associated pull requests within a Git repository.