Last active
April 11, 2025 06:58
-
-
Save aaronedev/f27a7e95e21ba559dbe8aea9dfc4e673 to your computer and use it in GitHub Desktop.
Bash Script: Auto-Update Multiple Git Repositories | home git repository updater ✅
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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