Skip to content

Instantly share code, notes, and snippets.

@shadowhand
Last active August 29, 2015 13:57
Show Gist options
  • Save shadowhand/9813453 to your computer and use it in GitHub Desktop.
Save shadowhand/9813453 to your computer and use it in GitHub Desktop.
Fast git branch switching (git-switchbranch)
#!/bin/bash
######################################################################################
# THIS GIST IS NO LONGER MAINTAINED AND MAY BE DELETED IN THE FUTURE! #
# PLEASE GO TO https://github.com/shadowhand/git-switchbranch FOR A CURRENT VERSION! #
######################################################################################
# git-switchbranch
# @link https://gist.github.com/shadowhand/9813453
# @author shadowhand https://github.com/shadowhand
# @license MIT
#
# installation:
# save this file as git-switchbranch somewhere in your $PATH
# make it executable: chmod +x git-switchbranch
#
# optional:
# git config --global alias.sb '! git switchbranch'
#
# usage:
# git switchbranch
# select the branch you want to move to using numbers
# press enter
# ???
# profit
#
# enjoy!
#
usage() {
echo "usage: git switchbranch [-a] [-r <remote>]"
}
# changelog
#
# 0.0.4
# - update prompt
#
# 0.0.3
# - update comments, documentation
# - fix select menu issues when in detached HEAD mode
# - added new options -a, -r $remote for selecting non-local branches
#
# 0.0.2
# - branch named "master" will always be first in menu
#
# 0.0.1
# - initial release
#
version() {
echo "switchbranch v0.0.4"
}
_select_branch() {
# First branch is always set to "master", or whatever local branch is first when looking for master
# Search all branches, not just local?
local branchargs="--list"
local remote=""
while getopts "r:a" o; do
case $o in
"a")
# select all branches
branchargs="$branchargs -a"
;;
"r")
# show a specific remote
branchargs="$branchargs -r"
remote="$OPTARG"
;;
esac
done
# branch names, removing detached and no branch warnings, and also trimming whitespace
if [[ ! -z $remote ]]; then
local branches=($(git branch $branchargs | grep -v -e '\->' -e '\* (detached from .*)' -e '(no branch)' | grep "$remote/" | sed -e 's/*//' -e 's/^[ \t]+//'))
else
local branches=($(git branch $branchargs | grep -v -e '\->' -e '\* (detached from .*)' -e '(no branch)' | sed -e 's/*//' -e 's/^[ \t]+//'))
fi
if [[ ! -z $remote ]]; then
# remove the remote from the branch name
branches=(${branches[@]/$remote\//})
fi
for (( i=0; i < ${#branches[@]}; i++ )); do
# attempt to find a master branch
if [[ "${branches[$i]}" == *"master" ]]; then
local master="${branches[$i]}"
unset branches[$i]
break # found one, stop looking
fi
done
if [[ ! -z $master ]]; then
# ensure that master branch is placed in front
branches=("$master" "${branches[@]}")
fi
# Set the prompt string
PS3="--> Switch branch [1-${#branches[@]}] or [q]? "
# ask for input!
select selected in ${branches[@]}; do
if [ "$selected" == "quit" -o "$selected" == "q" -o "$selected" == "" ]; then
exit 1
fi
git checkout "$selected"
exit 0
done
}
main() {
local command="$1"
case $command in
"version") version;;
*) _select_branch "$@";;
esac
}
main "$@"
@shadowhand
Copy link
Author

screenshot of ui, such as it is

v0.0.4

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