Compare commits

...

12 Commits
2.0.6 ... 2.0.8

Author SHA1 Message Date
Tom Ice
c11bce17bd Merge pull request #71 from tomice/master
Added ability to save log as a JSON formatted file
2019-05-26 10:27:58 -04:00
Tom Ice
5f0bc1c7cf Removed GPG info from JSON and updated README pics
* The GPG settings don't play well with OS X if you don't have
  certain tools installed, so they were removed from the git log
  format settings for the JSON output.

* Pictures have been updated to reflect the new menu option.
2019-05-24 23:35:11 -04:00
Tom Ice
5f71b785ac Added ability to save log as a JSON formatted file
* The main feature of this commit is addressing the feature request
  of adding the ability to save the output as a file to use in other
  tools. I decided to use the JSON format as it's relatively straight
  forward and easy to create thanks to a few Google searches.

  The original feature request was to add the ability to output any of
  the options as a JSON/XML/YAML format. That said, because this entire project
  is relying only on built-in shell utilities, we kind of have to format stuff
  ourselves in relatively primitive tools such as awk, sed, and bash in order
  to adhere to the "spirit" of this codebase.

  It is possible to use Perl and/or Python, but that would defeat the purpose
  of this, in my opinion. The downside of not using these tools is that it
  might not be as robust and battle hardened as the others.

  AS SUCH, THIS FEATURE IS CURRENTLY EXPERIMENTAL.

  As people provide feedback, we can adjust this and possibly extend it to
  more options. For now, it respects _GIT_SINCE and _GIT_UNTIL. It does not
  respect variable expansion in paths, though, so saving it to a location such
  as "${my_save_location}" will fail.

* Made some of the variables a bit more robust by utilizing the -r flag to
  make the variables readonly. It should be noted that "local readonly" does
  not work, nor does "readonly local". The best way to do this is either via
  "local -r foo=bar" or "local foo=bar && readonly bar".

* Fixed a few comments describing how functions work.

* Added a .gitignore.

* Changed all functions to adhere to camelCase style for no real reason
  other than consistency and a few other minor things.

* Closes #31
2019-05-24 21:15:19 -04:00
Tom Ice
cdb3f20790 Fixing failed test that occurred after merging PR
* This is just a small change to make it so that the build passes
  tests. It is minor and does not affect the release functionality
2019-05-17 17:28:02 -04:00
Tom Ice
dd69477293 Merge pull request #69 from mhickman/master
Change format of _GIT_SINCE in help
2019-05-17 13:00:16 -04:00
Matt Hickman
4aef465e6b Change format of _GIT_SINCE in help
The format _GIT_SINCE is what `git --since` takes in
which is YYYY-MM-DD.

Ref: https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
2019-05-17 09:54:27 -07:00
Tom Ice
81fce5cadf Updating README.md to reflect new theme(s) 2019-05-13 10:35:59 -04:00
Tom Ice
f3931eb1a3 Merge pull request #65 from Calinou/improve-interactive-menu
Improve the interactive menu
2019-05-13 10:31:03 -04:00
Tom Ice
bdfe3beb25 New default theme with toggle-able legacy theme
* This sets the newly proposed theme as the main theme. In order to
  switch back to the legacy theme, set _MENU_THEME to legacy.
  This feature is currently an experimental feature and may change
  in the future.

* Fixes documentation and updates test to reflect newly changed theme.
2019-05-12 19:32:11 -04:00
Tom Ice
90d118f09f Fixing some menu color issues 2019-05-10 22:55:42 -04:00
Tom Ice
d12c1c6c4f Added color scheme toggle-ability and updated docs
* You can now switch between the default theme and an alternative theme
  for those who would like a different look to the interactive menu.
  In order to set this, simply do export _MENU_THEME=alternative. Anything
  that isn't "alternative" will simply fall back to the default menu option.

* Fixed merge conflicts based on the latest master branch which added the
  contribution stats by branch option.

* Fixed tests, updated docs, and all that fun stuff.
2019-05-10 16:17:42 -04:00
Hugo Locurcio
749367701d Improve the interactive menu
This adds a `>` at the end of the message to denote the program
is waiting for user input.

