Last active
April 9, 2025 21:56
-
-
Save FBen3/22d879b551143370888ddab8ff374aad to your computer and use it in GitHub Desktop.
Custom Git Branch output
This file contains hidden or 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/sh | |
# Colors | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
BLUE='\033[0;34m' | |
YELLOW='\033[0;33m' | |
NO_COLOR='\033[0m' | |
# Column widths | |
width1=5 | |
width2=6 | |
width3=30 | |
width4=20 | |
width5=40 | |
# Check for flags | |
FROM_CURRENT=false | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
--from-current) | |
FROM_CURRENT=true | |
;; | |
*) | |
echo "Unknown option: $1" | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
# Function to print output | |
print_line() { | |
local ahead="$1" | |
local behind="$2" | |
local branch="$3" | |
local last_commit="$4" | |
local branch_desc="$5" | |
printf "${GREEN}%-${width1}s ${RED}%-${width2}s ${BLUE}%-${width3}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "$ahead" "$behind" "$branch" "$last_commit" "$branch_desc" | |
} | |
print_line "Ahead" "Behind" "Branch" "Last Commit" " " | |
print_line "-----" "------" "------------------------------" "-------------------" " " | |
# Compute ahead/behind for each branch relative to its remote | |
normal_mode() { | |
local current_branch | |
current_branch=$(git rev-parse --abbrev-ref HEAD) | |
format_string="%(refname:short)@%(committerdate:relative)@%(objectname:short)" | |
git for-each-ref --sort=-committerdate --format="$format_string" refs/remotes/origin/* | grep -v '^origin/HEAD$' | while IFS='@' read -r remote_branch time sha; do | |
local_branch=${remote_branch#origin/} | |
# Skip if it’s exactly 'origin' (sometimes shows up) | |
if [ "$local_branch" = "origin" ]; then | |
continue | |
fi | |
# Compute ahead/behind if a local branch with same name exists | |
if git show-ref --verify --quiet "refs/heads/$local_branch"; then | |
ahead_behind=$(git rev-list --left-right --count "$remote_branch...$local_branch") | |
ahead=$(echo "$ahead_behind" | cut -f2) | |
behind=$(echo "$ahead_behind" | cut -f1) | |
else | |
ahead="-" | |
behind="-" | |
fi | |
# Optional branch description | |
description=$(git config branch."$local_branch".description) | |
# Prefix current branch with '*' | |
branch_label="$local_branch" | |
if [ "$local_branch" = "$current_branch" ]; then | |
branch_label="* $local_branch" | |
fi | |
print_line "$ahead" "$behind" "$branch_label" "$time" "$description" | |
done | |
} | |
# Compute ahead/behind for each remote relative to HEAD | |
from_current_mode() { | |
local current_branch | |
current_branch=$(git rev-parse --abbrev-ref HEAD) | |
local current_sha | |
current_sha=$(git rev-parse HEAD) | |
format_string="%(refname:short)@%(committerdate:relative)@%(objectname:short)" | |
git for-each-ref --sort=-committerdate --format="$format_string" refs/remotes/origin/* | grep -v '^origin/HEAD$' | while IFS='@' read -r remote_branch time remote_sha; do | |
# Skip if it’s exactly 'origin' | |
[ "$remote_branch" = "origin" ] && continue | |
# Compute ahead/behind relative to HEAD | |
ahead_behind=$(git rev-list --left-right --count "$current_sha...$remote_sha") | |
ahead=$(echo "$ahead_behind" | cut -f2) | |
behind=$(echo "$ahead_behind" | cut -f1) | |
description="" | |
print_line "$ahead" "$behind" "$remote_branch" "$time" "$description" | |
done | |
} | |
# Main | |
if $FROM_CURRENT; then | |
from_current_mode | |
else | |
normal_mode | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following is adapted from Scott Chacon's better-git-branch.sh
The script can be aliased to any Git command, e.g.
git config --global alias.bb '!~/bin/git-branch-table.sh'
It has 2 modes:
default : for each local branch, it outputs how ahead or behind it is from its remote counterpart
--from-current
: for each remote, it outputs how ahead or behind it is fromHEAD
If you have the following scenario:
And you're on
main
git bb
:git bb --from-current
: