From 82ba58e01d4ad808bcaae355366f2c06e1a3e853 Mon Sep 17 00:00:00 2001 From: Lukas Mestan Date: Sat, 11 Jan 2020 14:09:04 +0100 Subject: [PATCH 1/2] refs #88 --- git-quick-stats | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/git-quick-stats b/git-quick-stats index 3d2180a..9e2df75 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -16,6 +16,12 @@ _until=${_GIT_UNTIL:-} _pathspec=${_GIT_PATHSPEC:-} [[ -n "${_pathspec}" ]] && _pathspec="-- $_pathspec" +_nomerge=${_GIT_WITH_MERGE:-} +if [[ -n "${_nomerge}" ]]; + then _nomerge="" +else + _nomerge="--no-merges" +fi _limit=${_GIT_LIMIT:-} if [[ -n "${_limit}" ]]; @@ -218,7 +224,7 @@ function detailedGitStats() { optionPicked "Contribution stats (by author) on the current branch:" fi - git -c log.showSignature=false log ${_branch} --use-mailmap --no-merges --numstat \ + git -c log.showSignature=false log ${_branch} --use-mailmap $_nomerge --numstat \ --pretty="format:commit %H%nAuthor: %aN <%aE>%nDate: %ad%n%n%w(0,4,4)%B%n" \ $_since $_until $_pathspec | LC_ALL=C awk ' function printStats(author) { @@ -293,7 +299,7 @@ function detailedGitStats() { ################################################################################ function suggestReviewers() { 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 $_nomerge $_since $_until \ --pretty=%aN $_pathspec | head -n 100 | sort | uniq -c | sort -nr | LC_ALL=C awk ' { args[NR] = $0; } END { @@ -310,7 +316,7 @@ function suggestReviewers() { ################################################################################ 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 \ + git -c log.showSignature=false log --use-mailmap $_nomerge $_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' \ @@ -329,7 +335,7 @@ function commitsByMonth() { 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 --no-merges --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_nomerge --format='%ad %s' \ $_since $_until | grep " $i " | wc -l done | awk '{ count[$1] = $2 @@ -360,7 +366,7 @@ function commitsByWeekday() { for i in Mon Tue Wed Thu Fri Sat Sun do echo -en "\t$i\t" - git -c log.showSignature=false shortlog -n --no-merges --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_nomerge --format='%ad %s' \ $_since $_until | grep "$i " | wc -l done | awk '{ @@ -405,7 +411,7 @@ function commitsByHour() { for i in $(seq -w 0 23) do echo -ne "\t$i\t" - git -c log.showSignature=false shortlog -n --no-merges --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_nomerge --format='%ad %s' \ "${_author}" $_since $_until | grep ' '$i: | wc -l done | awk '{ count[$1] = $2 @@ -433,7 +439,7 @@ function commitsByHour() { ################################################################################ function commitsPerDay() { 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 $_nomerge $_since $_until \ --date=short --format='%ad' $_pathspec | sort | uniq -c } @@ -445,9 +451,9 @@ function commitsPerDay() { ################################################################################ function commitsPerAuthor() { optionPicked "Git commits per author:" - local authorCommits=$(git -c log.showSignature=false log --use-mailmap --no-merges \ + local authorCommits=$(git -c log.showSignature=false log --use-mailmap $_nomerge \ $_since $_until | grep -i Author: | cut -c9-) - local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap --no-merges \ + local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap $_nomerge \ $_since $_until | grep -i Co-Authored-by: | cut -c21-) if [[ -z "${coAuthorCommits}" ]] @@ -485,7 +491,7 @@ function myDailyStats() { }' echo -e "\t" $(git -c log.showSignature=false log --use-mailmap \ - --author="$(git config user.name)" --no-merges \ + --author="$(git config user.name)" $_nomerge \ --since=$(date "+%Y-%m-%dT00:00:00") \ --until=$(date "+%Y-%m-%dT23:59:59") --reverse \ | grep commit | wc -l) "commits" @@ -498,7 +504,7 @@ function myDailyStats() { ################################################################################ function contributors() { 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 $_nomerge $_since $_until \ --format='%aN' $_pathspec | sort -u | cat -n } @@ -546,14 +552,14 @@ function changelogs() { git -c log.showSignature=false log \ --use-mailmap \ - --no-merges \ + $_nomerge \ --format="%cd" \ --date=short "${_author}" $_since $_until $_pathspec \ | sort -u -r | head -n $_limit \ | while read DATE; do echo -e "\n[$DATE]" GIT_PAGER=cat git -c log.showSignature=false log \ - --use-mailmap --no-merges \ + --use-mailmap $_nomerge \ --format=" * %s (%aN)" "${_author}" \ --since=$DATE --until=$next next=$DATE From 90f9e359c38e577436da4e608254f3000bdb01b4 Mon Sep 17 00:00:00 2001 From: Tom Ice Date: Fri, 17 Jan 2020 10:53:51 -0500 Subject: [PATCH 2/2] Add view strategy to allow merge commits in stats * Users can now switch between allowing merge commits in their stats, showing only merges in the stats, or ignoring merge commits in the stats all together. Showing merges might be good for people who wish to see the entire history as git shows it by default. For this, setting the new variable _GIT_MERGE_VIEW to enable will show merge commits in the stats together with normal commits. Showing only merges might be useful for people who wish to see how much of their git history is taken up by merges alone. It can be useful for re-evaluating a particular workflow. For this, setting the new var _GIT_MERGE_VIEW to exclusive will show only merge commits in the stats. The default action is to not display merge commits. Resolves #88 --- README.md | 10 +++++++++ git-quick-stats | 51 ++++++++++++++++++++++++++---------------- git-quick-stats.1 | 12 +++++++--- tests/commands_test.sh | 2 +- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index eeb9370..97bd5b8 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ * [**Git log since and until**](#git-log-since-and-until) * [**Git log limit**](#git-log-limit) * [**Git pathspec**](#git-pathspec) +* [**Git merge view strategy**](#git-merge-view-strategy) * [**Color themes**](#color-themes) [**Installation**](#installation) @@ -159,6 +160,15 @@ You can also exclude files from the stats. Note that it works with any alphanume 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. + +```bash +export _GIT_MERGE_VIEW="enable" +export _GIT_MERGE_VIEW="exclusive" +``` + ### Color themes You can change to the legacy color scheme by toggling the variable `_MENU_THEME` between `default` and `legacy` diff --git a/git-quick-stats b/git-quick-stats index 9e2df75..aa689e8 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -7,25 +7,34 @@ set -o nounset set -o errexit +# Beginning git log date. Respects all git datetime formats _since=${_GIT_SINCE:-} [[ -n "${_since}" ]] && _since="--since=$_since" +# End of git log date. Respects all git datetime formats _until=${_GIT_UNTIL:-} [[ -n "${_until}" ]] && _until="--until=$_until" +# Set files or directories to be excluded in stats _pathspec=${_GIT_PATHSPEC:-} [[ -n "${_pathspec}" ]] && _pathspec="-- $_pathspec" -_nomerge=${_GIT_WITH_MERGE:-} -if [[ -n "${_nomerge}" ]]; - then _nomerge="" +# Set merge commit view strategy. Default is to show no merge commits +# Exclusive shows only merge commits +# Enable shows regular commits together with normal commits +_merges=${_GIT_MERGE_VIEW:-} +if [[ "${_merges,,}" == "exclusive" ]]; then + _merges="--merges" +elif [[ "${_merges,,}" == "enable" ]]; then + _merges="" else - _nomerge="--no-merges" + _merges="--no-merges" fi +# Limit git log output _limit=${_GIT_LIMIT:-} -if [[ -n "${_limit}" ]]; - then _limit=$_limit +if [[ -n "${_limit}" ]]; then + _limit=$_limit else _limit=10 fi @@ -116,6 +125,10 @@ ADDITIONAL USAGE ex: export _GIT_LIMIT=20 You can exclude directories or files from the stats by using pathspec ex: export _GIT_PATHSPEC=':!pattern' + You can set _GIT_MERGE_VIEW to view merge commits with normal commits + ex: export _GIT_MERGE_VIEW=enable + You can also set _GIT_MERGE_VIEW to only show merge commits + ex: export _GIT_MERGE_VIEW=exclusive You can set _MENU_THEME to display the legacy color scheme ex: export _MENU_THEME=legacy" } @@ -224,7 +237,7 @@ function detailedGitStats() { optionPicked "Contribution stats (by author) on the current branch:" fi - git -c log.showSignature=false log ${_branch} --use-mailmap $_nomerge --numstat \ + 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 $_pathspec | LC_ALL=C awk ' function printStats(author) { @@ -299,7 +312,7 @@ function detailedGitStats() { ################################################################################ function suggestReviewers() { optionPicked "Suggested code reviewers (based on git history):" - git -c log.showSignature=false log --use-mailmap $_nomerge $_since $_until \ + git -c log.showSignature=false log --use-mailmap $_merges $_since $_until \ --pretty=%aN $_pathspec | head -n 100 | sort | uniq -c | sort -nr | LC_ALL=C awk ' { args[NR] = $0; } END { @@ -316,7 +329,7 @@ function suggestReviewers() { ################################################################################ function jsonOutput() { optionPicked "Output log saved to file at: ${json_path:?}/output.json" - git -c log.showSignature=false log --use-mailmap $_nomerge $_since $_until \ + git -c log.showSignature=false log --use-mailmap $_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' \ @@ -335,7 +348,7 @@ function commitsByMonth() { 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 $_nomerge --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \ $_since $_until | grep " $i " | wc -l done | awk '{ count[$1] = $2 @@ -366,7 +379,7 @@ function commitsByWeekday() { for i in Mon Tue Wed Thu Fri Sat Sun do echo -en "\t$i\t" - git -c log.showSignature=false shortlog -n $_nomerge --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \ $_since $_until | grep "$i " | wc -l done | awk '{ @@ -411,7 +424,7 @@ function commitsByHour() { for i in $(seq -w 0 23) do echo -ne "\t$i\t" - git -c log.showSignature=false shortlog -n $_nomerge --format='%ad %s' \ + git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \ "${_author}" $_since $_until | grep ' '$i: | wc -l done | awk '{ count[$1] = $2 @@ -439,7 +452,7 @@ function commitsByHour() { ################################################################################ function commitsPerDay() { optionPicked "Git commits per date:"; - git -c log.showSignature=false log --use-mailmap $_nomerge $_since $_until \ + git -c log.showSignature=false log --use-mailmap $_merges $_since $_until \ --date=short --format='%ad' $_pathspec | sort | uniq -c } @@ -451,9 +464,9 @@ function commitsPerDay() { ################################################################################ function commitsPerAuthor() { optionPicked "Git commits per author:" - local authorCommits=$(git -c log.showSignature=false log --use-mailmap $_nomerge \ + local authorCommits=$(git -c log.showSignature=false log --use-mailmap $_merges \ $_since $_until | grep -i Author: | cut -c9-) - local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap $_nomerge \ + local coAuthorCommits=$(git -c log.showSignature=false log --use-mailmap $_merges \ $_since $_until | grep -i Co-Authored-by: | cut -c21-) if [[ -z "${coAuthorCommits}" ]] @@ -491,7 +504,7 @@ function myDailyStats() { }' echo -e "\t" $(git -c log.showSignature=false log --use-mailmap \ - --author="$(git config user.name)" $_nomerge \ + --author="$(git config user.name)" $_merges \ --since=$(date "+%Y-%m-%dT00:00:00") \ --until=$(date "+%Y-%m-%dT23:59:59") --reverse \ | grep commit | wc -l) "commits" @@ -504,7 +517,7 @@ function myDailyStats() { ################################################################################ function contributors() { optionPicked "All contributors (sorted by name):" - git -c log.showSignature=false log --use-mailmap $_nomerge $_since $_until \ + git -c log.showSignature=false log --use-mailmap $_merges $_since $_until \ --format='%aN' $_pathspec | sort -u | cat -n } @@ -552,14 +565,14 @@ function changelogs() { git -c log.showSignature=false log \ --use-mailmap \ - $_nomerge \ + $_merges \ --format="%cd" \ --date=short "${_author}" $_since $_until $_pathspec \ | sort -u -r | head -n $_limit \ | while read DATE; do echo -e "\n[$DATE]" GIT_PAGER=cat git -c log.showSignature=false log \ - --use-mailmap $_nomerge \ + --use-mailmap $_merges \ --format=" * %s (%aN)" "${_author}" \ --since=$DATE --until=$next next=$DATE diff --git a/git-quick-stats.1 b/git-quick-stats.1 index 05f902a..f1abbd8 100644 --- a/git-quick-stats.1 +++ b/git-quick-stats.1 @@ -1,4 +1,4 @@ -.TH git-quick-stats "1" "January 2019" "git-quick-stats" "User Commands" +.TH git-quick-stats "1" "January 2020" "git-quick-stats" "User Commands" .SH NAME .B git\-quick\-stats \- Simple and efficient way to access various stats in a git repository. @@ -105,10 +105,8 @@ display this help text in the terminal .PP .SH ADDITIONAL USAGE You can set _GIT_SINCE and _GIT_UNTIL to limit the git time log, example: -.IP .PP .B export _GIT_SINCE="2017\-01\-20" -.IP .PP You can set _GIT_LIMIT for limited output log, example: .PP @@ -118,6 +116,14 @@ You can exclude directories or files from the stats by using pathspec, example: .PP .B export _GIT_PATHSPEC=':!pattern' .PP +You can set _GIT_MERGE_VIEW to show merge commits with normal commits, example: +.PP +.B export _GIT_MERGE_VIEW="enable" +.PP +You can also set _GIT_MERGE_VIEW to only show merge commits, example: +.PP +.B export _GIT_MERGE_VIEW="exclusive" +.PP You can switch to the legacy color scheme, example: .PP .B export _MENU_THEME=legacy diff --git a/tests/commands_test.sh b/tests/commands_test.sh index 7aba1a1..ad3f823 100755 --- a/tests/commands_test.sh +++ b/tests/commands_test.sh @@ -3,7 +3,7 @@ . tests/assert.sh -v 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 -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 directories or files from the stats by using pathspec\n ex: export _GIT_PATHSPEC=':!pattern'\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 -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 directories or files from the stats by using pathspec\n ex: export _GIT_PATHSPEC=':!pattern'\n You can set _GIT_MERGE_VIEW to view merge commits with normal commits\n ex: export _GIT_MERGE_VIEW=enable\n You can also set _GIT_MERGE_VIEW to only show merge commits\n ex: export _GIT_MERGE_VIEW=exclusive\n You can set _MENU_THEME to display the legacy color scheme\n ex: export _MENU_THEME=legacy" assert_raises "$src fail" 1 assert_contains "$src --suggest-reviewers" "Suggested code reviewers (based on git history)" 127