#!/usr/bin/env bash # # checkout files/commit/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 # and then select a specific commit to checkout against # ${branch}: checkout branch # ${commit}: checkout commit # ${selected_branch}: selected_branch to switch # ${selected_files}: selected_files to checkout to the version in HEAD # ${selected_commit}: selected commit to checkout # ${confirm}: confirm status of the user # Arguments # -h: show help message # -a: search all files instead of just the modified files # -b: search branch and checkout branch # -c: search commit and checkout commit set -e set -f 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/commit/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\tshow this help message and exit" echo -e " -a\tsearch all files and select a commit to checkout for selected files" echo -e " -b\tcheckout branch" echo -e " -c\tcheckout commit" } all_files="" branch="" commit="" while getopts ":habc" opt do case "$opt" in a) all_files='true' break ;; b) branch='true' break ;; c) commit='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 "${commit}" ]]; then # checkout commit selected_commit=$(get_commit 'Select a commit to checkout') [[ -z "${selected_commit}" ]] && exit 0 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout "${selected_commit}" 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 # shellcheck disable=SC2086 /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_commit=$(get_commit 'select the target commit' "${selected_files}") [[ -z "${selected_commit}" ]] && exit 0 echo "(dryrun) dotbare checkout ${selected_commit} -- ${selected_files}" confirm=$(get_confirmation "Confirm?") [[ "${confirm}" != 'y' ]] && exit 0 # shellcheck disable=SC2086 /usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" checkout "${selected_commit}" ${selected_files} fi fi