-
-
Save schacon/e9e743dee2e92db9a464619b99e94eff 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' | |
width1=5 | |
width2=6 | |
width3=30 | |
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) | |
printf "${GREEN}%-${width1}s ${RED}%-${width2}s ${BLUE}%-${width3}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "Ahead" "Behind" "Branch" "Last Commit" " " | |
# Separator line for clarity | |
printf "${GREEN}%-${width1}s ${RED}%-${width2}s ${BLUE}%-${width3}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "-----" "------" "------------------------------" "-------------------" " " | |
format_string="%(objectname:short)@%(refname:short)@%(committerdate:relative)" | |
IFS=$'\n' | |
for branchdata in $(git for-each-ref --sort=-authordate --format="$format_string" refs/heads/ --no-merged); do | |
sha=$(echo "$branchdata" | cut -d '@' -f1) | |
branch=$(echo "$branchdata" | cut -d '@' -f2) | |
time=$(echo "$branchdata" | cut -d '@' -f3) | |
if [ "$branch" != "$main_branch" ]; then | |
# Get branch description | |
description=$(git config branch."$branch".description) | |
# Count commits ahead and behind | |
ahead_behind=$(count_commits "$sha" "$main_branch") | |
ahead=$(echo "$ahead_behind" | cut -f2) | |
behind=$(echo "$ahead_behind" | cut -f1) | |
# Display branch info | |
printf "${GREEN}%-${width1}s ${RED}%-${width2}s ${BLUE}%-${width3}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" $ahead $behind $branch "$time" "$description" | |
fi | |
done | |
schacon
commented
Jan 13, 2024
Nice!
koool Thanks Scott!
chef kiss
wicked
One-liner with similar functionality:
git for-each-ref --color --sort=-committerdate --format=$'%(color:red)%(ahead-behind:HEAD)\t%(color:blue)%(refname:short)\t%(color:yellow)%(committerdate:relative)\t%(color:default)%(describe)' refs/heads/ --no-merged | \
sed 's/ /\t/' | \
column --separator=$'\t' --table --table-columns='Ahead,Behind,Branch Name,Last Commit,Description'
One-liner with similar functionality:
git for-each-ref --color --sort=-committerdate --format=$'%(color:red)%(ahead-behind:HEAD)\t%(color:blue)%(refname:short)\t%(color:yellow)%(committerdate:relative)\t%(color:default)%(describe)' refs/heads/ --no-merged | \ sed 's/ /\t/' | \ column --separator=$'\t' --table --table-columns='Ahead,Behind,Branch Name,Last Commit,Description'
I think ahead-behind
field was added in git 2.41
..?
Neat! A while ago I wrote https://github.com/jlebon/git-bstatus in the same vein. Some may find it overkill depending on their needs.
One-liner with similar functionality:
git for-each-ref --color --sort=-committerdate --format=$'%(color:red)%(ahead-behind:HEAD)\t%(color:blue)%(refname:short)\t%(color:yellow)%(committerdate:relative)\t%(color:default)%(describe)' refs/heads/ --no-merged | \ sed 's/ /\t/' | \ column --separator=$'\t' --table --table-columns='Ahead,Behind,Branch Name,Last Commit,Description'
for macos:
bb = !git for-each-ref --color --sort=-committerdate --format=$'%(color:red)%(ahead-behind:HEAD)\t%(color:blue)%(refname:short)\t%(color:yellow)%(committerdate:relative)\t%(color:default)%(describe)' refs/heads/ --no-merged | sed 's/ /\t/' | column -s=$'\t' -t -c 'Ahead,Behind,Branch Name,Last Commit,Description'
column
in macos is BSD (not GNU) and has different argument names.
Thanks for the amazing script !
One change for anyone not wanting two fatal errors and some more output, when you run it by mistake from a directory which is not git repo:
diff --git a/git-better-branch.sh b/git-better-branch.sh
index 6281256f32d3..47d04496658f 100755
--- a/git-better-branch.sh
+++ b/git-better-branch.sh
@@ -27,6 +27,11 @@ count_commits() {
# Main script
main_branch=$(git rev-parse HEAD)
+if [ $? -ne 0 ]; then
+ # If 'git rev-parse' failed, probably we are not in a git repo, fail now
+ exit 1
+fi
+
printf "${GREEN}%-${width1}s ${RED}%-${width2}s ${BLUE}%-${width3}s ${YELLOW}%-${width4}s ${NO_COLOR}%-${width5}s\n" "Ahead" "Behind" "Branch" "Last Commit" " "
# Separator line for clarity
I might be a bit too late, but none of the above is working out for me. Is it depecrated? or am I dumb
I'm using macos, the solution proposed by @evilr00t for macos doesn't show any output.
the .sh file gives an empty table with no branches. I did git branch -a to make sure I'm in the correct path.
Is there any suggestions?
@Azzam-Alotaibi Hey, i found out that cloning a repository only checkouts the default branch. This script only shows the branches you have checked out. And this script does not show the default branch.
It uses git for-each-ref
command to get all the branches and selects the branches that starts with refs/heads
To checkout all the remote branches at once, run this in bash:
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
git branch --track ${branch#remotes/origin/} $branch
done
I realized this script only uses local branches so if your branches change remotely this may not show accurate information. I need to test if this is the case.
One liner that works with git version 2.34.1
on Linux (bash, zsh), MacOS (bash, zsh), Windows (git bash, powershell inside of Windows Terminal):
git for-each-ref --color --sort=-committerdate --format='%(color: bold magenta)%(align:60,left)%(refname:short)%(color:bold red) %(upstream:track,nobracket)%(end)%(color:nobold yellow)%(align:58,left)%(committerdate:format:%Y-%d-%m %H:%M) (%(committerdate:relative), %(committerdate:format:%A %d))%(end)%(color:green)%(align:24,left)%(authorname)%(end)%(color:green)%(align:64,left)%(contents:lines=1)%(end)' refs/heads/ --count 16
It looks a little different. It shows your current branch too and sorts by most recent commit first:
It also prints gone
near branch when upstream branch is unknown/gone. On Windows may output strange characters and random guids, in current shell session type powershell/bash again and all should be fine. If you modify it and wonder why alignment seems smaller than numbers say, try piping to | cat -v
and you will see ANSI color escape sequences, they count too.
Adjust --count 16
to print more/less branches.