From 8c1d81a29da24e8f863440ecd30f8f34b0008952 Mon Sep 17 00:00:00 2001 From: Ben Cotton Date: Wed, 26 Jun 2024 09:53:44 -0400 Subject: [PATCH 1/3] Add a list of new contributors This reports generates a list of all contributors whose first commit was after a specified date. Fixes #169 Signed-off-by: Ben Cotton --- README.md | 2 ++ git-quick-stats | 90 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f4dcfe2..dd5b13d 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,8 @@ LIST OPTIONS show branches by date -C, --contributors see a list of everyone who contributed to the repo + -n, --new-contributors + list everyone who made their first contribution since a specified date -a, --commits-per-author displays a list of commits per author -d, --commits-per-day diff --git a/git-quick-stats b/git-quick-stats index 1286f95..5ced56a 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -182,6 +182,8 @@ LIST OPTIONS show branches by date -C, --contributors see a list of everyone who contributed to the repo + -n, --new-contributors + list everyone who made their first contribution since a specified date -a, --commits-per-author displays a list of commits per author -d, --commits-per-day @@ -274,18 +276,19 @@ function showMenu() { printf %b "${NUMS} 8)${TEXT} Branch tree view (last $_limit)\\n" printf %b "${NUMS} 9)${TEXT} All branches (sorted by most recent commit)\\n" printf %b "${NUMS} 10)${TEXT} All contributors (sorted by name)\\n" - printf %b "${NUMS} 11)${TEXT} Git commits per author\\n" - printf %b "${NUMS} 12)${TEXT} Git commits per date\\n" - printf %b "${NUMS} 13)${TEXT} Git commits per month\\n" - printf %b "${NUMS} 14)${TEXT} Git commits per year\\n" - printf %b "${NUMS} 15)${TEXT} Git commits per weekday\\n" - printf %b "${NUMS} 16)${TEXT} Git commits per weekday by author\\n" - printf %b "${NUMS} 17)${TEXT} Git commits per hour\\n" - printf %b "${NUMS} 18)${TEXT} Git commits per hour by author\\n" - printf %b "${NUMS} 19)${TEXT} Git commits per timezone\\n" - printf %b "${NUMS} 20)${TEXT} Git commits per timezone by author\\n" + printf %b "${NUMS} 11)${TEXT} New contributors\\n" + printf %b "${NUMS} 12)${TEXT} Git commits per author\\n" + printf %b "${NUMS} 13)${TEXT} Git commits per date\\n" + printf %b "${NUMS} 14)${TEXT} Git commits per month\\n" + printf %b "${NUMS} 15)${TEXT} Git commits per year\\n" + printf %b "${NUMS} 16)${TEXT} Git commits per weekday\\n" + printf %b "${NUMS} 17)${TEXT} Git commits per weekday by author\\n" + printf %b "${NUMS} 18)${TEXT} Git commits per hour\\n" + printf %b "${NUMS} 19)${TEXT} Git commits per hour by author\\n" + printf %b "${NUMS} 20)${TEXT} Git commits per timezone\\n" + printf %b "${NUMS} 21)${TEXT} Git commits per timezone by author\\n" printf %b "\\n${TITLES} Suggest:\\n" - printf %b "${NUMS} 21)${TEXT} Code reviewers (based on git history)\\n" + printf %b "${NUMS} 22)${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 @@ -685,6 +688,26 @@ function contributors() { --format='%aN' $_log_options $_pathspec | sort -u | cat -n } +################################################################################ +# DESC: Lists all new contributors to a repo since the specified time +# ARGS: $newDate (required): Cutoff date for being considered "new" +# OUTS: None +################################################################################ +function newContributors() { + optionPicked "New contributors since $newDate:" + local contributors=$(git -c log.showSignature=false log --use-mailmap $_merges \ + "$_since" "$_until" --format='%aE' $_log_options \ + $_pathspec | sort -u) + for c in $contributors; do + local firstCommit=$(git -c log.showSignature=false log --author="$c" \ + --reverse --use-mailmap $_merges "$_since" "$_until" \ + --format='%at' $_log_options $_pathspec | head -n 1) + if [[ $firstCommit -ge $(date -d "$newDate" +%s) ]]; then + echo "$c" + fi + done +} + ################################################################################ # DESC: Displays the number of commits and percentage contributed to the repo # per author and sorts them by contribution percentage @@ -1004,6 +1027,20 @@ if [[ "$#" -eq 1 ]]; then -b|--branch-tree) branchTree;; -D|--branches-by-date) branchesByDate;; -C|--contributors) contributors;; + -n|--new-contributors) + newDate="" + while [[ -z "${newDate}" ]]; do + read -r -p "Since what date? " newDate + # Test if the date provide is valid and try again if it isn't. + # date(1) is pretty accepting of time stamps but you never know + # what people may try. This script doesn't provide any additional + # output for a bad date since `date`'s STDERR already contains + # useful information. + if [ ! $(date -d "${newDate}" +%s) ]; then + newDate="" + fi + done + newContributors "${newDate}";; -a|--commits-per-author) commitsPerAuthor;; -d|--commits-per-day) commitsPerDay;; -Y|--commits-by-year ) commitsByYear;; @@ -1083,29 +1120,38 @@ while [[ "${opt}" != "" ]]; do 8) branchTree; showMenu;; 9) branchesByDate; showMenu;; 10) contributors; showMenu;; - 11) commitsPerAuthor; showMenu;; - 12) commitsPerDay; showMenu;; - 13) commitsByMonth; showMenu;; - 14) commitsByYear; showMenu;; - 15) commitsByWeekday; showMenu;; - 16) author="" + 11) newDate="" + while [[ -z "${newDate}" ]]; do + read -r -p "Since what date? " newDate + # Test if the date provide is valid and try again if it isn't. + if [ ! $(date -d "${newDate}" +%s) ]; then + newDate="" + fi + done + newContributors "${newDate}"; showMenu;; + 12) commitsPerAuthor; showMenu;; + 13) commitsPerDay; showMenu;; + 14) commitsByMonth; showMenu;; + 15) commitsByYear; showMenu;; + 16) commitsByWeekday; showMenu;; + 17) author="" while [[ -z "${author}" ]]; do read -r -p "Which author? " author done commitsByWeekday "${author}"; showMenu;; - 17) commitsByHour; showMenu;; - 18) author="" + 18) commitsByHour; showMenu;; + 19) author="" while [[ -z "${author}" ]]; do read -r -p "Which author? " author done commitsByHour "${author}"; showMenu;; - 19) commitsByTimezone; showMenu;; - 20) author="" + 20) commitsByTimezone; showMenu;; + 21) author="" while [[ -z "${author}" ]]; do read -r -p "Which author? " author done commitsByTimezone "${author}"; showMenu;; - 21) suggestReviewers; showMenu;; + 22) suggestReviewers; showMenu;; q|"\n") exit;; *) clear; optionPicked "Pick an option from the menu"; showMenu;; esac From fe2df31c360c8893263bc3e59c9dcd1ec124b79e Mon Sep 17 00:00:00 2001 From: Ben Cotton Date: Thu, 19 Sep 2024 11:57:38 -0400 Subject: [PATCH 2/3] Address review feedback * Indicate how we're sorting new contributors * Don't fork for `date` checks * Include reference in the manpage Signed-off-by: Ben Cotton --- git-quick-stats | 6 +++--- git-quick-stats.1 | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/git-quick-stats b/git-quick-stats index 5ced56a..9244623 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -276,7 +276,7 @@ function showMenu() { printf %b "${NUMS} 8)${TEXT} Branch tree view (last $_limit)\\n" printf %b "${NUMS} 9)${TEXT} All branches (sorted by most recent commit)\\n" printf %b "${NUMS} 10)${TEXT} All contributors (sorted by name)\\n" - printf %b "${NUMS} 11)${TEXT} New contributors\\n" + printf %b "${NUMS} 11)${TEXT} New contributors (sorted by email)\\n" printf %b "${NUMS} 12)${TEXT} Git commits per author\\n" printf %b "${NUMS} 13)${TEXT} Git commits per date\\n" printf %b "${NUMS} 14)${TEXT} Git commits per month\\n" @@ -1036,7 +1036,7 @@ if [[ "$#" -eq 1 ]]; then # what people may try. This script doesn't provide any additional # output for a bad date since `date`'s STDERR already contains # useful information. - if [ ! $(date -d "${newDate}" +%s) ]; then + if ! date -d "${newDate}" +%s > /dev/null 2>&1; then newDate="" fi done @@ -1124,7 +1124,7 @@ while [[ "${opt}" != "" ]]; do while [[ -z "${newDate}" ]]; do read -r -p "Since what date? " newDate # Test if the date provide is valid and try again if it isn't. - if [ ! $(date -d "${newDate}" +%s) ]; then + if ! date -d "${newDate}" +%s > /dev/null 2>&1; then newDate="" fi done diff --git a/git-quick-stats.1 b/git-quick-stats.1 index 55a05f6..f9ea257 100644 --- a/git-quick-stats.1 +++ b/git-quick-stats.1 @@ -70,6 +70,11 @@ show branches by date see a list of everyone who contributed to the repo .HP .PP +\fB\-n\fR, \fB\-\-new\-contributors\fR +.IP +list everyone who made their first contribution since a specified date +.HP +.PP \fB\-a\fR, \fB\-\-commits\-per\-author\fR .IP displays a list of commits per author From 7d5087795eefaddf1d309d9573542d4aa14a615d Mon Sep 17 00:00:00 2001 From: Ben Cotton Date: Thu, 19 Sep 2024 14:28:41 -0400 Subject: [PATCH 3/3] Address more feedback * Add date examples to prompts * Update tests Signed-off-by: Ben Cotton --- git-quick-stats | 4 ++-- tests/commands_test.sh | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/git-quick-stats b/git-quick-stats index 9244623..ad96227 100755 --- a/git-quick-stats +++ b/git-quick-stats @@ -1030,7 +1030,7 @@ if [[ "$#" -eq 1 ]]; then -n|--new-contributors) newDate="" while [[ -z "${newDate}" ]]; do - read -r -p "Since what date? " newDate + read -r -p "Since what date? (e.g. '2023-04-13', '13 April 2023', 'last Thursday') " newDate # Test if the date provide is valid and try again if it isn't. # date(1) is pretty accepting of time stamps but you never know # what people may try. This script doesn't provide any additional @@ -1122,7 +1122,7 @@ while [[ "${opt}" != "" ]]; do 10) contributors; showMenu;; 11) newDate="" while [[ -z "${newDate}" ]]; do - read -r -p "Since what date? " newDate + read -r -p "Since what date? (e.g. '2023-04-13', '13 April 2023', 'last Thursday') " newDate # Test if the date provide is valid and try again if it isn't. if ! date -d "${newDate}" +%s > /dev/null 2>&1; then newDate="" diff --git a/tests/commands_test.sh b/tests/commands_test.sh index bd55765..bcb5a5e 100755 --- a/tests/commands_test.sh +++ b/tests/commands_test.sh @@ -50,6 +50,8 @@ LIST OPTIONS show branches by date -C, --contributors see a list of everyone who contributed to the repo + -n, --new-contributors + list everyone who made their first contribution since a specified date -a, --commits-per-author displays a list of commits per author -d, --commits-per-day