Published on : 2026-03-11 10:07
       
       Some time ago ( 2025-07-10 ) I wrote about a small script for 
       updating and navigating Git repositories:
       
 (DIR)   Automating Git Repo Updates and Navigation with a POSIX Shell Script
       
       Since then, my workflow has evolved a bit. The script below is an 
       updated version with a few quality-of-life improvements, mainly 
       around usability and integration with my terminal and tmux 
       workflow.
       
       What This New Script Does
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       The script manages all Git repositories stored in ~/Work. 
       It performs two main tasks:
       
        * Updates every repository in the directory
        * Lets me quickly search, select and open a repository
       
       See the script in action
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       You can view the video linked below and see it in action:
       
 (BIN)  Update repositories (new script) in action
       
       Get the script
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
 (TXT)  💾 Source code
       
       Change lines 3 and 4 to update your work directory and terminal
       
       Why I Like This Approach
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       This setup keeps things simple and efficient:
       
        * all repositories update with one command
        * fuzzy search makes project selection instant
        * every repository has its own tmux session
        * everything relies on small Unix tools
       
       Tools used:
       ‾‾‾‾‾‾‾‾‾‾‾
       
        * bash
        * git
        * fzf
        * tmux
        * dunst - for notifications
        * alacritty - my terminal of choice
       
       The workflow is simple:
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
        * Update all repositories with git pull
        * Send a desktop notification when the update is finished
        * Present a repository list using fzf
        * Open the selected repository in a tmux session in a terminal
       
       This turns a plain directory of projects into a lightweight 
       project launcher.
       
       Updating All Repositories
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       The first part scans the directory for .git folders and pulls 
       updates.
       
           for gitdir in */.git; do
               [ -d "$gitdir" ] || continue
               repo="${gitdir%/.git}"
               echo "Updating $repo"
               git -C "$repo" pull --ff-only || true
           done
       
       Using --ff-only prevents accidental merge commits during automated 
       pulls. If a repository cannot fast-forward, it is simply skipped.
       
       Desktop Notification
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       Once all repositories are processed, the script sends a 
       notification:
       
           dunstify -h string:x-dunst-stack-tag:git "Git Update" \
                "All repositories has been updated"
       
       This integrates nicely with lightweight notification daemons 
       like dunst.
       
       Discovering Repositories
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       The script then searches for Git repositories inside the working 
       directory:
       
           find "$WORKDIR" -mindepth 1 -maxdepth 1 -type d \
               -exec test -d "{}/.git" \; -print
       
       The directory names are extracted, sorted, and turned into a menu 
       list for fzf. An Exit option is added so the menu can be 
       dismissed easily.
       
       Selecting a Repository
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       Repository selection is handled with fzf:
       
           repo=$(printf "%s\n" "$menu" | fzf \
               --prompt="Select repo > " \
               --height=35% \
               --border=rounded \
               --tmux)
       
       This makes navigating a large number of repositories fast 
       and convenient.
       
       Opening the Project in tmux
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       Once a repository is selected, the script checks if a tmux session 
       already exists:
       
           tmux has-session -t "$repo" 2>/dev/null ||
           tmux new-session -d -s "$repo" -c "$dir"
       
       If the session doesn't exist, it creates one in the repository 
       directory.
       
       Finally, a new terminal window (in my case alacritty) opens and 
       attaches to that session.
       
       This means every project keeps its own persistent tmux workspace.
       
       Closing Thoughts
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       
       Small scripts like this are a good reminder of how powerful 
       simple tools can be. A bit of shell scripting can replace much 
       heavier project management workflows.
       
       And like most scripts, it keeps evolving as the workflow evolves.
       
 (DIR)  Back to my phlog