Skip to content

Instantly share code, notes, and snippets.

@iguatemigarin
Created July 5, 2024 11:57
Show Gist options
  • Save iguatemigarin/f2fb5abf4a0e164dfad875f17500afe1 to your computer and use it in GitHub Desktop.
Save iguatemigarin/f2fb5abf4a0e164dfad875f17500afe1 to your computer and use it in GitHub Desktop.
Git Checkout Interactive
#!/bin/bash
set -e
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# Check if in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}Error: Not a git repo${NC}" >&2
exit 1
fi
# Get the 10 most recently checked out branches
recent_branches=($(git reflog | grep -E 'checkout: moving from .+ to' | awk '{print $NF}' | awk '!seen[$0]++' | head -n 10))
# Check if there are any branches
if [ ${#recent_branches[@]} -eq 0 ]; then
echo -e "${YELLOW}No recent branch checkouts found.${NC}"
exit 0
fi
# Add "Cancel" option
recent_branches+=("Cancel")
# Function to display branches
display_branches() {
local current=$1
local first_run=$2
if [ "$first_run" = true ]; then
echo -e "${CYAN}Select a branch to checkout ${NC}${BOLD}(use arrow keys, press Enter to select):${NC}"
else
# Move cursor up to the start of the branch list
for ((i=0; i<${#recent_branches[@]}; i++)); do
echo -en "\033[A"
done
fi
for i in "${!recent_branches[@]}"; do
if [ $i -eq $current ]; then
echo -en "\033[K${GREEN}${BOLD}> ${recent_branches[$i]}${NC}\n"
else
echo -en "\033[K ${recent_branches[$i]}\n"
fi
done
}
# Arrow key navigation
current=0
display_branches $current true
while true; do
# Read a single character
read -s -n 1 key
# Handle arrow keys
if [[ $key == $'\e' ]]; then
read -s -n 2 key
if [[ $key == "[A" ]]; then # Up arrow
if ((current > 0)); then
((current--))
display_branches $current false
fi
elif [[ $key == "[B" ]]; then # Down arrow
if ((current < ${#recent_branches[@]} - 1)); then
((current++))
display_branches $current false
fi
fi
elif [[ $key == "" ]]; then # Enter key
break
fi
done
# Clear the branch list
for ((i=0; i<${#recent_branches[@]}+1; i++)); do
echo -en "\033[A" # Move cursor up
echo -en "\033[K" # Clear line
done
# Handle selection
selected="${recent_branches[$current]}"
if [ "$selected" = "Cancel" ]; then
echo -e "${YELLOW}Operation cancelled.${NC}"
exit 0
elif [ -n "$selected" ]; then
echo -e "${CYAN}${BOLD}Checking out $selected${NC}"
echo
if git checkout "$selected"; then
echo
else
echo
echo -e "${RED}Failed to switch to branch '${BOLD}$selected${NC}${RED}'${NC}"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment