Merge pull request #133 from tomice/master

Add stat by author per timezone functionality
This commit is contained in:
Lukáš Mešťan
2021-06-15 13:52:05 +02:00
committed by GitHub
4 changed files with 640 additions and 512 deletions

142
README.md
View File

@@ -5,7 +5,7 @@
>
> Any git repository may contain tons of information about commits, contributors, and files. Extracting this information is not always trivial, mostly because there are a gadzillion options to a gadzillion git commands I dont think there is a single person alive who knows them all. Probably not even [Linus Torvalds](https://github.com/torvalds) himself :).
![mainMenuScreenshot](https://user-images.githubusercontent.com/8818630/118892347-c7375c80-b8ce-11eb-84f0-6e04bb65f850.png)
![mainMenuScreenshot](https://user-images.githubusercontent.com/8818630/121750502-8223d600-cada-11eb-94bc-470be4e22ba4.png)
## Table of Contents
@@ -53,9 +53,9 @@
## Screenshots
![commitsByWeekdayScreenshot](https://user-images.githubusercontent.com/8818630/118892353-c8688980-b8ce-11eb-96be-a48e1b7dc73b.png)
![commitsByWeekdayScreenshot](https://user-images.githubusercontent.com/8818630/121750517-8819b700-cada-11eb-99a0-a72942822da5.png)
![commitsByHourScreenshot](https://user-images.githubusercontent.com/8818630/118892355-c9012000-b8ce-11eb-991c-ac0e2a335cd6.png)
![commitsByHourScreenshot](https://user-images.githubusercontent.com/8818630/121750525-8c45d480-cada-11eb-8054-78716ce6623c.png)
## Usage
@@ -92,42 +92,51 @@ git quick-stats <optional-command-to-execute-directly>
Possible arguments in short and long form:
```bash
-r, --suggest-reviewers
show the best people to contact to review code
-T, --detailed-git-stats
give a detailed list of git stats
-R, --git-stats-by-branch
see detailed list of git stats by branch
-V, --csv-output-by-branch
output daily stats by branch in CSV format
-d, --commits-per-day
displays a list of commits per day
-m, --commits-by-month
displays a list of commits per month
-w, --commits-by-weekday
displays a list of commits per weekday
-o, --commits-by-hour
displays a list of commits per hour
-A, --commits-by-author-by-hour
displays a list of commits per hour by author
-a, --commits-per-author
displays a list of commits per author
-S, --my-daily-stats
see your current daily stats
-C, --contributors
see a list of everyone who contributed to the repo
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-j, --json-output
save git log as a JSON formatted file to a specified area
-h, -?, --help
display this help text in the terminal
GENERATE OPTIONS
-T, --detailed-git-stats
give a detailed list of git stats
-R, --git-stats-by-branch
see detailed list of git stats by branch
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-S, --my-daily-stats
see your current daily stats
-V, --csv-output-by-branch
output daily stats by branch in CSV format
-j, --json-output
save git log as a JSON formatted file to a specified area
LIST OPTIONS
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-C, --contributors
see a list of everyone who contributed to the repo
-a, --commits-per-author
displays a list of commits per author
-d, --commits-per-day
displays a list of commits per day
-m, --commits-by-month
displays a list of commits per month
-w, --commits-by-weekday
displays a list of commits per weekday
-o, --commits-by-hour
displays a list of commits per hour
-A, --commits-by-author-by-hour
displays a list of commits per hour by author
-z, --commits-by-timezone
displays a list of commits per timezone
-Z, --commits-by-author-by-timezone
displays a list of commits per timezone by author
SUGGEST OPTIONS
-r, --suggest-reviewers
show the best people to contact to review code
-h, -?, --help
display this help text in the terminal
```
### Git log since and until
@@ -151,7 +160,7 @@ export _GIT_LIMIT=20
### Git log options
You can set _GIT_LOG_OPTIONS for [git log options](https://git-scm.com/docs/git-log#_options):
You can set `_GIT_LOG_OPTIONS` for [git log options](https://git-scm.com/docs/git-log#_options):
```bash
export _GIT_LOG_OPTIONS="--ignore-all-space --ignore-blank-lines"
@@ -173,7 +182,7 @@ export _GIT_PATHSPEC=':!package-lock.json'
### Git merge view strategy
You can set the variable `_GIT_MERGE_VIEW` to enable merge commits to be part of the stats by setting `_GIT_MERGE_VIEW` to `enable`. You can also choose to only show merge commits by setting `_GIT_MERGE_VIEW` to `exclusive`. Default is to not show merge commits. These work similar to git's built-in `--merges` and `--no-merges` log options.
You can set the variable `_GIT_MERGE_VIEW` to enable merge commits to be part of the stats by setting `_GIT_MERGE_VIEW` to `enable`. You can also choose to only show merge commits by setting `_GIT_MERGE_VIEW` to `exclusive`. Default is to not show merge commits. These work similar to git's built-in `--merges` and `--no-merges` log options.
```bash
export _GIT_MERGE_VIEW="enable"
@@ -182,7 +191,7 @@ export _GIT_MERGE_VIEW="exclusive"
### Git branch
You can set the variable `_GIT_BRANCH` to set the branch of the stats. Works with commands `--git-stats-by-branch` and `--csv-output-by-branch`.
You can set the variable `_GIT_BRANCH` to set the branch of the stats. Works with commands `--git-stats-by-branch` and `--csv-output-by-branch`.
```bash
export _GIT_BRANCH="master"
@@ -193,10 +202,10 @@ export _GIT_BRANCH="master"
You can change to the legacy color scheme by toggling the variable `_MENU_THEME` between `default` and `legacy`
```bash
export _MENU_THEME=legacy
export _MENU_THEME="legacy"
```
![legacyThemeScreenshot](https://user-images.githubusercontent.com/8818630/118892356-c9012000-b8ce-11eb-8fd8-1b71e0ca6466.png)
![legacyThemeScreenshot](https://user-images.githubusercontent.com/8818630/121750530-8f40c500-cada-11eb-808c-5f5fb81801d2.png)
## Installation
@@ -255,7 +264,25 @@ You can use the Docker image provided:
## System requirements
* An OS with a Bash shell
* Tools we use: awk ; basename ; cat ; column ; echo ; git ; grep ; head ; seq ; sort ; tput ; tr ; uniq ; wc
* Tools we use:
```bash
awk
basename
cat
column
echo
git
grep
head
printf
seq
sort
tput
tr
uniq
wc
```
### Dependencies
@@ -318,25 +345,26 @@ MIT see [LICENSE][] for the full license text.
## Contributors
This project exists thanks to all the people who contribute.
<a href="https://github.com/arzzen/git-quick-stats/graphs/contributors"><img src="https://opencollective.com/git-quick-stats/contributors.svg?width=890&button=false" /></a>
[![contributors](https://opencollective.com/git-quick-stats/contributors.svg?width=890&button=false)](https://github.com/arzzen/git-quick-stats/graphs/contributors)
### Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/git-quick-stats#backer)]
<a href="https://opencollective.com/git-quick-stats#backers" target="_blank"><img src="https://opencollective.com/git-quick-stats/backers.svg?width=890"></a>
[![backers](https://opencollective.com/git-quick-stats/backers.svg?width=890)](https://opencollective.com/git-quick-stats#backers)
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/git-quick-stats#sponsor)]
<a href="https://opencollective.com/git-quick-stats/sponsor/0/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/0/avatar.svg?v=1"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/1/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/2/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/3/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/4/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/5/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/6/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/7/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/8/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/git-quick-stats/sponsor/9/website" target="_blank"><img src="https://opencollective.com/git-quick-stats/sponsor/9/avatar.svg"></a>
[![sponsor0](https://opencollective.com/git-quick-stats/sponsor/0/avatar.svg?v=1)](https://opencollective.com/git-quick-stats/sponsor/0/website)
[![sponsor1](https://opencollective.com/git-quick-stats/sponsor/1/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/1/website)
[![sponsor2](https://opencollective.com/git-quick-stats/sponsor/2/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/2/website)
[![sponsor3](https://opencollective.com/git-quick-stats/sponsor/3/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/3/website)
[![sponsor4](https://opencollective.com/git-quick-stats/sponsor/4/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/4/website)
[![sponsor5](https://opencollective.com/git-quick-stats/sponsor/5/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/5/website)
[![sponsor6](https://opencollective.com/git-quick-stats/sponsor/6/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/6/website)
[![sponsor7](https://opencollective.com/git-quick-stats/sponsor/7/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/7/website)
[![sponsor8](https://opencollective.com/git-quick-stats/sponsor/8/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/8/website)
[![sponsor9](https://opencollective.com/git-quick-stats/sponsor/9/avatar.svg)](https://opencollective.com/git-quick-stats/sponsor/9/website)

View File

@@ -4,6 +4,9 @@
################################################################################
# GLOBALS AND SHELL OPTIONS
# NOTE: Should we look into allowing for a customized config file so that the
# user does not have to customize their shell's run command file or
# manually override these every time they want to change them?
set -o nounset
set -o errexit
@@ -69,15 +72,18 @@ fi
# Set the legacy theme by typing "export _MENU_THEME=legacy"
_theme="${_MENU_THEME:=default}"
################################################################################
# HELPER AND MENU FUNCTIONS
################################################################################
# DESC: Checks to make sure the user has the appropriate utilities installed
# ARGS: None
# OUTS: None
################################################################################
checkUtils() {
function checkUtils() {
readonly MSG="not found. Please make sure this is installed and in PATH."
readonly UTILS="awk basename cat column echo git grep head seq sort tput \
tr uniq wc"
readonly UTILS="awk basename cat column echo git grep head printf seq sort \
tput tr uniq wc"
for u in $UTILS
do
@@ -85,12 +91,23 @@ checkUtils() {
done
}
################################################################################
# DESC: Prints a formatted message of the selected option by the user to stdout
# ARGS: $* (required): String to print (usually provided by other functions)
# OUTS: None
################################################################################
function optionPicked() {
local msg=${*:-"Error: No message passed"}
echo -e "${msg}\n"
}
################################################################################
# DESC: Help information printed to stdout during non-interactive mode
# ARGS: None
# OUTS: None
################################################################################
usage() {
function usage() {
readonly PROGRAM=$(basename "$0")
echo "
@@ -108,15 +125,31 @@ DESCRIPTION
This program allows you to see detailed information about a git repository.
OPTIONS
-r, --suggest-reviewers
show the best people to contact to review code
GENERATE OPTIONS
-T, --detailed-git-stats
give a detailed list of git stats
-R, --git-stats-by-branch
see detailed list of git stats by branch
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-S, --my-daily-stats
see your current daily stats
-V, --csv-output-by-branch
output daily stats by branch in CSV format
-j, --json-output
save git log as a JSON formatted file to a specified area
LIST OPTIONS
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-C, --contributors
see a list of everyone who contributed to the repo
-a, --commits-per-author
displays a list of commits per author
-d, --commits-per-day
displays a list of commits per day
-m, --commits-by-month
@@ -127,22 +160,14 @@ OPTIONS
displays a list of commits per hour
-A, --commits-by-author-by-hour
displays a list of commits per hour by author
-a, --commits-per-author
displays a list of commits per author
-S, --my-daily-stats
see your current daily stats
-C, --contributors
see a list of everyone who contributed to the repo
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-j, --json-output
save git log as a JSON formatted file to a specified area
-z, --commits-by-timezone
displays a list of commits per timezone
-Z, --commits-by-author-by-timezone
displays a list of commits per timezone by author
SUGGEST OPTIONS
-r, --suggest-reviewers
show the best people to contact to review code
-h, -?, --help
display this help text in the terminal
@@ -170,7 +195,8 @@ ADDITIONAL USAGE
# ARGS: None
# OUTS: $opt: Option selected by the user based on menu choice
################################################################################
showMenu() {
function showMenu() {
# These are "global" and can be overriden from users if so desired
NORMAL=$(tput sgr0)
CYAN=$(tput setaf 6)
BOLD=$(tput bold)
@@ -215,116 +241,18 @@ showMenu() {
printf %b "${NUMS} 13)${TEXT} Git commits per month\\n"
printf %b "${NUMS} 14)${TEXT} Git commits per weekday\\n"
printf %b "${NUMS} 15)${TEXT} Git commits per hour\\n"
printf %b "${NUMS} 16)${TEXT} Git commits by author per hour\\n"
printf %b "${NUMS} 16)${TEXT} Git commits per hour by author\\n"
printf %b "${NUMS} 17)${TEXT} Git commits per timezone\\n"
printf %b "${NUMS} 18)${TEXT} Git commits per timezone by author\\n"
printf %b "\\n${TITLES} Suggest:\\n"
printf %b "${NUMS} 17)${TEXT} Code reviewers (based on git history)\\n"
printf %b "${NUMS} 19)${TEXT} Code reviewers (based on git history)\\n"
printf %b "\\n${HELP_TXT}Please enter a menu option or ${EXIT_TXT}press Enter to exit.\\n"
printf %b "${TEXT}> ${NORMAL}"
read -r opt
}
################################################################################
# DESC: Prints a formatted message of the selected option by the user to stdout
# ARGS: $* (required): String to print (usually provided by other functions)
# OUTS: None
################################################################################
function optionPicked() {
local msg=${*:-"Error: No message passed"}
echo -e "${msg}\n"
}
################################################################################
# DESC: Shows detailed contribution stats per author by parsing every commit in
# the repo and outputting their contribution stats
# ARGS: $branch (optional): Users can specify an alternative branch instead of
# the current default one
# OUTS: None
################################################################################
function csvOutput() {
local is_branch_existing=false
local branch="${1:-}"
local _branch=""
# Check if requesting for a specific branch
if [[ -n "${branch}" ]]; then
# Check if branch exist
if [[ $(git show-ref refs/heads/"${branch}") ]] ; then
is_branch_existing=true
_branch="${branch}"
else
is_branch_existing=false
_branch=""
fi
fi
echo "author,insertions,insertions_per,deletions,deletions_per,files,files_per,commits,commits_per,lines_changed,lines_changed_per"
git -c log.showSignature=false log ${_branch} --use-mailmap $_merges --numstat \
--pretty="format:commit %H%nAuthor: %aN <%aE>%nDate: %ad%n%n%w(0,4,4)%B%n" \
"$_since" "$_until" $_log_options $_pathspec | LC_ALL=C awk '
function printStats(author) {
printf "%s,", author
if(more["total"] > 0) {
printf "%d,%.0f%%,", more[author], \
(more[author] / more["total"] * 100)
}
if(less["total"] > 0) {
printf "%d,%.0f%%,", less[author], \
(less[author] / less["total"] * 100)
}
if(file["total"] > 0) {
printf "%d,%.0f%%,", file[author], \
(file[author] / file["total"] * 100)
}
if(commits["total"] > 0) {
printf "%d,%.0f%%,", commits[author], \
(commits[author] / commits["total"] * 100)
}
if (first[author] != "") {
if ( ((more["total"] + less["total"]) * 100) > 0) {
printf "%d,", more[author] + less[author]
printf "%.0f%%\n", ((more[author] + less[author]) / \
(more["total"] + less["total"]) * 100)
}
}
}
/^Author:/ {
$1 = ""
author = $0
commits[author] += 1
commits["total"] += 1
}
/^Date:/ {
$1="";
first[author] = substr($0, 2)
if(last[author] == "" ) { last[author] = first[author] }
}
/^[0-9]/ {
more[author] += $1
less[author] += $2
file[author] += 1
more["total"] += $1
less["total"] += $2
file["total"] += 1
}
END {
for (author in commits) {
if (author != "total") {
printStats(author)
}
}
}'
}
# FUNCTIONS FOR GENERATING STATS
################################################################################
# DESC: Shows detailed contribution stats per author by parsing every commit in
@@ -354,7 +282,8 @@ function detailedGitStats() {
if [[ "${is_branch_existing}" && -n "${_branch}" ]]; then
optionPicked "Contribution stats (by author) on ${_branch} branch:"
elif [[ -n "${branch}" && -z "${_branch}" ]]; then
optionPicked "Branch ${branch} does not exist.\nContribution stats (by author) on the current branch:"
optionPicked "Branch ${branch} does not exist."
optionPicked "Contribution stats (by author) on the current branch:"
else
optionPicked "Contribution stats (by author) on the current branch:"
fi
@@ -434,253 +363,6 @@ function detailedGitStats() {
}'
}
################################################################################
# DESC: Displays the authors in order of total contribution to the repo
# ARGS: None
# OUTS: None
################################################################################
function suggestReviewers() {
optionPicked "Suggested code reviewers (based on git history):"
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--pretty=%aN $_log_options $_pathspec | head -n 100 | sort | uniq -c | sort -nr | LC_ALL=C awk '
{ args[NR] = $0; }
END {
for (i = 1; i <= NR; ++i) {
printf "%s\n", args[i]
}
}' | column -t -s,
}
################################################################################
# DESC: Saves the git log output in a JSON format
# ARGS: $json_path (required): Path to where the file is saved
# OUTS: A JSON formatted file
################################################################################
function jsonOutput() {
optionPicked "Output log saved to file at: ${json_path}/output.json"
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" $_log_options \
--pretty=format:'{%n "commit": "%H",%n "abbreviated_commit": "%h",%n "tree": "%T",%n "abbreviated_tree": "%t",%n "parent": "%P",%n "abbreviated_parent": "%p",%n "refs": "%D",%n "encoding": "%e",%n "subject": "%s",%n "sanitized_subject_line": "%f",%n "body": "%b",%n "commit_notes": "%N",%n "author": {%n "name": "%aN",%n "email": "%aE",%n "date": "%aD"%n },%n "commiter": {%n "name": "%cN",%n "email": "%cE",%n "date": "%cD"%n }%n},' \
| sed "$ s/,$//" \
| sed ':a;N;$!ba;s/\r\n\([^{]\)/\\n\1/g' \
| awk 'BEGIN { print("[") } { print($0) } END { print("]") }' \
> "${json_path}/output.json"
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per month
# ARGS: None
# OUTS: None
################################################################################
function commitsByMonth() {
optionPicked "Git commits by month:"
echo -e "\tmonth\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
for i in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
do
echo -en "\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"$_since" "$_until" $_log_options | grep -E "($startYear|$endYear)" | grep " $i " | wc -l
done | awk '{
count[$1] = $2
total += $2
}
END{
for (month in count) {
s="|";
if (total > 0) {
percent = ((count[month] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf( "\t%s\t%-0s\t%s\n", month, count[month], s );
}
}
}' | LC_TIME="en_EN.UTF-8" sort -M
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per weekday
# ARGS: None
# OUTS: None
################################################################################
function commitsByWeekday() {
optionPicked "Git commits by weekday:"
echo -e "\tday\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
local counter=1
for i in Mon Tue Wed Thu Fri Sat Sun
do
echo -en "\t$counter\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"$_since" "$_until" $_log_options | grep -E "($startYear|$endYear)" | grep "$i " | wc -l
counter=$((counter+1))
done | awk '{
}
NR == FNR {
count[$1" "$2] = $3;
total += $3;
next
}
END{
for (day in count) {
s="|";
if (total > 0) {
percent = ((count[day] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf("\t%s\t%s\t%-0s\t%s\n", substr(day,0,1), substr(day,3,5), count[day], s);
}
}
}' | sort -k 1 -n | awk '{$1=""}1' | awk '{$1=$1}1' | awk '{printf("\t%s\t%s\t%s\n", $1, $2, $3)}'
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per hour
# ARGS: $author (optional): Can focus on a single author. Default is all authors
# OUTS: None
################################################################################
function commitsByHour() {
local author="${1:-}"
local _author=""
if [[ -z "${author}" ]]; then
optionPicked "Git commits by hour:"
_author="--author=**"
else
optionPicked "Git commits by hour for author '${author}':"
_author="--author=${author}"
fi
echo -e "\thour\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
for i in $(seq -w 0 23)
do
echo -ne "\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"${_author}" "$_since" "$_until" $_log_options | grep -E "($startYear|$endYear)" | grep ' '$i: | wc -l
done | awk '{
count[$1] = $2
total += $2
}
END{
for (hour in count) {
s="|";
if (total > 0) {
percent = ((count[hour] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf( "\t%s\t%-0s\t%s\n", hour, count[hour], s );
}
}
}' | sort
}
################################################################################
# DESC: Shows the number of commits that were committed per date recorded in the
# repo's log history
# ARGS: None
# OUTS: None
################################################################################
function commitsPerDay() {
optionPicked "Git commits per date:";
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--date=short --format='%ad' $_log_options $_pathspec | sort | uniq -c
}
################################################################################
# DESC: Displays the number of commits and percentage contributed to the repo
# per author and sorts them by contribution percentage
# ARGS: None
# OUTS: None
################################################################################
function commitsPerAuthor() {
optionPicked "Git commits per author:"
local authorCommits=$(git -c log.showSignature=false log --use-mailmap $_merges \
"$_since" "$_until" $_log_options | grep -i Author: | cut -c9-)
local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap $_merges \
"$_since" "$_until" $_log_options | grep -i Co-Authored-by: | cut -c21-)
if [[ -z "${coAuthorCommits}" ]]
then
allCommits="${authorCommits}"
else
allCommits="${authorCommits}\n${coAuthorCommits}"
fi
echo -e "${allCommits}" | awk '
{ $NF=""; author[NR] = $0 }
END {
for(i in author) {
sum[author[i]]++; name[author[i]] = author[i]; total++;
}
for(i in sum) {
printf "\t%d:%s:%2.1f%%\n", sum[i], name[i], (100 * sum[i] / total)
}
}' | sort -n -r | column -t -s:
}
################################################################################
# DESC: Shows git shortstats on the current user's changes for current day
# ARGS: None
# OUTS: None
################################################################################
function myDailyStats() {
optionPicked "My daily status:"
git diff --shortstat '@{0 day ago}' | sort -nr | tr ',' '\n' | LC_ALL=C awk '
{ args[NR] = $0; }
END {
for (i = 1; i <= NR; ++i) {
printf "\t%s\n", args[i]
}
}'
echo -e "\t" $(git -c log.showSignature=false log --use-mailmap \
--author="$(git config user.name)" $_merges \
--since=$(date "+%Y-%m-%dT00:00:00") \
--until=$(date "+%Y-%m-%dT23:59:59") --reverse $_log_options \
| grep -E "commit [a-f0-9]{40}" | wc -l) "commits"
}
################################################################################
# DESC: Lists all contributors to a repo sorted by alphabetical order
# ARGS: None
# OUTS: None
################################################################################
function contributors() {
optionPicked "All contributors (sorted by name):"
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--format='%aN' $_log_options $_pathspec | sort -u | cat -n
}
################################################################################
# DESC: Shows an abbreviated ASCII graph based off of commit history
# ARGS: None
# OUTS: None
################################################################################
function branchTree() {
optionPicked "Branching tree view:"
git -c log.showSignature=false log --use-mailmap --graph --abbrev-commit \
"$_since" "$_until" --decorate \
--format=format:'--+ Commit: %h %n | Date: %aD (%ar) %n'' | Message: %s %d %n'' + Author: %aN %n' \
--all $_log_options | head -n $((_limit*5))
}
################################################################################
# DESC: Lists all branches sorted by their most recent commit
# ARGS: None
# OUTS: None
################################################################################
function branchesByDate() {
optionPicked "All branches (sorted by most recent commit):"
git for-each-ref --sort=committerdate refs/heads/ \
--format='[%(authordate:relative)] %(authorname) %(refname:short)' | cat -n
}
################################################################################
# DESC: Displays the latest commit history in an easy to read format by date
# ARGS: $author (optional): Can focus on a single author. Default is all authors
@@ -715,6 +397,389 @@ function changelogs() {
done
}
################################################################################
# DESC: Shows git shortstats on the current user's changes for current day
# ARGS: None
# OUTS: None
################################################################################
function myDailyStats() {
optionPicked "My daily status:"
git diff --shortstat '@{0 day ago}' | sort -nr | tr ',' '\n' | LC_ALL=C awk '
{ args[NR] = $0; }
END {
for (i = 1; i <= NR; ++i) {
printf "\t%s\n", args[i]
}
}'
echo -e "\t" $(git -c log.showSignature=false log --use-mailmap \
--author="$(git config user.name)" $_merges \
--since=$(date "+%Y-%m-%dT00:00:00") \
--until=$(date "+%Y-%m-%dT23:59:59") --reverse $_log_options \
| grep -E "commit [a-f0-9]{40}" | wc -l) "commits"
}
################################################################################
# DESC: Shows detailed contribution stats per author by parsing every commit in
# the repo and outputting their contribution stats
# ARGS: $branch (optional): Users can specify an alternative branch instead of
# the current default one
# OUTS: None
################################################################################
function csvOutput() {
# TODO: Look into if we can refactor this to work as an option for the user
# so they can choose between JSON or CSV or possibly other formats
# like XML, YAML, and so on.
# TODO: Look into allowing the user to adjust the separator value
local is_branch_existing=false
local branch="${1:-}"
local _branch=""
# Check if requesting for a specific branch
if [[ -n "${branch}" ]]; then
# Check if branch exist
if [[ $(git show-ref refs/heads/"${branch}") ]] ; then
is_branch_existing=true
_branch="${branch}"
else
is_branch_existing=false
_branch=""
fi
fi
printf "author,insertions,insertions_per,deletions,deletions_per,files,"
printf "files_per,commits,commits_per,lines_changed,lines_changed_per\n"
git -c log.showSignature=false log ${_branch} --use-mailmap $_merges --numstat \
--pretty="format:commit %H%nAuthor: %aN <%aE>%nDate: %ad%n%n%w(0,4,4)%B%n" \
"$_since" "$_until" $_log_options $_pathspec | LC_ALL=C awk '
function printStats(author) {
printf "%s,", author
if(more["total"] > 0) {
printf "%d,%.0f%%,", more[author], \
(more[author] / more["total"] * 100)
}
if(less["total"] > 0) {
printf "%d,%.0f%%,", less[author], \
(less[author] / less["total"] * 100)
}
if(file["total"] > 0) {
printf "%d,%.0f%%,", file[author], \
(file[author] / file["total"] * 100)
}
if(commits["total"] > 0) {
printf "%d,%.0f%%,", commits[author], \
(commits[author] / commits["total"] * 100)
}
if (first[author] != "") {
if ( ((more["total"] + less["total"]) * 100) > 0) {
printf "%d,", more[author] + less[author]
printf "%.0f%%\n", ((more[author] + less[author]) / \
(more["total"] + less["total"]) * 100)
}
}
}
/^Author:/ {
$1 = ""
author = $0
commits[author] += 1
commits["total"] += 1
}
/^Date:/ {
$1="";
first[author] = substr($0, 2)
if(last[author] == "" ) { last[author] = first[author] }
}
/^[0-9]/ {
more[author] += $1
less[author] += $2
file[author] += 1
more["total"] += $1
less["total"] += $2
file["total"] += 1
}
END {
for (author in commits) {
if (author != "total") {
printStats(author)
}
}
}'
}
################################################################################
# DESC: Saves the git log output in a JSON format
# ARGS: $json_path (required): Path to where the file is saved
# OUTS: A JSON formatted file
################################################################################
function jsonOutput() {
optionPicked "Output log saved to file at: ${json_path}/output.json"
# TODO: Can we shorten this pretty format line? Quick experiment shows that
# it does not properly respect \ and interprets them literally.
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" $_log_options \
--pretty=format:'{%n "commit": "%H",%n "abbreviated_commit": "%h",%n "tree": "%T",%n "abbreviated_tree": "%t",%n "parent": "%P",%n "abbreviated_parent": "%p",%n "refs": "%D",%n "encoding": "%e",%n "subject": "%s",%n "sanitized_subject_line": "%f",%n "body": "%b",%n "commit_notes": "%N",%n "author": {%n "name": "%aN",%n "email": "%aE",%n "date": "%aD"%n },%n "commiter": {%n "name": "%cN",%n "email": "%cE",%n "date": "%cD"%n }%n},' \
| sed "$ s/,$//" \
| sed ':a;N;$!ba;s/\r\n\([^{]\)/\\n\1/g' \
| awk 'BEGIN { print("[") } { print($0) } END { print("]") }' \
> "${json_path}/output.json"
}
################################################################################
# FUNCTIONS FOR LISTING STATS
################################################################################
# DESC: Shows an abbreviated ASCII graph based off of commit history
# ARGS: None
# OUTS: None
################################################################################
function branchTree() {
optionPicked "Branching tree view:"
# TODO: Can we shorten this pretty format line? Quick experiment shows that
# it does not properly respect \ and interprets them literally.
git -c log.showSignature=false log --use-mailmap --graph --abbrev-commit \
"$_since" "$_until" --decorate \
--format=format:'--+ Commit: %h %n | Date: %aD (%ar) %n'' | Message: %s %d %n'' + Author: %aN %n' \
--all $_log_options | head -n $((_limit*5))
}
################################################################################
# DESC: Lists all branches sorted by their most recent commit
# ARGS: None
# OUTS: None
################################################################################
function branchesByDate() {
optionPicked "All branches (sorted by most recent commit):"
git for-each-ref --sort=committerdate refs/heads/ \
--format='[%(authordate:relative)] %(authorname) %(refname:short)' | cat -n
}
################################################################################
# DESC: Lists all contributors to a repo sorted by alphabetical order
# ARGS: None
# OUTS: None
################################################################################
function contributors() {
optionPicked "All contributors (sorted by name):"
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--format='%aN' $_log_options $_pathspec | sort -u | cat -n
}
################################################################################
# DESC: Displays the number of commits and percentage contributed to the repo
# per author and sorts them by contribution percentage
# ARGS: None
# OUTS: None
################################################################################
function commitsPerAuthor() {
optionPicked "Git commits per author:"
local authorCommits=$(git -c log.showSignature=false log --use-mailmap \
$_merges "$_since" "$_until" $_log_options \
| grep -i Author: | cut -c9-)
local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap \
$_merges "$_since" "$_until" $_log_options \
| grep -i Co-Authored-by: | cut -c21-)
if [[ -z "${coAuthorCommits}" ]]; then
allCommits="${authorCommits}"
else
allCommits="${authorCommits}\n${coAuthorCommits}"
fi
echo -e "${allCommits}" | awk '
{ $NF=""; author[NR] = $0 }
END {
for(i in author) {
sum[author[i]]++; name[author[i]] = author[i]; total++;
}
for(i in sum) {
printf "\t%d:%s:%2.1f%%\n", sum[i], name[i], (100 * sum[i] / total)
}
}' | sort -n -r | column -t -s:
}
################################################################################
# DESC: Shows the number of commits that were committed per date recorded in the
# repo's log history
# ARGS: None
# OUTS: None
################################################################################
function commitsPerDay() {
optionPicked "Git commits per date:";
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--date=short --format='%ad' $_log_options $_pathspec | sort | uniq -c
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per month
# ARGS: None
# OUTS: None
################################################################################
function commitsByMonth() {
optionPicked "Git commits by month:"
echo -e "\tmonth\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
for i in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
do
echo -en "\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"$_since" "$_until" $_log_options | grep -E "($startYear|$endYear)" \
| grep " $i " | wc -l
done | awk '{
count[$1] = $2
total += $2
}
END{
for (month in count) {
s="|";
if (total > 0) {
percent = ((count[month] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf( "\t%s\t%-0s\t%s\n", month, count[month], s );
}
}
}' | LC_TIME="en_EN.UTF-8" sort -M
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per weekday
# ARGS: None
# OUTS: None
################################################################################
function commitsByWeekday() {
optionPicked "Git commits by weekday:"
echo -e "\tday\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
local counter=1
for i in Mon Tue Wed Thu Fri Sat Sun
do
echo -en "\t$counter\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"$_since" "$_until" $_log_options | grep -E "($startYear|$endYear)" \
| grep "$i " | wc -l
counter=$((counter+1))
done | awk '{
}
NR == FNR {
count[$1" "$2] = $3;
total += $3;
next
}
END{
for (day in count) {
s="|";
if (total > 0) {
percent = ((count[day] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf("\t%s\t%s\t%-0s\t%s\n", substr(day,0,1), substr(day,3,5), count[day], s);
}
}
}' | sort -k 1 -n | awk '{$1=""}1' | awk '{$1=$1}1' \
| awk '{printf("\t%s\t%s\t%s\n", $1, $2, $3)}'
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per hour
# ARGS: $author (optional): Can focus on a single author. Default is all authors
# OUTS: None
################################################################################
function commitsByHour() {
local author="${1:-}"
local _author=""
if [[ -z "${author}" ]]; then
optionPicked "Git commits by hour:"
_author="--author=**"
else
optionPicked "Git commits by hour for author '${author}':"
_author="--author=${author}"
fi
echo -e "\thour\tsum"
local startYear=$(echo "$_since" | grep -Eo "[0-9]{4}")
local endYear=$(echo "$_until" | grep -Eo "[0-9]{4}")
for i in $(seq -w 0 23)
do
echo -ne "\t$i\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"${_author}" "$_since" "$_until" $_log_options \
| grep -E "($startYear|$endYear)" | grep ' '$i: | wc -l
done | awk '{
count[$1] = $2
total += $2
}
END{
for (hour in count) {
s="|";
if (total > 0) {
percent = ((count[hour] / total) * 100) / 1.25;
for (i = 1; i <= percent; ++i) {
s=s"█"
}
printf( "\t%s\t%-0s\t%s\n", hour, count[hour], s );
}
}
}' | sort
}
################################################################################
# DESC: Displays number of commits per timezone
# ARGS: $author (optional): Can focus on a single author. Default is all authors
# OUTS: None
################################################################################
function commitsByTimezone() {
local author="${1:-}"
local _author=""
if [[ -z "${author}" ]]; then
optionPicked "Git commits by timezone:"
_author="--author=**"
else
optionPicked "Git commits by timezone for author '${author}':"
_author="--author=${author}"
fi
echo -e "Commits\tTimeZone"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"${_author}" "$_since" "$_until" --date=iso $_log_options $_pathspec \
| cut -d " " -f 12 | grep -v -e '^[[:space:]]*$' | sort | uniq -c
}
################################################################################
# FUNCTIONS FOR SUGGESTION STATS
################################################################################
# DESC: Displays the authors in order of total contribution to the repo
# ARGS: None
# OUTS: None
################################################################################
function suggestReviewers() {
optionPicked "Suggested code reviewers (based on git history):"
git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
--pretty=%aN $_log_options $_pathspec | head -n 100 | sort | uniq -c \
| sort -nr | LC_ALL=C awk '
{ args[NR] = $0; }
END {
for (i = 1; i <= NR; ++i) {
printf "%s\n", args[i]
}
}' | column -t -s,
}
################################################################################
# MAIN
@@ -727,7 +792,7 @@ git rev-parse --is-inside-work-tree > /dev/null
# Parse non-interative commands
if [[ "$#" -eq 1 ]]; then
case "$1" in
-r|--suggest-reviewers) suggestReviewers;;
# GENERATE OPTIONS
-T|--detailed-git-stats) detailedGitStats;;
-R|--git-stats-by-branch)
branch="${_GIT_BRANCH:-}"
@@ -735,18 +800,6 @@ if [[ "$#" -eq 1 ]]; then
read -r -p "Which branch? " branch
done
detailedGitStats "${branch}";;
-V|--csv-output-by-branch)
branch="${_GIT_BRANCH:-}"
while [[ -z "${branch}" ]]; do
read -r -p "Which branch? " branch
done
csvOutput "${branch}";;
-b|--branch-tree) branchTree;;
-d|--commits-per-day) commitsPerDay;;
-a|--commits-per-author) commitsPerAuthor;;
-S|--my-daily-stats) myDailyStats;;
-C|--contributors) contributors;;
-D|--branches-by-date) branchesByDate;;
-c|--changelogs) changelogs;;
-L|--changelogs-by-author)
author="${_GIT_AUTHOR:-}"
@@ -754,15 +807,13 @@ if [[ "$#" -eq 1 ]]; then
read -r -p "Which author? " author
done
changelogs "${author}";;
-w|--commits-by-weekday) commitsByWeekday;;
-o|--commits-by-hour) commitsByHour;;
-A|--commits-by-author-by-hour)
author="${_GIT_AUTHOR:-}"
while [[ -z "${author}" ]]; do
read -r -p "Which author? " author
-S|--my-daily-stats) myDailyStats;;
-V|--csv-output-by-branch)
branch="${_GIT_BRANCH:-}"
while [[ -z "${branch}" ]]; do
read -r -p "Which branch? " branch
done
commitsByHour "${author}";;
-m|--commits-by-month) commitsByMonth;;
csvOutput "${branch}";;
-j|--json-output)
json_path=""
while [[ -z "${json_path}" ]]; do
@@ -781,6 +832,30 @@ if [[ "$#" -eq 1 ]]; then
fi
done
jsonOutput "${json_path}";;
# LIST OPTIONS
-b|--branch-tree) branchTree;;
-D|--branches-by-date) branchesByDate;;
-C|--contributors) contributors;;
-a|--commits-per-author) commitsPerAuthor;;
-d|--commits-per-day) commitsPerDay;;
-m|--commits-by-month) commitsByMonth;;
-w|--commits-by-weekday) commitsByWeekday;;
-o|--commits-by-hour) commitsByHour;;
-A|--commits-by-author-by-hour)
author="${_GIT_AUTHOR:-}"
while [[ -z "${author}" ]]; do
read -r -p "Which author? " author
done
commitsByHour "${author}";;
-z|--commits-by-timezone) commitsByTimezone;;
-Z|--commits-by-author-by-timezone)
author="${_GIT_AUTHOR:-}"
while [[ -z "${author}" ]]; do
read -r -p "Which author? " author
done
commitsByTimezone "${author}";;
# SUGGEST OPTIONS
-r|--suggest-reviewers) suggestReviewers;;
-h|-\?|--help) usage;;
*) echo "Invalid argument"; usage; exit 1;;
esac
@@ -843,7 +918,13 @@ while [[ "${opt}" != "" ]]; do
read -r -p "Which author? " author
done
commitsByHour "${author}"; showMenu;;
17) suggestReviewers; showMenu;;
17) commitsByTimezone; showMenu;;
18) author=""
while [[ -z "${author}" ]]; do
read -r -p "Which author? " author
done
commitsByTimezone "${author}"; showMenu;;
19) suggestReviewers; showMenu;;
q|"\n") exit;;
*) clear; optionPicked "Pick an option from the menu"; showMenu;;
esac

View File

@@ -1,4 +1,4 @@
.TH git-quick-stats "1" "January 2020" "git-quick-stats" "User Commands"
.TH git-quick-stats "1" "June 2021" "git-quick-stats" "User Commands"
.SH NAME
.B git\-quick\-stats
\- Simple and efficient way to access various stats in a git repository.
@@ -17,12 +17,7 @@ and files. Extracting this information is not always trivial, mostly because
of a gadzillion options to a gadzillion git commands.
This program allows you to see detailed information about a git repository.
.PP
.SH OPTIONS
.HP
\fB\-r\fR, \fB\-\-suggest\-reviewers\fR
.IP
show the best people to contact to review code
.HP
.SH GENERATE OPTIONS
.PP
\fB\-T\fR, \fB\-\-detailed\-git\-stats\fR
.IP
@@ -34,11 +29,52 @@ give a detailed list of git stats
see detailed list of git stats by branch
.HP
.PP
\fB\-c\fR, \fB\-\-changelogs\fR
.IP
see changelogs
.HP
.PP
\fB\-L\fR, \fB\-\-changelogs\-by\-author\fR
.IP
see changelogs by author
.HP
.PP
\fB\-S\fR, \fB\-\-my\-daily\-stats\fR
.IP
see your current daily stats
.HP
.PP
\fB\-V\fR, \fB\-\-csv\-output\-by\-branch\fR
.IP
output daily stats by branch in CSV format
.HP
.PP
\fB\-j\fR, \fB\-\-json\-output\fR
.IP
save git log as a JSON formatted file to a specified area
.HP
.SH LIST OPTIONS
.PP
\fB\-b\fR, \fB\-\-branch\-tree\fR
.IP
show an ASCII graph of the git repo branch history
.HP
.PP
\fB\-D\fR, \fB\-\-branches\-by\-date\fR
.IP
show branches by date
.HP
.PP
\fB\-C\fR, \fB\-\-contributors\fR
.IP
see a list of everyone who contributed to the repo
.HP
.PP
\fB\-a\fR, \fB\-\-commits\-per\-author\fR
.IP
displays a list of commits per author
.HP
.PP
\fB\-d\fR, \fB\-\-commits\-per\-day\fR
.IP
displays a list of commits per day
@@ -64,44 +100,20 @@ displays a list of commits per hour
displays a list of commits per hour by author
.HP
.PP
\fB\-a\fR, \fB\-\-commits\-per\-author\fR
\fB\-z\fR, \fB\-\-commits\-by\-timezone\fR
.IP
displays a list of commits per author
displays a list of commits per timezone
.HP
.PP
\fB\-S\fR, \fB\-\-my\-daily\-stats\fR
\fB\-Z\fR, \fB\-\-commits\-by\-author\-by\-timezone\fR
.IP
see your current daily stats
displays a list of commits per timezone by author
.HP
.SH SUGGEST OPTIONS
.PP
\fB\-C\fR, \fB\-\-contributors\fR
\fB\-r\fR, \fB\-\-suggest\-reviewers\fR
.IP
see a list of everyone who contributed to the repo
.HP
.PP
\fB\-b\fR, \fB\-\-branch\-tree\fR
.IP
show an ASCII graph of the git repo branch history
.HP
.PP
\fB\-D\fR, \fB\-\-branches\-by\-date\fR
.IP
show branches by date
.HP
.PP
\fB\-c\fR, \fB\-\-changelogs\fR
.IP
see changelogs
.HP
.PP
\fB\-L\fR, \fB\-\-changelogs\-by\-author\fR
.IP
see changelogs by author
.HP
.PP
\fB\-j\fR, \fB\-\-json\-output\fR
.IP
save git log as a JSON formatted file to a specified area
show the best people to contact to review code
.HP
.PP
\fB\-h\fR, \-?, \fB\-\-help\fR
@@ -142,4 +154,3 @@ You can set _GIT_BRANCH to set the branch of the stats, example:
.B export _GIT_BRANCH="master"
.
.fi

View File

@@ -19,15 +19,31 @@ DESCRIPTION
This program allows you to see detailed information about a git repository.
OPTIONS
-r, --suggest-reviewers
show the best people to contact to review code
GENERATE OPTIONS
-T, --detailed-git-stats
give a detailed list of git stats
-R, --git-stats-by-branch
see detailed list of git stats by branch
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-S, --my-daily-stats
see your current daily stats
-V, --csv-output-by-branch
output daily stats by branch in CSV format
-j, --json-output
save git log as a JSON formatted file to a specified area
LIST OPTIONS
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-C, --contributors
see a list of everyone who contributed to the repo
-a, --commits-per-author
displays a list of commits per author
-d, --commits-per-day
displays a list of commits per day
-m, --commits-by-month
@@ -38,22 +54,14 @@ OPTIONS
displays a list of commits per hour
-A, --commits-by-author-by-hour
displays a list of commits per hour by author
-a, --commits-per-author
displays a list of commits per author
-S, --my-daily-stats
see your current daily stats
-C, --contributors
see a list of everyone who contributed to the repo
-b, --branch-tree
show an ASCII graph of the git repo branch history
-D, --branches-by-date
show branches by date
-c, --changelogs
see changelogs
-L, --changelogs-by-author
see changelogs by author
-j, --json-output
save git log as a JSON formatted file to a specified area
-z, --commits-by-timezone
displays a list of commits per timezone
-Z, --commits-by-author-by-timezone
displays a list of commits per timezone by author
SUGGEST OPTIONS
-r, --suggest-reviewers
show the best people to contact to review code
-h, -?, --help
display this help text in the terminal