This also tweaks colors for better readability.
2019-04-11 14:40:16 +02:00
5 changed files with 182 additions and 87 deletions

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.json
*.db
.DS_Store*
._*
.*.swp
.*.swo
.Spotlight*
.Trash*
**/*~

View File

@@ -5,7 +5,7 @@
> Any git repository contains tons of information about commits, contributors, and files. Extracting this information is not always trivial, mostly because of 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 :). > Any git repository contains tons of information about commits, contributors, and files. Extracting this information is not always trivial, mostly because of 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/57544421-4891a700-7325-11e9-9cdd-034a6619ae0f.png) ![mainMenuScreenshot](https://user-images.githubusercontent.com/8818630/58364013-61e53800-7e7b-11e9-87f9-790d6744fbd5.png)
## Table of Contents ## Table of Contents
@@ -35,9 +35,9 @@
## Screenshots ## Screenshots
![commitsByWeekdayScreenshot](https://user-images.githubusercontent.com/8818630/57544420-4891a700-7325-11e9-876a-15df90bce420.png) ![commitsByWeekdayScreenshot](https://user-images.githubusercontent.com/8818630/58364011-61e53800-7e7b-11e9-9417-16cbb241ac2e.png)
![commitsByHourScreenshot](https://user-images.githubusercontent.com/8818630/57544419-47f91080-7325-11e9-82d3-57e4f98be240.png) ![commitsByHourScreenshot](https://user-images.githubusercontent.com/8818630/58364010-61e53800-7e7b-11e9-8711-a40b50aebf52.png)
## Usage ## Usage
@@ -83,6 +83,8 @@ Possible arguments in short and long form:
see changelogs see changelogs
-L, --changelogs-by-author -L, --changelogs-by-author
see changelogs by author see changelogs by author
-j, --json-output
save git log as a JSON formatted file to a specified area
-h, -?, --help -h, -?, --help
display this help text in the terminal display this help text in the terminal
``` ```
@@ -92,8 +94,8 @@ Possible arguments in short and long form:
You can set variable `_GIT_SINCE`, `_GIT_UNTIL` and limit the git log You can set variable `_GIT_SINCE`, `_GIT_UNTIL` and limit the git log
```bash ```bash
export _GIT_SINCE="2017-20-01" export _GIT_SINCE="2017-01-20"
export _GIT_UNTIL="2017-22-01" export _GIT_UNTIL="2017-01-22"
``` ```
then run `git quick-stats` (affect all stats, except "My daily status" and "Git changelogs" ) then run `git quick-stats` (affect all stats, except "My daily status" and "Git changelogs" )
@@ -115,6 +117,14 @@ You can exclude directory from the stats by using [pathspec](https://git-scm.com
export _GIT_PATHSPEC=':!directory' export _GIT_PATHSPEC=':!directory'
``` ```
#### Color themes
You can change to the legacy color scheme by toggling the variable `_MENU_THEME` between `default` and `legacy`
```bash
export _MENU_THEME=legacy
```
![legacyThemeScreenshot](https://user-images.githubusercontent.com/8818630/58364012-61e53800-7e7b-11e9-910a-aaff836260eb.png)
## Installation ## Installation

View File

@@ -24,13 +24,17 @@ else
_limit=10 _limit=10
fi fi
# Default menu theme
# Set the legacy theme by typing "export _MENU_THEME=legacy"
_theme="${_MENU_THEME:=default}"
################################################################################ ################################################################################
# DESC: Checks to make sure the user has the appropriate utilities installed # DESC: Checks to make sure the user has the appropriate utilities installed
# ARGS: None # ARGS: None
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function check_utils() { function checkUtils() {
local msg="not found. Please make sure this is installed and in PATH." local -r msg="not found. Please make sure this is installed and in PATH."
command -v awk >/dev/null 2>&1 || { echo >&2 "awk ${msg}"; exit 1; } command -v awk >/dev/null 2>&1 || { echo >&2 "awk ${msg}"; exit 1; }
command -v basename >/dev/null 2>&1 || { echo >&2 "basename ${msg}"; exit 1; } command -v basename >/dev/null 2>&1 || { echo >&2 "basename ${msg}"; exit 1; }
@@ -54,7 +58,7 @@ function check_utils() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function usage() { function usage() {
local program=$(basename "$0") local -r program=$(basename "$0")
echo " echo "
NAME NAME
@@ -102,16 +106,20 @@ OPTIONS
see changelogs see changelogs
-L, --changelogs-by-author -L, --changelogs-by-author
see changelogs by author see changelogs by author
-j, --json-output
save git log as a JSON formatted file to a specified area
-h, -?, --help -h, -?, --help
display this help text in the terminal display this help text in the terminal
ADDITIONAL USAGE ADDITIONAL USAGE
You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log
ex: export _GIT_SINCE=\"2017-20-01\" ex: export _GIT_SINCE=\"2017-01-20\"
You can set _GIT_LIMIT for limited output log You can set _GIT_LIMIT for limited output log
ex: export _GIT_LIMIT=20 ex: export _GIT_LIMIT=20
You can exclude a directory from the stats by using pathspec You can exclude a directory from the stats by using pathspec
ex: export _GIT_PATHSPEC=':!directory'" ex: export _GIT_PATHSPEC=':!directory'
You can set _MENU_THEME to display the legacy color scheme
ex: export _MENU_THEME=legacy"
} }
################################################################################ ################################################################################
@@ -119,31 +127,55 @@ ADDITIONAL USAGE
# ARGS: None # ARGS: None
# OUTS: $opt: Option selected by the user based on menu choice # OUTS: $opt: Option selected by the user based on menu choice
################################################################################ ################################################################################
function show_menu() { function showMenu() {
local normal=$(tput sgr0) local -r normal=$(tput sgr0)
local cyan=$(tput setaf 6) local -r cyan=$(tput setaf 6)
local red=$(tput setaf 1) local -r bold=$(tput bold)
local yellow=$(tput setaf 3) local -r red=$(tput setaf 1)
local -r yellow=$(tput setaf 3)
local -r white=$(tput setaf 7)
local titles=""
local text=""
local nums=""
local help_txt=""
local exit_txt=""
# Adjustable color menu option
if [[ "${_theme}" == "legacy" ]]; then
titles="${bold}${red}" && readonly titles
text="${normal}${cyan}" && readonly text
nums="${bold}${yellow}" && readonly nums
help_txt="${normal}${yellow}" && readonly help_txt
exit_txt="${bold}${red}" && readonly exit_txt
else
titles="${bold}${cyan}" && readonly titles
text="${normal}${white}" && readonly text
nums="${normal}${bold}${white}" && readonly nums
help_txt="${normal}${cyan}" && readonly help_txt
exit_txt="${bold}${cyan}" && readonly exit_txt
fi
echo -e "\n${red} Generate: ${normal}" echo -e "\n${titles} Generate:${normal}"
echo -e "${cyan} ${yellow} 1)${cyan} Contribution stats (by author) ${normal}" echo -e "${nums} 1)${text} Contribution stats (by author)"
echo -e "${cyan} ${yellow} 2)${cyan} Contribution stats (by author) on a specific branch ${normal}" echo -e "${nums} 2)${text} Contribution stats (by author) on a specific branch"
echo -e "${cyan} ${yellow} 3)${cyan} Git changelogs (last $_limit days)${normal}" echo -e "${nums} 3)${text} Git changelogs (last $_limit days)"
echo -e "${cyan} ${yellow} 4)${cyan} Git changelogs by author ${normal}" echo -e "${nums} 4)${text} Git changelogs by author"
echo -e "${cyan} ${yellow} 5)${cyan} My daily status ${normal}" echo -e "${nums} 5)${text} My daily status"
echo -e "${red} List: ${normal}" echo -e "${nums} 6)${text} Save git log output in JSON format"
echo -e "${cyan} ${yellow} 6)${cyan} Branch tree view (last $_limit)${normal}" echo -e "\n${titles} List:"
echo -e "${cyan} ${yellow} 7)${cyan} All branches (sorted by most recent commit) ${normal}" echo -e "${nums} 7)${text} Branch tree view (last $_limit)"
echo -e "${cyan} ${yellow} 8)${cyan} All contributors (sorted by name) ${normal}" echo -e "${nums} 8)${text} All branches (sorted by most recent commit)"
echo -e "${cyan} ${yellow} 9)${cyan} Git commits per author ${normal}" echo -e "${nums} 9)${text} All contributors (sorted by name)"
echo -e "${cyan} ${yellow} 10)${cyan} Git commits per date ${normal}" echo -e "${nums} 10)${text} Git commits per author"
echo -e "${cyan} ${yellow} 11)${cyan} Git commits per month ${normal}" echo -e "${nums} 11)${text} Git commits per date"
echo -e "${cyan} ${yellow} 12)${cyan} Git commits per weekday ${normal}" echo -e "${nums} 12)${text} Git commits per month"
echo -e "${cyan} ${yellow} 13)${cyan} Git commits per hour ${normal}" echo -e "${nums} 13)${text} Git commits per weekday"
echo -e "${cyan} ${yellow} 14)${cyan} Git commits by author per hour ${normal}" echo -e "${nums} 14)${text} Git commits per hour"
echo -e "${red} Suggest: ${normal}" echo -e "${nums} 15)${text} Git commits by author per hour"
echo -e "${cyan} ${yellow} 15)${cyan} Code reviewers (based on git history) ${normal}" echo -e "\n${titles} Suggest:"
echo -e "\n${yellow}Please enter a menu option or ${red}press enter to exit. ${normal}" echo -e "${nums} 16)${text} Code reviewers (based on git history)"
echo -e "\n${help_txt}Please enter a menu option or ${exit_txt}press Enter to exit."
echo -n "${text}> ${normal}"
read -r opt read -r opt
} }
@@ -152,10 +184,10 @@ function show_menu() {
# ARGS: $* (required): String to print (usually provided by other functions) # ARGS: $* (required): String to print (usually provided by other functions)
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function option_picked() { function optionPicked() {
local bold=$(tput bold) local -r bold=$(tput bold)
local red=$(tput setaf 1) local -r red=$(tput setaf 1)
local reset=$(tput sgr0) local -r reset=$(tput sgr0)
local msg=${*:-"${reset}Error: No message passed"} local msg=${*:-"${reset}Error: No message passed"}
echo -e "${bold}${red}${msg}${reset}\n" echo -e "${bold}${red}${msg}${reset}\n"
@@ -164,7 +196,8 @@ function option_picked() {
################################################################################ ################################################################################
# DESC: Shows detailed contribution stats per author by parsing every commit in # DESC: Shows detailed contribution stats per author by parsing every commit in
# the repo and outputting their contribution stats # the repo and outputting their contribution stats
# ARGS: None # ARGS: $branch (optional): Users can specify an alternative branch instead of
# the current default one
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function detailedGitStats() { function detailedGitStats() {
@@ -185,12 +218,12 @@ function detailedGitStats() {
fi fi
# Prompt message # Prompt message
if [[ $is_branch_existing && -n "${_branch}" ]]; then if [[ "${is_branch_existing}" && -n "${_branch}" ]]; then
option_picked "Contribution stats (by author) on ${_branch} branch:" optionPicked "Contribution stats (by author) on ${_branch} branch:"
elif [[ -n "${branch}" && -z "${_branch}" ]]; then elif [[ -n "${branch}" && -z "${_branch}" ]]; then
option_picked "Branch \"${branch}\" does not exist.\nContribution stats (by author) on the current branch:" optionPicked "Branch ${branch} does not exist.\nContribution stats (by author) on the current branch:"
else else
option_picked "Contribution stats (by author) on the current branch:" optionPicked "Contribution stats (by author) on the current branch:"
fi fi
git -c log.showSignature=false log ${_branch} --use-mailmap --no-merges --numstat \ git -c log.showSignature=false log ${_branch} --use-mailmap --no-merges --numstat \
@@ -267,7 +300,7 @@ function detailedGitStats() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function suggestReviewers() { function suggestReviewers() {
option_picked "Suggested code reviewers (based on git history):" optionPicked "Suggested code reviewers (based on git history):"
git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \ git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \
--pretty=%aN $_pathspec | head -n 100 | sort | uniq -c | sort -nr | LC_ALL=C awk ' --pretty=%aN $_pathspec | head -n 100 | sort | uniq -c | sort -nr | LC_ALL=C awk '
{ args[NR] = $0; } { args[NR] = $0; }
@@ -278,13 +311,28 @@ function suggestReviewers() {
}' | column -t -s, }' | 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 --no-merges $_since $_until \
--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 # DESC: Displays a horizontal bar graph based on total commits per month
# ARGS: None # ARGS: None
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function commitsByMonth() { function commitsByMonth() {
option_picked "Git commits by month:" optionPicked "Git commits by month:"
echo -e "\tmonth\tsum" echo -e "\tmonth\tsum"
for i in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec for i in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
do do
@@ -315,7 +363,7 @@ function commitsByMonth() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function commitsByWeekday() { function commitsByWeekday() {
option_picked "Git commits by weekday:" optionPicked "Git commits by weekday:"
echo -e "\tday\tsum" echo -e "\tday\tsum"
for i in Mon Tue Wed Thu Fri Sat Sun for i in Mon Tue Wed Thu Fri Sat Sun
do do
@@ -355,10 +403,10 @@ function commitsByHour() {
local _author="" local _author=""
if [[ -z "${author}" ]]; then if [[ -z "${author}" ]]; then
option_picked "Git commits by hour:" optionPicked "Git commits by hour:"
_author="--author=**" _author="--author=**"
else else
option_picked "Git commits by hour for author '${author}':" optionPicked "Git commits by hour for author '${author}':"
_author="--author=${author}" _author="--author=${author}"
fi fi
echo -e "\thour\tsum" echo -e "\thour\tsum"
@@ -392,7 +440,7 @@ function commitsByHour() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function commitsPerDay() { function commitsPerDay() {
option_picked "Git commits per date:"; optionPicked "Git commits per date:";
git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \ git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \
--date=short --format='%ad' $_pathspec | sort | uniq -c --date=short --format='%ad' $_pathspec | sort | uniq -c
} }
@@ -404,7 +452,7 @@ function commitsPerDay() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function commitsPerAuthor() { function commitsPerAuthor() {
option_picked "Git commits per author:" optionPicked "Git commits per author:"
git -c log.showSignature=false shortlog $_since $_until --no-merges -n -s \ git -c log.showSignature=false shortlog $_since $_until --no-merges -n -s \
| sort -nr | LC_ALL=C awk ' | sort -nr | LC_ALL=C awk '
{ args[NR] = $0; sum += $0 } { args[NR] = $0; sum += $0 }
@@ -421,7 +469,7 @@ function commitsPerAuthor() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function myDailyStats() { function myDailyStats() {
option_picked "My daily status:" optionPicked "My daily status:"
git diff --shortstat '@{0 day ago}' | sort -nr | tr ',' '\n' | LC_ALL=C awk ' git diff --shortstat '@{0 day ago}' | sort -nr | tr ',' '\n' | LC_ALL=C awk '
{ args[NR] = $0; } { args[NR] = $0; }
END { END {
@@ -443,7 +491,7 @@ function myDailyStats() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function contributors() { function contributors() {
option_picked "All contributors (sorted by name):" optionPicked "All contributors (sorted by name):"
git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \ git -c log.showSignature=false log --use-mailmap --no-merges $_since $_until \
--format='%aN' $_pathspec | sort -u | cat -n --format='%aN' $_pathspec | sort -u | cat -n
} }
@@ -454,7 +502,7 @@ function contributors() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function branchTree() { function branchTree() {
option_picked "Branching tree view:" optionPicked "Branching tree view:"
git -c log.showSignature=false log --use-mailmap --graph --abbrev-commit \ git -c log.showSignature=false log --use-mailmap --graph --abbrev-commit \
$_since $_until --decorate \ $_since $_until --decorate \
--format=format:'--+ Commit: %h %n | Date: %aD (%ar) %n'' | Message: %s %d %n'' + Author: %aN %n' \ --format=format:'--+ Commit: %h %n | Date: %aD (%ar) %n'' | Message: %s %d %n'' + Author: %aN %n' \
@@ -467,7 +515,7 @@ function branchTree() {
# OUTS: None # OUTS: None
################################################################################ ################################################################################
function branchesByDate() { function branchesByDate() {
option_picked "All branches (sorted by most recent commit):" optionPicked "All branches (sorted by most recent commit):"
git for-each-ref --sort=committerdate refs/heads/ \ git for-each-ref --sort=committerdate refs/heads/ \
--format='[%(authordate:relative)] %(authorname) %(refname:short)' | cat -n --format='[%(authordate:relative)] %(authorname) %(refname:short)' | cat -n
} }
@@ -480,36 +528,37 @@ function branchesByDate() {
function changelogs() { function changelogs() {
local author="${1:-}" local author="${1:-}"
local _author="" local _author=""
local next=$(date +%F)
if [[ -z "${author}" ]]; then if [[ -z "${author}" ]]; then
option_picked "Git changelogs:" optionPicked "Git changelogs:"
_author="--author=**" _author="--author=**"
else else
option_picked "Git changelogs for author '${author}':" optionPicked "Git changelogs for author '${author}':"
_author="--author=${author}" _author="--author=${author}"
fi fi
NEXT=$(date +%F)
git -c log.showSignature=false log \ git -c log.showSignature=false log \
--use-mailmap \ --use-mailmap \
--no-merges \ --no-merges \
--format="%cd" \ --format="%cd" \
--date=short "${_author}" $_since $_until $_pathspec \ --date=short "${_author}" $_since $_until $_pathspec \
| sort -u -r | head -n $_limit | while read DATE; do | sort -u -r | head -n $_limit \
echo -e "\n[$DATE]" | while read DATE; do
GIT_PAGER=cat git -c log.showSignature=false log \ echo -e "\n[$DATE]"
--use-mailmap --no-merges \ GIT_PAGER=cat git -c log.showSignature=false log \
--format=" * %s (%aN)" "${_author}" \ --use-mailmap --no-merges \
--since=$DATE --until=$NEXT --format=" * %s (%aN)" "${_author}" \
NEXT=$DATE --since=$DATE --until=$next
done next=$DATE
done
} }
################################################################################ ################################################################################
# MAIN # MAIN
# Check to make sure all utilities required for this script are installed # Check to make sure all utilities required for this script are installed
check_utils checkUtils
# Check if we are currently in a git repo. # Check if we are currently in a git repo.
git rev-parse --is-inside-work-tree > /dev/null git rev-parse --is-inside-work-tree > /dev/null
@@ -547,6 +596,16 @@ if [[ "$#" -eq 1 ]]; then
done done
commitsByHour "${author}";; commitsByHour "${author}";;
-m|--commits-by-month) commitsByMonth;; -m|--commits-by-month) commitsByMonth;;
-j|--json-output)
json_path=""
while [[ -z "${json_path}" ]]; do
read -r -p "Path to save JSON file: " json_path
if [[ ! -w "${json_path}" ]]; then
echo "Invalid path or permission denied to write to given area."
json_path=""
fi
done
jsonOutput "${json_path}";;
-h|-\?|--help) usage;; -h|-\?|--help) usage;;
*) echo "Invalid argument"; usage; exit 1;; *) echo "Invalid argument"; usage; exit 1;;
esac esac
@@ -556,39 +615,48 @@ fi
# Parse interactive commands # Parse interactive commands
clear clear
show_menu showMenu
while [[ "${opt}" != "" ]]; do while [[ "${opt}" != "" ]]; do
clear clear
case "${opt}" in case "${opt}" in
1) detailedGitStats; show_menu;; 1) detailedGitStats; showMenu;;
2) branch="" 2) branch=""
while [[ -z "${branch}" ]]; do while [[ -z "${branch}" ]]; do
read -r -p "Which branch? " branch read -r -p "Which branch? " branch
done done
detailedGitStats "${branch}"; show_menu;; detailedGitStats "${branch}"; showMenu;;
3) changelogs; show_menu;; 3) changelogs; showMenu;;
4) author="" 4) author=""
while [[ -z "${author}" ]]; do while [[ -z "${author}" ]]; do
read -r -p "Which author? " author read -r -p "Which author? " author
done done
changelogs "${author}"; show_menu;; changelogs "${author}"; showMenu;;
5) myDailyStats; show_menu;; 5) myDailyStats; showMenu;;
6) branchTree; show_menu;; 6) json_path=""
7) branchesByDate; show_menu;; while [[ -z "${json_path}" ]]; do
8) contributors; show_menu;; read -r -p "Path to save JSON file: " json_path
9) commitsPerAuthor; show_menu;; if [[ ! -w "${json_path}" ]]; then
10) commitsPerDay; show_menu;; echo "Invalid path or permission denied to write to given area."
11) commitsByMonth; show_menu;; json_path=""
12) commitsByWeekday; show_menu;; fi
13) commitsByHour; show_menu;; done
14) author="" jsonOutput "${json_path}"; showMenu;;
7) branchTree; showMenu;;
8) branchesByDate; showMenu;;
9) contributors; showMenu;;
10) commitsPerAuthor; showMenu;;
11) commitsPerDay; showMenu;;
12) commitsByMonth; showMenu;;
13) commitsByWeekday; showMenu;;
14) commitsByHour; showMenu;;
15) author=""
while [[ -z "${author}" ]]; do while [[ -z "${author}" ]]; do
read -r -p "Which author? " author read -r -p "Which author? " author
done done
commitsByHour "${author}"; show_menu;; commitsByHour "${author}"; showMenu;;
15) suggestReviewers; show_menu;; 16) suggestReviewers; showMenu;;
q|"\n") exit;; q|"\n") exit;;
*) clear; option_picked "Pick an option from the menu"; show_menu;; *) clear; optionPicked "Pick an option from the menu"; showMenu;;
esac esac
done done

View File

@@ -94,6 +94,11 @@ see changelogs
see changelogs by author see changelogs by author
.HP .HP
.PP .PP
\fB\-j\fR, \fB\-\-json\-output\fR
.IP
save git log as a JSON formatted file to a specified area
.HP
.PP
\fB\-h\fR, \-?, \fB\-\-help\fR \fB\-h\fR, \-?, \fB\-\-help\fR
.IP .IP
display this help text in the terminal display this help text in the terminal
@@ -102,7 +107,7 @@ display this help text in the terminal
You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log, example: You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log, example:
.IP .IP
.PP .PP
.B export _GIT_SINCE="2017\-20\-01" .B export _GIT_SINCE="2017\-01\-20"
.IP .IP
.PP .PP
You can set _GIT_LIMIT for limited output log, example: You can set _GIT_LIMIT for limited output log, example:
@@ -112,6 +117,10 @@ You can set _GIT_LIMIT for limited output log, example:
You can exclude a directory from the stats by using pathspec, example: You can exclude a directory from the stats by using pathspec, example:
.PP .PP
.B export _GIT_PATHSPEC=':!directory' .B export _GIT_PATHSPEC=':!directory'
.PP
You can switch to the legacy color scheme, example:
.PP
.B export _MENU_THEME=legacy
. .
.fi .fi

View File

@@ -3,8 +3,7 @@
. tests/assert.sh -v . tests/assert.sh -v
src="./git-quick-stats" src="./git-quick-stats"
#assert "$src fail" "Invalid argument\n\nNAME\n git-quick-stats - Simple and efficient way to access various stats in a git repo\n\nSYNOPSIS\n For non-interactive mode: git-quick-stats [OPTIONS]\n For interactive mode: git-quick-stats\n\nDESCRIPTION\n Any git repository contains tons of information about commits, contributors,\n and files. Extracting this information is not always trivial, mostly because\n of a gadzillion options to a gadzillion git commands.\n\n This program allows you to see detailed information about a git repository.\n\nOPTIONS\n suggestReviewers - see best people to contact to review code\n detailedGitStats - displays a detailed list of git status\n commitsPerDay - displays a list of commits per day\n commitsByMonth - displays a list of commits per month\n commitsByWeekday - displays a list of commits per weekday\n commitsByHour - displays a list of commits per hour\n commitsByAuthorByHour - see a list of commits per hour by author\n commitsPerAuthor - displays a list of commits per author\n myDailyStats - see your current daily stats\n contributors - see a list of all contributors\n branchTree - see an ASCII graph of the git repo\n branchesByDate - show branches by date\n changelogs - see changelogs\n changelogsByAuthor - see changelogs by author\n\nADDITIONAL USAGE\n You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log\n ex: export _GIT_SINCE=2017-20-01\n You can set _GIT_LIMIT for limited output log\n ex: export _GIT_LIMIT=20\n You can exclude a directory from the stats by using pathspec\n ex: export _GIT_PATHSPEC=':!directory'\n \nCONTRIBUTION\n For details regarding contribution, please see the contribution.md document\n\nLICENSE\n This is under the MIT license. See LICENSE in the repo for more info" assert "$src fail" "Invalid argument\n\nNAME\n git-quick-stats - Simple and efficient way to access various stats in a git repo\n\nSYNOPSIS\n For non-interactive mode: git-quick-stats [OPTIONS]\n For interactive mode: git-quick-stats\n\nDESCRIPTION\n Any git repository contains tons of information about commits, contributors,\n and files. Extracting this information is not always trivial, mostly because\n of a gadzillion options to a gadzillion git commands.\n\n This program allows you to see detailed information about a git repository.\n\nOPTIONS\n -r, --suggest-reviewers\n show the best people to contact to review code\n -T, --detailed-git-stats\n give a detailed list of git stats\n -R, --git-stats-by-branch\n see detailed list of git stats by branch\n -d, --commits-per-day\n displays a list of commits per day\n -m, --commits-by-month\n displays a list of commits per month\n -w, --commits-by-weekday\n displays a list of commits per weekday\n -o, --commits-by-hour\n displays a list of commits per hour\n -A, --commits-by-author-by-hour\n displays a list of commits per hour by author\n -a, --commits-per-author\n displays a list of commits per author\n -S, --my-daily-stats\n see your current daily stats\n -C, --contributors\n see a list of everyone who contributed to the repo\n -b, --branch-tree\n show an ASCII graph of the git repo branch history\n -D, --branches-by-date\n show branches by date\n -c, --changelogs\n see changelogs\n -L, --changelogs-by-author\n see changelogs by author\n -j, --json-output\n save git log as a JSON formatted file to a specified area\n -h, -?, --help\n display this help text in the terminal\n\nADDITIONAL USAGE\n You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log\n ex: export _GIT_SINCE=\"2017-01-20\"\n You can set _GIT_LIMIT for limited output log\n ex: export _GIT_LIMIT=20\n You can exclude a directory from the stats by using pathspec\n ex: export _GIT_PATHSPEC=':!directory'\n You can set _MENU_THEME to display the legacy color scheme\n ex: export _MENU_THEME=legacy"
assert "$src fail" "Invalid argument\n\nNAME\n git-quick-stats - Simple and efficient way to access various stats in a git repo\n\nSYNOPSIS\n For non-interactive mode: git-quick-stats [OPTIONS]\n For interactive mode: git-quick-stats\n\nDESCRIPTION\n Any git repository contains tons of information about commits, contributors,\n and files. Extracting this information is not always trivial, mostly because\n of a gadzillion options to a gadzillion git commands.\n\n This program allows you to see detailed information about a git repository.\n\nOPTIONS\n -r, --suggest-reviewers\n show the best people to contact to review code\n -T, --detailed-git-stats\n give a detailed list of git stats\n -R, --git-stats-by-branch\n see detailed list of git stats by branch\n -d, --commits-per-day\n displays a list of commits per day\n -m, --commits-by-month\n displays a list of commits per month\n -w, --commits-by-weekday\n displays a list of commits per weekday\n -o, --commits-by-hour\n displays a list of commits per hour\n -A, --commits-by-author-by-hour\n displays a list of commits per hour by author\n -a, --commits-per-author\n displays a list of commits per author\n -S, --my-daily-stats\n see your current daily stats\n -C, --contributors\n see a list of everyone who contributed to the repo\n -b, --branch-tree\n show an ASCII graph of the git repo branch history\n -D, --branches-by-date\n show branches by date\n -c, --changelogs\n see changelogs\n -L, --changelogs-by-author\n see changelogs by author\n -h, -?, --help\n display this help text in the terminal\n\nADDITIONAL USAGE\n You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log\n ex: export _GIT_SINCE=\"2017-20-01\"\n You can set _GIT_LIMIT for limited output log\n ex: export _GIT_LIMIT=20\n You can exclude a directory from the stats by using pathspec\n ex: export _GIT_PATHSPEC=':!directory'"
assert_raises "$src fail" 1 assert_raises "$src fail" 1
assert_contains "$src --suggest-reviewers" "Suggested code reviewers (based on git history)" 127 assert_contains "$src --suggest-reviewers" "Suggested code reviewers (based on git history)" 127