Skip to content

Instantly share code, notes, and snippets.

@paranoiq
Last active May 7, 2026 11:32
Show Gist options
  • Select an option

  • Save paranoiq/6307849f7b0799ec7110ae492be19336 to your computer and use it in GitHub Desktop.

Select an option

Save paranoiq/6307849f7b0799ec7110ae492be19336 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
NO_COLOR='\033[0m'
BLUE='\033[0;34m'
YELLOW='\033[0;33m'
NO_COLOR='\033[0m'
width0=1
widthN=3
width3=40
width1=5
width2=6
width4=20
width5=40
# Function to count commits
count_commits() {
local branch="$1"
local base_branch="$2"
local ahead_behind
ahead_behind=$(git rev-list --left-right --count "$base_branch"..."$branch")
echo "$ahead_behind"
}
# Main script
#main_branch=$(git rev-parse HEAD)
main_branch=$(git show-ref -s origin/master)
current_branch=$(git rev-parse --abbrev-ref HEAD)
printf " ${NO_COLOR}%${widthN}s ${BLUE}%-${width3}s ${GREEN}%-${width1}s ${RED}%-${width2}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "#" "Branch" "Ahead" "Behind" "Last Commit" "Last Commit Message"
# Separator line for clarity
printf " ${NO_COLOR}%${widthN}s ${BLUE}%-${width3}s ${GREEN}%-${width1}s ${RED}%-${width2}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "---" "----------------------------------------" "-----" "------" "--------------------" "----------------------------------------"
format_string="%(objectname:short)@%(refname:short)@%(committerdate:relative)"
IFS=$'\n'
branches=()
index=0
for branchdata in $(git for-each-ref --sort=-authordate --format="$format_string" refs/heads/ ); do # --no-merged
sha=$(echo "$branchdata" | cut -d '@' -f1)
branch=$(echo "$branchdata" | cut -d '@' -f2)
time=$(echo "$branchdata" | cut -d '@' -f3)
if [ "$branch" == "$current_branch" ]; then
main='*'
commit_message=$(git log --format="%B" -n 1 HEAD)
else
main=" "
commit_message=$(git log --format="%B" -n 1 "$branch")
fi
description=$(echo "$commit_message" | head -n 1)
description=${description:0:80}
# Count commits ahead and behind
ahead_behind=$(count_commits "$sha" "$main_branch")
ahead=$(echo "$ahead_behind" | cut -f2)
behind=$(echo "$ahead_behind" | cut -f1)
index=$((index + 1))
branches+=("$branch")
# Display branch info
printf "${NO_COLOR}%-${width0}s ${NO_COLOR}%${widthN}s ${BLUE}%-${width3}s ${GREEN}%-${width1}s ${RED}%-${width2}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "$main" "$index" $branch $ahead $behind "$time" "$description"
done
unset IFS
if [ "$index" -eq 0 ]; then
exit 0
fi
printf "\nEnter row number to checkout (or press Enter to exit): "
read -r selection </dev/tty
if [ -z "$selection" ]; then
exit 0
fi
if ! [[ "$selection" =~ ^[0-9]+$ ]] || [ "$selection" -lt 1 ] || [ "$selection" -gt "$index" ]; then
echo "Invalid selection: $selection" >&2
exit 1
fi
target_branch="${branches[$((selection - 1))]}"
git checkout "$target_branch"
@paranoiq

paranoiq commented Jan 18, 2024

Copy link
Copy Markdown
Author

customized https://gist.github.com/schacon/e9e743dee2e92db9a464619b99e94eff (better-git-branch.sh)

changes:

  • references against origin/master (instead of current branch)
  • prints all branches (including merged)
  • marks current branch
  • fixed descriptions (last commit message)

@paranoiq

paranoiq commented May 7, 2026

Copy link
Copy Markdown
Author
  • added option to checkout a branch
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment