It is very common nowadays for companies to have a big when not a huge amount of code in their repositories and, if we are lucky, all this code will be split across multiple projects and repositories. In addition to this, it is very common in this company environments that no one owns an specific project, people just work in their tasks and sometimes they change multiple projects. This environment produces a situation where when you have questions about an specific project you do not know exactly who is the best person to ask.
There is not a simple solution to solve that but, if you are using git as a version control system, one possible solution is to obtain the top committers of the project. We can do this easily with a very simple command:
git shortlog -s -n --all | head -3
This will show us the first three top committers for our project. But, we are developers, we are lazy and we like to automate and build scripts to cover more than the simple case. Then, we can build this script:
#!/bin/bash
print_help() {
echo " Do you need help or knowledge about one of our projects?
Who is the better person to ask about one of them?
Here you can find it!
TOPCOMMITTERS(1)
NAME
topcommitters - list top committers in the git projects
SYNOPSIS
topcommitters [OPTION]... [PROJECT]...
DESCRIPTION
List top committers in the git projects
There are not mandatory arguments. By default top 5 committers in all projects are listed.
-f, --folder
location of the repositories. By default ~/sourcecode
-c, --count
number of committers listed. By default 5
-p, --project
single project to be listed. ie: deliveries-service
-h, --help
show this help message.
Exit status:
0 if OK,
AUTHOR
Written by fjavierm.
REPORTING BUGS
www.binarycoders.wordpress.com
BSD 1 July, 2018 BSD
"
}
show_multiple() {
# Loop all sub-directories
for f in $dir
do
show_single $f
done
}
show_single() {
f=$1
# Only interested in directories
[ -d "${f}" ] || return
echo -en "\033[0;35m"
echo -n "${f}"
echo -en "\033[0m"
# Check if directory is a git repository
inside_git_repo="$f/$(git rev-parse --is-inside-work-tree 2>/dev/null)"
if [ "$inside_git_repo" ];
then
cd $f
basename=${PWD}
dirlen=${#basename}
# list top authors
echo -en "\n"
git shortlog -s -n --all -- . | head -${count}
cd ../
else
echo -ne "\t\t\tNot a git repository"
fi
echo
}
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-f|--folder)
FOLDER="$2"
shift # past argument
shift # past value
;;
-c|--count)
COUNT="$2"
shift # past argument
shift # past value
;;
-p|--project)
PROJECT="$2"
shift # past argument
shift # past value
;;
-h|--help)
print_help
exit 0
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
dir="$FOLDER"
count="$COUNT"
# No directory has been provided, use default
if [ -z "$dir" ]
then
dir="${HOME}/sourcecode"
fi
# No count has been provided, use 5
if [ -z "$count" ]
then
count="5"
fi
# Make sure directory ends with "/"
if [[ $dir != */ ]]
then
dir="$dir/*"
else
dir="$dir*"
fi
if [ -z "$PROJECT" ]
then
show_multiple
else
show_single $dir$PROJECT
fi
exit 0
Basically the script executes almost the same command we have seen at the beginning but it offers us a few more options.
We can list all the projects at once in our default folder ~/sourcecode:
./topcommitters.sh
We can see the help text:
./topcommitters.sh -h
We can specify where our projects are:
./topcommitters.sh -f ~/mycode
We can select where the projects are, which concrete project do we want and how many committers we want to see:
./topcommitters.sh -f ~/mycode -p ecommerce -c 3
One interesting feature is that, as you can notice, the command in the script is slightly different to the original command:
Original: git shortlog -s -n --all | head -3
Script: git shortlog -s -n --all -- . | head -${count}
This difference gives us the possibility to list committers in a folder inside the git repository even if that folder is not the repository folder. For example, imagine we have the next project structure:
big-project
-- .git
-- 3rd-party-apis
Imagine that we want to obtain information about the facebook project. If we just execute “./topcommitters.sh -p big-project” we will obtain the top committers for the whole project and this is not what we want but, with the modification of the original command in the script, we are allowed to execute “./topcommitters.sh -p big-project/facebook” and obtain the exact information we want.