List All Git Repositories with Modified Files
Motivation
As I’m using more than one machine to do my work, I often forget to upload updates to a git repository. It causes me to deal with unnecessary merges or even requiring me to go back to previous computer to push the changes prior to start my work.
The Solution
Keep track of all repositories that have uncommitted changes. In my case, it is sufficient because I use to push changes immediately after committing.
Low Tech
To handle this I used a simpler approach: a bash scripts that finds all repositories and filter only the ones with uncommitted changes. I’m using find
, sed
, git ls-files
and a simple for-loop
in the bash script.
Implementation and comments
modified-repos.sh
#!/usr/bin/env bash
if [ -n "$1" ]; then DIR="$1"; else DIR="$HOME"; fi
if [ "$1" == "help" ];
then
echo 'Usage: $ ./modified-repos.sh [directory-name]'
echo ' directory-name: optional parameters, defaults to $HOME'
echo 'Example: $ ./modified-repos.sh .'
exit 0;
fi
for f in $(find $DIR -name .git -type d -not -name 'node_modules' 2> /dev/null | sed 's/\/.git$/'/)
do
if [ $(git -C $f ls-files -m | wc -l) -ne 0 ]; then echo "$f"; fi
done
Handle args
Accepts: a base directory or “help” Defaults to $HOME as base directory
find command
The find
searches for .git
directories and uses the -not -name
to exclude the node_modules folder. It also ignores errors caused by directories in which the current user does not have permission.
sed command
Remove the .git
part of the directory to keep the repository root directory only.
git ls-files
The line if [ $(git -C $f ls-files -m | wc -l) -ne 0 ]; then echo "$f"; fi
is the more interesting one. Let’s break down it:
git -C <directory-name>
: allows me to run a git command from another directory
ls-files -m
: command to list modified git controlled files
wc -l
: count the number modified files given by ls-files -m
If the number of modified files is not zero, it outputs the directory name. Otherwise does nothing.
The expected output
$ ./modified-repos.sh .
May output:
./elisp/emacs-bitbucket
./elisp/mosql
./elisp/company-sql
./elisp/mopomo