#!/bin/bash # # checkout files/commits/branches using fzf # # @params # Globals # ${mydir}: current directory of the script, used for imports # ${all_files}: search all tracked files instead of just the modified files # ${branch}: checkout branch # ${selected_branch}: selected_branch to switch # ${selected_files}: selected_files to checkout to the version in HEAD # Arguments # -h: show help message # -a: search all files instead of just the modified files # -b: search branch and checkout branch # -c: search commits and checkout commits set -e mydir="${0%/*}" source "${mydir}"/../helper/set_variable.sh source "${mydir}"/../helper/get_confirmation.sh source "${mydir}"/../helper/git_query.sh function usage() { echo -e "Usage: dotbare fcheckout [-h] [-a] [-b] [-c] ...\n" echo -e "Checkout files/commits/branch using fzf" echo -e "By default: checkout files back to HEAD (Reset changes back to HEAD)\n" echo -e "optional arguments:" echo -e " -h\t\tshow this help message and exit" echo -e " -a\t\tsearch all files and select a commit to checkout for selected files" echo -e " -b\t\tcheckout branch" echo -e " -c\t\tcheckout commit" } all_files="" branch="" commits="" while getopts ":habcC" opt do case "$opt" in a) all_files='true' break ;; b) branch='true' break ;; c) commits='true' break ;; h) usage exit 0 ;; *) echo "Invalid option: ${OPTARG}" >&2 usage exit 1 ;; esac done if [[ -n "${branch}" ]]; then # checkout branch selected_branch=$(get_branch 'Select a branch to checkout') [[ -z "${selected_branch}" ]] && exit 0 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout "${selected_branch}" exit 0 elif [[ -n "${commits}" ]]; then # checkout commits selected_commits=$(get_commit 'Select a commit to checkout') [[ -z "${selected_commits}" ]] && exit 0 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout "${selected_commits}" exit 0 else # checkout files (reset file changes back to HEAD) if [[ -z "${all_files}" ]]; then selected_files=$(get_modified_file 'select a file to checkout version in HEAD' | tr '\n' ' ') [[ -z "${selected_files}" ]] && exit 0 echo "(dryrun) dotbare checkout -- ${selected_files}" confirm=$(get_confirmation "Confirm?") [[ "${confirm}" != 'y' ]] && exit 0 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout -- ${selected_files} else selected_files=$(get_git_file 'select a file to checkout' | tr '\n' ' ') echo "${selected_files}" [[ -z "${selected_files}" ]] && exit 0 # continue select a commit and then checkout the file back to the selected commit selected_commits=$(/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \ log --oneline --color=always --decorate=short \ | fzf --no-multi --header="${header}" --preview "echo {} \ | awk '{print \$1}' \ | xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \ diff --color=always __ $selected_files" \ | awk '{print $1}') [[ -z "${selected_commits}" ]] && exit 0 echo "(dryrun) dotbare checkout ${selected_commits} -- ${selected_files}" confirm=$(get_confirmation "Confirm?") [[ "${confirm}" != 'y' ]] && exit 0 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout "${selected_commits}" ${selected_files} fi fi