diff --git a/README.md b/README.md index 0448655..e000b02 100644 --- a/README.md +++ b/README.md @@ -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 don’t think there is a single person alive who knows them all. Probably not even [Linus Torvalds](https://github.com/torvalds) himself :). -![screenshot](https://user-images.githubusercontent.com/6382002/52440487-86acde00-2b1e-11e9-9bb4-ca42ce2d0fc0.png) +![mainMenuScreenshot](https://user-images.githubusercontent.com/8818630/57544421-4891a700-7325-11e9-9cdd-034a6619ae0f.png) ## Table of Contents @@ -35,9 +35,9 @@ ## Screenshots -![screenshot-3](https://user-images.githubusercontent.com/6382002/52440631-f6bb6400-2b1e-11e9-98f4-2a75c8fc8435.png) +![commitsByWeekdayScreenshot](https://user-images.githubusercontent.com/8818630/57544420-4891a700-7325-11e9-876a-15df90bce420.png) -![screenshot-2](https://user-images.githubusercontent.com/6382002/52440598-db505900-2b1e-11e9-8f4a-bb8c55757c62.png) +![commitsByHourScreenshot](https://user-images.githubusercontent.com/8818630/57544419-47f91080-7325-11e9-82d3-57e4f98be240.png) ## Usage @@ -57,6 +57,8 @@ Possible arguments in short and long form: 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 -d, --commits-per-day displays a list of commits per day -m, --commits-by-month @@ -113,6 +115,13 @@ You can exclude directory from the stats by using [pathspec](https://git-scm.com export _GIT_PATHSPEC=':!directory' ``` +#### Color themes + +You can change to an alternative color scheme by toggling the variable `_MENU_THEME` between `default` and `alternative` + +```bash +export _MENU_THEME=alternative +``` ## Installation diff --git a/git-quick-stats b/git-quick-stats index 0065375..a33d162 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -24,6 +24,10 @@ else _limit=10 fi +# Default menu theme +# Set an alternative by typing "export _MENU_THEME=alternative" +_theme="${_MENU_THEME:=default}" + ################################################################################ # DESC: Checks to make sure the user has the appropriate utilities installed # ARGS: None @@ -76,6 +80,8 @@ OPTIONS 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 -d, --commits-per-day displays a list of commits per day -m, --commits-by-month @@ -109,7 +115,9 @@ ADDITIONAL USAGE You can set _GIT_LIMIT for limited output log ex: export _GIT_LIMIT=20 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 an alternative color scheme + ex: export _MENU_THEME=alternative" } ################################################################################ @@ -121,25 +129,46 @@ function show_menu() { local normal=$(tput sgr0) local cyan=$(tput setaf 6) local bold=$(tput bold) + local red=$(tput setaf 1) + local yellow=$(tput setaf 3) + local white=$(tput setaf 7) + local titles="" + local text="" + local nums="" + local help_txt="" - echo -e "\n${bold}${cyan} Generate: ${normal}" - echo -e "${bold} 1)${normal} Contribution stats (by author)" - echo -e "${bold} 2)${normal} Git changelogs (last $_limit days)" - echo -e "${bold} 3)${normal} Git changelogs by author" - echo -e "${bold} 4)${normal} My daily status" - echo -e "\n${bold}${cyan} List:${normal}" - echo -e "${bold} 5)${normal} Branch tree view (last $_limit)" - echo -e "${bold} 6)${normal} All branches (sorted by most recent commit)" - echo -e "${bold} 7)${normal} All contributors (sorted by name)" - echo -e "${bold} 8)${normal} Git commits per author" - echo -e "${bold} 9)${normal} Git commits per date" - echo -e "${bold} 10)${normal} Git commits per month" - echo -e "${bold} 11)${normal} Git commits per weekday" - echo -e "${bold} 12)${normal} Git commits per hour" - echo -e "${bold} 13)${normal} Git commits by author per hour" - echo -e "\n${bold}${cyan} Suggest:${normal}" - echo -e "${bold} 14)${normal} Code reviewers (based on git history)" - echo -e "\n${cyan}Please enter a menu option or press Enter to exit.${normal}" + # Adjustable color menu option + if [[ "${_theme}" == "alternative" ]]; then + titles="${bold}${cyan}" + text="${white}" + nums="${bold}" + help_txt="${cyan}" + else + titles="${bold}${red}" + text="${white}" + nums="${yellow}" + help_txt="${white}" + fi + + echo -e "\n${titles} Generate: ${normal}" + echo -e "${nums} 1)${text} Contribution stats (by author)" + echo -e "${nums} 2)${text} Contribution stats (by author) on a specific branch" + echo -e "${nums} 3)${text} Git changelogs (last $_limit days)" + echo -e "${nums} 4)${text} Git changelogs by author" + echo -e "${nums} 5)${text} My daily status" + echo -e "\n${titles} List:${normal}" + echo -e "${nums} 6)${text} Branch tree view (last $_limit)" + echo -e "${nums} 7)${text} All branches (sorted by most recent commit)" + echo -e "${nums} 8)${text} All contributors (sorted by name)" + echo -e "${nums} 9)${text} Git commits per author" + echo -e "${nums} 10)${text} Git commits per date" + echo -e "${nums} 11)${text} Git commits per month" + echo -e "${nums} 12)${text} Git commits per weekday" + echo -e "${nums} 13)${text} Git commits per hour" + echo -e "${nums} 14)${text} Git commits by author per hour" + echo -e "\n${titles} Suggest:${normal}" + echo -e "${nums} 15)${text} Code reviewers (based on git history)" + echo -e "\n${help_txt}Please enter a menu option or press Enter to exit.${normal}" echo -n "> " read -r opt } @@ -165,73 +194,97 @@ function option_picked() { # OUTS: None ################################################################################ function detailedGitStats() { - option_picked "Contribution stats (by author):" - git -c log.showSignature=false log --use-mailmap --no-merges --numstat \ + 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 + + # Prompt message + if [[ $is_branch_existing && -n "${_branch}" ]]; then + option_picked "Contribution stats (by author) on ${_branch} branch:" + elif [[ -n "${branch}" && -z "${_branch}" ]]; then + option_picked "Branch \"${branch}\" does not exist.\nContribution stats (by author) on the current branch:" + else + option_picked "Contribution stats (by author) on the current branch:" + fi + + git -c log.showSignature=false log ${_branch} --use-mailmap --no-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) { - printf "\t%s:\n", author + function printStats(author) { + printf "\t%s:\n", author - if(more["total"] > 0) { - printf "\t insertions: %d (%.0f%%)\n", more[author], \ - (more[author] / more["total"] * 100) - } - - if(less["total"] > 0) { - printf "\t deletions: %d (%.0f%%)\n", less[author], \ - (less[author] / less["total"] * 100) - } - - if(file["total"] > 0) { - printf "\t files: %d (%.0f%%)\n", file[author], \ - (file[author] / file["total"] * 100) - } - - if(commits["total"] > 0) { - printf "\t commits: %d (%.0f%%)\n", commits[author], \ - (commits[author] / commits["total"] * 100) - } - - if (first[author] != "") { - printf "\t lines changed: %s\n", more[author] + less[author] - printf "\t first commit: %s\n", first[author] - printf "\t last commit: %s\n", last[author] - } - - printf "\n" - } - - /^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) + if(more["total"] > 0) { + printf "\t insertions: %d (%.0f%%)\n", more[author], \ + (more[author] / more["total"] * 100) } - } - printStats("total") - }' + + if(less["total"] > 0) { + printf "\t deletions: %d (%.0f%%)\n", less[author], \ + (less[author] / less["total"] * 100) + } + + if(file["total"] > 0) { + printf "\t files: %d (%.0f%%)\n", file[author], \ + (file[author] / file["total"] * 100) + } + + if(commits["total"] > 0) { + printf "\t commits: %d (%.0f%%)\n", commits[author], \ + (commits[author] / commits["total"] * 100) + } + + if (first[author] != "") { + printf "\t lines changed: %s\n", more[author] + less[author] + printf "\t first commit: %s\n", first[author] + printf "\t last commit: %s\n", last[author] + } + + printf "\n" + } + + /^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) + } + } + printStats("total") + }' } ################################################################################ @@ -492,6 +545,12 @@ if [[ "$#" -eq 1 ]]; then case "$1" in -r|--suggest-reviewers) suggestReviewers;; -T|--detailed-git-stats) detailedGitStats;; + -R|--git-stats-by-branch) + branch="" + while [[ -z "${branch}" ]]; do + read -r -p "Which branch? " branch + done + detailedGitStats "${branch}";; -b|--branch-tree) branchTree;; -d|--commits-per-day) commitsPerDay;; -a|--commits-per-author) commitsPerAuthor;; @@ -529,27 +588,32 @@ while [[ "${opt}" != "" ]]; do clear case "${opt}" in 1) detailedGitStats; show_menu;; - 2) changelogs; show_menu;; - 3) author="" + 2) branch="" + while [[ -z "${branch}" ]]; do + read -r -p "Which branch? " branch + done + detailedGitStats "${branch}"; show_menu;; + 3) changelogs; show_menu;; + 4) author="" while [[ -z "${author}" ]]; do read -r -p "Which author? " author done changelogs "${author}"; show_menu;; - 4) myDailyStats; show_menu;; - 5) branchTree; show_menu;; - 6) branchesByDate; show_menu;; - 7) contributors; show_menu;; - 8) commitsPerAuthor; show_menu;; - 9) commitsPerDay; show_menu;; - 10) commitsByMonth; show_menu;; - 11) commitsByWeekday; show_menu;; - 12) commitsByHour; show_menu;; - 13) author="" + 5) myDailyStats; show_menu;; + 6) branchTree; show_menu;; + 7) branchesByDate; show_menu;; + 8) contributors; show_menu;; + 9) commitsPerAuthor; show_menu;; + 10) commitsPerDay; show_menu;; + 11) commitsByMonth; show_menu;; + 12) commitsByWeekday; show_menu;; + 13) commitsByHour; show_menu;; + 14) author="" while [[ -z "${author}" ]]; do read -r -p "Which author? " author done commitsByHour "${author}"; show_menu;; - 14) suggestReviewers; show_menu;; + 15) suggestReviewers; show_menu;; q|"\n") exit;; *) clear; option_picked "Pick an option from the menu"; show_menu;; esac diff --git a/git-quick-stats.1 b/git-quick-stats.1 index b98af27..e39592f 100644 --- a/git-quick-stats.1 +++ b/git-quick-stats.1 @@ -24,12 +24,16 @@ This program allows you to see detailed information about a git repository. show the best people to contact to review code .HP .PP -.PP \fB\-T\fR, \fB\-\-detailed\-git\-stats\fR .IP give a detailed list of git stats .HP .PP +\fB\-R\fR, \fB\-\-git\-stats\-by\-branch\fR +.IP +see detailed list of git stats by branch +.HP +.PP \fB\-d\fR, \fB\-\-commits\-per\-day\fR .IP displays a list of commits per day @@ -108,6 +112,10 @@ You can set _GIT_LIMIT for limited output log, example: You can exclude a directory from the stats by using pathspec, example: .PP .B export _GIT_PATHSPEC=':!directory' +.PP +You can switch to an alternative color scheme, example: +.PP +.B export _MENU_THEME=alternative . .fi diff --git a/tests/commands_test.sh b/tests/commands_test.sh index 8d6fcaf..92c7314 100755 --- a/tests/commands_test.sh +++ b/tests/commands_test.sh @@ -4,7 +4,7 @@ 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 -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 "$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'\n You can set _MENU_THEME to display an alternative color scheme\n ex: export _MENU_THEME=alternative" assert_raises "$src fail" 1 assert_contains "$src --suggest-reviewers" "Suggested code reviewers (based on git history)" 127