Check Git Status Across All Your Projects with This Bash Script
I usually work across multiple computers for both personal and professional projects, so I keep (almost) everything on GitHub. There, I store not only software projects but also my notes (organized using the Zettelkasten method — more on that in a future post!). I also host various personal files, such as music sheets that I edit with MuseScore. Another key repository is a directory with all my configuration files (dotfiles
) for tools I use daily — Neovim, tiling window managers, bash, zsh, terminals, and more. I manage these using the legendary GNU tool stow
.
Keeping all my repositories up-to-date is essential for my daily workflow. If I forget to push changes, I risk running into annoying merge conflicts. That’s why I wrote this bash script to automatically check the status of all my git repositories.
How it checks the specified directories
I usually keep my projects inside a directory called repos/
. However, some repositories live elsewhere. For instance, I store my configuration files in ~/.dotfiles
, and when I fork Neovim plugins, I place them in ~/.local/share/nvim/lazy/
— the directory used by Neovim’s lazy.nvim. One such example is my fork of the kanagawa colorscheme.
That’s why I declare several directory variables at the beginning of the script. The base_dir
is iterated over, while the others are individual repositories assumed to contain a .git/
directory.
Here’s how those directories are declared:
base_dir="/home/daniel/Documentos/repos"dotfiles="/home/daniel/.dotfiles/"notas="/home/daniel/Documentos/Notas/"kanagawa="/home/daniel/.local/share/nvim/lazy/kanagawa.nvim"
Styles
There are a couple of things that I used for making it clean and readable. I have two variables for having bold and normal fonts using tput
:
# Font Stylesbold=$(tput bold)normal=$(tput sgr0)
I also used separators:
echo "--------------------------------------------------------------------------"
And two emojis: ✅ and ⚠️.
The logic
The script is pretty simple. It includes a function that checks each repository’s status and prints a friendly summary:
check_git_status() { local dir="$1" local label="$2"
if ! git -C "$dir" rev-parse --is-inside-work-tree > /dev/null 2>&1; then printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}❌ That's not a Git repository${normal}" return fi
local status=$(git -C "$dir" status) local shortstatus=$(git -C "$dir" status --short)
if [[ $status =~ "nothing to commit, working tree clean" ]]; then printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}✅ Updated${normal}" else printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}⚠️ Pending changes${normal}" echo "$shortstatus" fi}
Note: If your system’s default language isn’t English, you’ll need to modify the condition that matches git status output. For example, in Spanish:
# Spanishif [[ $status =~ "nada para hacer commit, el árbol de trabajo está limpio" ]]; then
The following loop iterates over all directories inside base_dir:
# Iteration in the base_dirfor dir in "$base_dir"/*; do dir_name=$(basename "$dir") if [ -d "$dir" ]; then check_git_status "$dir" "$dir_name" fidone
Then, the script checks each of the individually declared directories:
echo "--------------------------------------------------------------------------"
if [ -d "$dotfiles" ]; then check_git_status "$dotfiles" "Configuration files"fi
echo "--------------------------------------------------------------------------"
if [ -d "$notas" ]; then check_git_status "$notas" "Notas"fi
echo "--------------------------------------------------------------------------"
if [ -d "$kanagawa" ]; then check_git_status "$kanagawa" "kanagawa"fi
The complete script
So here is the full script:
#!/bin/bash
# Defines directories that are going to be usedbase_dir="/home/daniel/Documentos/repos"dotfiles="/home/daniel/.dotfiles/"notas="/home/daniel/Documentos/Notas/"kanagawa="/home/daniel/.local/share/nvim/lazy/kanagawa.nvim"
# Font Stylesbold=$(tput bold)normal=$(tput sgr0)
check_git_status() { local dir="$1" local label="$2"
if ! git -C "$dir" rev-parse --is-inside-work-tree > /dev/null 2>&1; then printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}❌ That's not a Git repository${normal}" return fi
local status=$(git -C "$dir" status) local shortstatus=$(git -C "$dir" status --short)
if [[ $status =~ "nothing to commit, working tree clean" ]]; then printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}✅ Updated${normal}" else printf "%-40s %-30s\n" "${bold}$label:${normal}" "${bold}⚠️ Pending changes${normal}" echo "$shortstatus" fi}
# Iteration in the base_dirfor dir in "$base_dir"/*; do dir_name=$(basename "$dir") if [ -d "$dir" ]; then check_git_status "$dir" "$dir_name" fidone
echo "--------------------------------------------------------------------------"
if [ -d "$dotfiles" ]; then check_git_status "$dotfiles" "Configuration files"fi
echo "--------------------------------------------------------------------------"
if [ -d "$notas" ]; then check_git_status "$notas" "Notas"fi
echo "--------------------------------------------------------------------------"
if [ -d "$kanagawa" ]; then check_git_status "$kanagawa" "kanagawa"fi
And this would be the output of it!
backend-fullstack-open: ✅ Updatedclothing-store-api-rest: ✅ Updatedd-penedo: ✅ Updatedempleo: ✅ Updatedescuela-de-columna: ✅ Updatedfullstackopen: ✅ UpdatedgeneradorDeComprobantes: ✅ Updatedjolastoki: ✅ Updatedlista-tareas-sqlite: ✅ Updatedmatafuegos-mar-del-plata: ✅ UpdatedMooc-Java: ✅ Updatedpomodb: ✅ Updatedtutoriales: ✅ Updated--------------------------------------------------------------------------Configuration files: ⚠️ Pending changes M bin/.local/bin/estatus M kitty/.config/kitty/current-theme.conf--------------------------------------------------------------------------Notas: ⚠️ Pending changes M Proyectos/dPenedo-blog/Posts/Template.md?? Proyectos/dPenedo-blog/Posts/Check-the-status-on-all-your-repositories-by-this-bash-script.md--------------------------------------------------------------------------kanagawa: ⚠️ Pending changes M lua/kanagawa/colors.lua M lua/kanagawa/highlights/editor.lua