#!/bin/bash

#
# git recent 2.0 - switching branches, but so fancy
#
# - view recently edited local branches
# - see unique commits to that branch, and optionally the branch diff (against the main/master/primary branch) with Ctrl-o
# - hit Enter to checkout the selected branch.
# - text filtering against branch names, too.
#

if ! command -v fzf >/dev/null 2>&1; then
  echo "Error: fzf is not installed. Please install fzf to use git-recent." >&2
  exit 1
fi
if [[ "$1" == "--help" ]]; then
  echo "git-recent: Browse and checkout recently used Git branches."
  echo
  echo "Keybindings:"
  echo "  Enter:      Checkout the selected branch"
  echo "  Ctrl-O:     Show the diff of the selected branch against the main/master branch"
  echo "  Ctrl-C:     Exit"
  exit 0
fi

# ---------------------------------------------------------------------------------------

branches_format="%(color:yellow)%(refname:short)%(color:reset)"
commits_format="%C(red bold)%h %C(bold blue)%an %C(bold green)%ad %Creset%s"

# The primary branch (eg main or master or w/e)
origin_HEAD=$(cat $(git rev-parse --show-cdup).git/refs/remotes/origin/HEAD | awk '{print $2}')

uniqcommits_cmd="git log --date=human --color=always --format='$commits_format' --no-merges $origin_HEAD..{1}"

diffbranch_cmd="git diff --color=always $origin_HEAD...{}"
# Progressive enhancement if you have delta or diff-so-fancy
if command -v delta >/dev/null 2>&1; then
  diffbranch_cmd="$diffbranch_cmd | delta"
elif command -v diff-so-fancy >/dev/null 2>&1; then
  diffbranch_cmd="$diffbranch_cmd | diff-so-fancy"
fi

# Copy to clipboard, variants for mac/linux
copy_cmd="echo 'Could not copy {} to clipboard.'"
if command -v pbcopy >/dev/null; then
  copy_cmd="printf '%s' {} | pbcopy"
elif command -v wl-copy >/dev/null; then
  copy_cmd="printf '%s' {} | wl-copy"
elif command -v xclip >/dev/null; then
  copy_cmd="printf '%s' {} | xclip -selection clipboard"
elif command -v xsel >/dev/null; then
  copy_cmd="printf '%s' {} | xsel --clipboard"
fi

# if extra arg passed (eg `git recent remotename`), then list those remote branches, rather than local ones
[[ -n "$1" ]] && heads="refs/remotes/$1" || heads="refs/heads"

# fzf git inspiration:
# - https://github.com/junegunn/fzf/wiki/Examples#git 
# - https://github.com/junegunn/fzf/wiki/Examples-(fish)#git
# - https://github.com/junegunn/fzf-git.sh (intense.)

_browse_branches() {
  git for-each-ref --color=always --sort=-authordate "$heads" --format="$branches_format" \
    |  fzf --ansi -- \
        --layout=reverse --multi --height=90% --min-height=20  \
        --border-label-pos=2 --border-label '🌲 Branches' --border \
        --no-hscroll --no-multi \
        --preview-window='right,70%,border-left,border-rounded' --preview="$uniqcommits_cmd" --preview-label="Commits unique to branch" \
        --header $'ENTER (checkout)\nCTRL-O (show branch diff)\nCTRL-Y (copy name to clipboard)' \
        --bind 'preview-scroll-up:preview-up+preview-up+preview-up' \
        --bind 'preview-scroll-down:preview-down+preview-down+preview-down' \
        --bind "ctrl-y:execute-silent($copy_cmd)" \
        --bind "ctrl-o:preview:$diffbranch_cmd" 
} 

chosen_branch="$(_browse_branches)"
if [[ -n "$chosen_branch" ]]; then
  echo git checkout "$chosen_branch"
  git checkout "$chosen_branch"
fi
