Skip to content

Instantly share code, notes, and snippets.

@aaronedev
Last active April 11, 2025 06:58
Show Gist options
  • Save aaronedev/f27a7e95e21ba559dbe8aea9dfc4e673 to your computer and use it in GitHub Desktop.
Save aaronedev/f27a7e95e21ba559dbe8aea9dfc4e673 to your computer and use it in GitHub Desktop.
Bash Script: Auto-Update Multiple Git Repositories | home git repository updater ✅
#!/bin/bash
# File: ~/.local/bin/update-repos.sh
# Make sure to chmod +x this script after creating it
# Define color variables for styling output
BLUE='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[1;34m'
MAGENTA='\033[1;35m'
NC='\033[0m'
repos=(
"$HOME/dotfiles"
"$HOME/Templates/dotfiles"
"$HOME/vaults/bbq"
"$HOME/vaults/vault"
"$HOME/vaults/cheatsheets"
"$HOME/Pictures/wallz"
"$HOME/Templates/fatusb-dotfiles"
"$HOME/Templates/theme-generator"
"$HOME/Templates/dotfiles-archive"
"$HOME/repos/hyprland-autoname-workspaces"
"$HOME/repos/bat-theme"
"$HOME/repos/bat"
"$HOME/repos/Vortex"
"$HOME/repos/aaronsamuel"
"$HOME/repos/glamour"
"$HOME/repos/ascii-matrix"
"$HOME/repos/Adwaita-for-Steam"
"$HOME/repos/paru"
)
echo -e "${MAGENTA}Starting repository update...${NC}"
echo ""
for repo in "${repos[@]}"; do
if [ -d "$repo/.git" ]; then
echo -e "${BLUE}Processing repository:${NC} ${YELLOW}$repo${NC}"
cd "$repo" || {
echo -e "${RED}Failed to change directory to $repo. Skipping.${NC}"
continue
}
# Check if there are uncommitted changes
if [ -n "$(git status --porcelain)" ]; then
echo -e "${RED}Local changes detected in $repo.${NC}"
# Option 1: Automatically commit changes with a generic message:
git add -A
git commit -m "Auto-commit before pull on $(date)" || echo -e "${YELLOW}Nothing to commit in $repo.${NC}"
# Option 2: Or you can choose to skip auto committing.
# Uncomment the following line to prompt for manual commit instead.
# echo -e "${YELLOW}Please commit your changes manually in $repo.${NC}"
else
echo -e "${BLUE}No local changes detected in $repo.${NC}"
fi
# Pull latest changes
echo -e "${MAGENTA}Pulling latest changes for $repo...${NC}"
git pull
echo -e "${BLUE}Finished updating $repo${NC}"
echo ""
else
echo -e "${RED}$repo is not a git repository. Skipping.${NC}"
echo ""
fi
done
echo -e "${MAGENTA}All repositories have been processed. ✅${NC}"
#!/bin/bash
# File: ~/.local/bin/update-repos.sh
# Make sure to chmod +x this script after creating it
# Define color variables for styling output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[1;34m'
MAGENTA='\033[1;35m'
CYAN='\033[1;36m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# Define special symbols
CHECK=""
CROSS=""
ARROW=""
STAR=""
UPDATE=""
# Function to display a repository header
repo_header() {
echo -e "\n${BOLD}${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${BLUE}${YELLOW}Repository:${NC} ${CYAN}$1${BLUE} ${NC}${BLUE}${NC}"
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}\n"
}
# Function to display status messages
status_msg() {
local color=$1
local symbol=$2
local message=$3
echo -e "${color}${symbol} ${message}${NC}"
}
# List of repositories to update
repos=(
"$HOME/dotfiles"
"$HOME/Templates/dotfiles"
"$HOME/vaults/bbq"
"$HOME/vaults/vault"
"$HOME/vaults/cheatsheets"
"$HOME/Pictures/wallz"
"$HOME/Templates/fatusb-dotfiles"
"$HOME/Templates/theme-generator"
"$HOME/Templates/dotfiles-archive"
"$HOME/repos/hyprland-autoname-workspaces"
"$HOME/repos/bat-theme"
"$HOME/repos/bat"
"$HOME/repos/Vortex"
"$HOME/repos/aaronsamuel"
"$HOME/repos/glamour"
"$HOME/repos/ascii-matrix"
"$HOME/repos/Adwaita-for-Steam"
"$HOME/repos/paru"
)
# Display a fancy header
echo -e "\n${BOLD}${MAGENTA}╔═══════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${MAGENTA}║ REPOSITORY UPDATE SCRIPT - $(date +"%Y-%m-%d")${NC}"
echo -e "${BOLD}${MAGENTA}╚═══════════════════════════════════════════════════╝${NC}\n"
# Counter for statistics
total_repos=0
updated_repos=0
skipped_repos=0
error_repos=0
committed_repos=0
# Process each repository
for repo in "${repos[@]}"; do
((total_repos++))
if [ -d "$repo/.git" ]; then
repo_header "$repo"
cd "$repo" || {
status_msg "$RED" "$CROSS" "Failed to change directory. Skipping."
((error_repos++))
continue
}
# Store the current commit hash before pulling
old_commit=$(git rev-parse HEAD)
# Check for uncommitted changes
if [ -n "$(git status --porcelain)" ]; then
status_msg "$YELLOW" "!" "Local changes detected"
# Auto-commit changes
git add -A
if git commit -m "Auto-commit before pull on $(date +"%Y-%m-%d %H:%M:%S")"; then
status_msg "$GREEN" "$CHECK" "Changes committed successfully"
((committed_repos++))
else
status_msg "$YELLOW" "!" "Nothing to commit or commit failed"
fi
else
status_msg "$BLUE" "$CHECK" "Working directory clean"
fi
# Pull latest changes with more visible output
echo -e "\n${CYAN}${ARROW} Checking for updates...${NC}"
# Capture the pull output to check for updates
pull_output=$(git pull 2>&1)
pull_status=$?
# Get the new commit hash
new_commit=$(git rev-parse HEAD)
# Handle the pull result with more distinctive styling
if [ $pull_status -ne 0 ]; then
status_msg "$RED" "$CROSS" "Pull failed with error"
echo -e "${RED}$pull_output${NC}"
((error_repos++))
elif [[ "$pull_output" == *"Already up to date"* ]]; then
status_msg "$BLUE" "$CHECK" "Repository already up to date"
else
# Count changes to show what was updated
commit_count=$(git rev-list --count $old_commit..$new_commit)
if [ "$commit_count" -gt 0 ]; then
echo -e "\n${BOLD}${GREEN}╔════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${GREEN}${STAR} ${YELLOW}UPDATES FOUND AND APPLIED${GREEN} ${STAR}${NC}"
echo -e "${BOLD}${GREEN}╚════════════════════════════════════════════════════╝${NC}"
# Show a summary of the changes
echo -e "\n${CYAN}${UPDATE} Update Summary:${NC}"
git --no-pager log --oneline --pretty=format:"${GREEN}➤ %h${NC} - %s" $old_commit..$new_commit
echo
((updated_repos++))
else
status_msg "$GREEN" "$CHECK" "Pull completed, no new commits"
fi
fi
echo -e "\n${BLUE}${CHECK} Finished processing repository${NC}\n"
else
status_msg "$RED" "$CROSS" "$repo is not a git repository. Skipping."
((skipped_repos++))
fi
# Visual separator between repositories
echo -e "${MAGENTA}────────────────────────────────────────────────────────────${NC}"
done
# Display summary statistics
echo -e "\n${BOLD}${MAGENTA}╔═══════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${MAGENTA}║ UPDATE SUMMARY ║${NC}"
echo -e "${BOLD}${MAGENTA}╚═══════════════════════════════════════════════════╝${NC}\n"
echo -e "${CYAN}Total repositories processed:${NC} ${BOLD}$total_repos${NC}"
echo -e "${GREEN}Repositories updated:${NC} ${BOLD}$updated_repos${NC}"
echo -e "${YELLOW}Repositories with commits:${NC} ${BOLD}$committed_repos${NC}"
echo -e "${RED}Repositories with errors:${NC} ${BOLD}$error_repos${NC}"
echo -e "${BLUE}Repositories skipped:${NC} ${BOLD}$skipped_repos${NC}"
echo -e "\n${BOLD}${GREEN}Update completed at $(date +"%H:%M:%S") ${CHECK}${NC}\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment