Skip to content

Instantly share code, notes, and snippets.

@verfriemelt-dot-org
Last active July 9, 2022 17:08
Show Gist options
  • Save verfriemelt-dot-org/c194d74fe4439cb890d6cdf459bf70a0 to your computer and use it in GitHub Desktop.
Save verfriemelt-dot-org/c194d74fe4439cb890d6cdf459bf70a0 to your computer and use it in GitHub Desktop.
fzf-gitbranch.sh
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace
trim_origin=false
include_local_branches=true
refs=()
picklist=()
echo_command="echo"
read_heads() {
if [[ -z $1 ]]
then
echo "read_heads requires arguments"
exit 1
fi
echo $( git for-each-ref refs/$1 --format='%(refname)' | \
sed "s/refs\/$1\///" | \
awk '{ print length(), $0 | "sort -n" }' | \
cut -d ' ' -f2-
)
}
check_for_git_repo() {
set +e
git rev-parse --is-inside-work-tree 2>/dev/null >/dev/null
if [ $? -ne 0 ]
then
echo 'not a git repository'
exit 1
fi
set -e
}
while getopts "hoctNL" arg;
do
case $arg in
h)
echo "reads git branches and builds a fzf picklist"
echo ""
echo "options:"
echo ""
echo -e "\t\e[32m-h \e[39m print this help"
echo -e "\t\e[32m-o \e[39m include branches from origin"
echo -e "\t\e[32m-c \e[39m trim origin from branchname, useful for checkout"
echo -e "\t\e[32m-t \e[39m include tags"
echo -e "\t\e[32m-l \e[39m include local branches \e[32m(default)\e[39m"
echo -e "\t\e[32m-L \e[39m exclude local branches"
echo -e "\t\e[32m-N \e[39m omit newline"
echo ""
exit
;;
c)
trim_origin=true
;;
o)
refs+=("remotes")
;;
t)
refs+=("tags")
;;
L)
include_local_branches=false
;;
N)
echo_command='echo -n'
esac
done
shift $(($OPTIND - 1))
query="${1:-}"
check_for_git_repo
if [[ "$include_local_branches" = true ]]
then
picklist+=($(read_heads "heads"))
fi
for source in ${refs[@]}; do
if [[ "$source" = "remotes" && "$trim_origin" = true ]]
then
picklist+=( $(read_heads $source | sed 's/origin\///g') )
# remove duplicates from list due to trimmed origin
picklist=( $( printf '%s\n' "${picklist[@]}" | awk '{ print length(), $0 | "sort -n" }' | uniq | cut -d ' ' -f2- ) )
else
picklist+=($(read_heads $source))
fi
done;
branch=$(
printf '%s\n' ${picklist[@]} | grep -v HEAD |
fzf --no-sort -q "$query" --preview="git -c color.ui=always log --no-merges -n 100 --oneline \$( git show-ref {} -s | head -n1 ) --"
);
if [ -z $branch ]
then
exit 1
fi
$echo_command $branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment