Skip to content

Instantly share code, notes, and snippets.

@FBen3
Last active April 9, 2025 21:56
Show Gist options
  • Save FBen3/22d879b551143370888ddab8ff374aad to your computer and use it in GitHub Desktop.
Save FBen3/22d879b551143370888ddab8ff374aad to your computer and use it in GitHub Desktop.
Custom Git Branch output
#!/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
@FBen3
Copy link
Author

FBen3 commented Apr 6, 2025

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 from HEAD

If you have the following scenario:

* 07b5e92 (origin/test-branch) Update some_file.txt
| * 54bf05d (origin/test-branch-2, test-branch-2) Something something
|/  
* b22ec23 (test-branch) Something
* 6762fbf (HEAD -> main, origin/main, origin/HEAD) Clean slate
* 8f76c08 Getting ready to test git bb logic

And you're on main

git bb:

Ahead Behind Branch                         Last Commit                                                  
----- ------ ------------------------------ -------------------                                          
0     1      test-branch                    53 minutes ago                                               
0     0      test-branch-2                  54 minutes ago                                               
0     0      * main                         60 minutes ago 

git bb --from-current:

Ahead Behind Branch                         Last Commit                                                  
----- ------ ------------------------------ -------------------                                          
2     0      origin/test-branch             53 minutes ago                                               
2     0      origin/test-branch-2           54 minutes ago                                               
0     0      origin/main                    60 minutes ago  

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