fcheckout (3892B) - raw


      1 #!/usr/bin/env zsh
      2 
      3 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
      4 0="${${(M)0:#/*}:-$PWD/$0}"
      5 
      6 # Desc: checkout files/commit/branches using fzf
      7 #
      8 # @params
      9 # Globals:
     10 #   ${mydir}: current directory of the script, used for imports
     11 #   ${action_type}: what type of git commands to use (branch|select|commit|modified)
     12 #   ${selected_branch}: selected_branch to switch
     13 #   ${selected_files}: selected_files to checkout
     14 #   ${selected_commit}: selected commit to checkout
     15 #   ${confirm}: confirm status of the user
     16 # Arguments:
     17 #   -h|--help: show help message
     18 #   -s|--select: search all files instead of just the modified files
     19 #   -b|--branch: search branch and checkout branch
     20 #   -c|--commit: search commit and checkout commit
     21 
     22 emulate -LR zsh
     23 setopt warncreateglobal noshortloops
     24 
     25 local mydir; mydir=${0:h:A}
     26 builtin source ${mydir}/fgit_helper
     27 
     28 function usage() {
     29   builtin print -P -- "\
     30 %F{1}%BUsage%f%b:
     31   %F{2}fcheckout%f [%F{13}-h%f] [%F{13}-s%f] [%F{13}-b%f] [%F{13}-c%f] [%F{13}-y%f] ...
     32 
     33 %F{11}Select%f files/commit/branch through fzf and checkout the selected objects.
     34 %F{11}Files%f: checkout version in %F{2}HEAD%f or in a specific commit (reset file content to commit).
     35 %F{11}Branch%f: switch to the selected branch.
     36 %F{11}Commit%f: switch to a specific commit.
     37 
     38 %F{4}Default%f: list all modified files and reset selected files back to HEAD.
     39 
     40 %F{1}%BOptions%f%b:
     41   %F{13}-h%f, %F{13}--help%f    Show this help message and exit
     42   %F{13}-s%f, %F{13}--select%f  List all tracked files and select a commit to checkout the selected files
     43   %F{13}-b%f, %F{13}--branch%f  List all branch and checkout/switch the selected branch
     44   %F{13}-c%f, %F{13}--commit%f  List all commits and checkout selected commit
     45   %F{13}-y%f, %F{13}--yes%f     Acknowledge all actions that will be taken and skip confirmation"
     46 }
     47 
     48 local -a selected_files
     49 local action_type confirm selected_commit selected_branch
     50 action_type="modified"
     51 
     52 while (( $# )) {
     53   case "$1" in
     54     (-s|--select) action_type="select"; shift ;;
     55     (-b|--branch) action_type="branch"; shift ;;
     56     (-c|--commit) action_type="commit"; shift ;;
     57     (-y|--yes)    confirm="y";             shift ;;
     58     (-h|--help)   usage && exit 0 ;;
     59     (*)           print::error "Invalid option: $1" && { usage; exit 1 } ;;
     60   esac
     61 }
     62 
     63 if [[ "$action_type" = branch ]]; then
     64   # Checkout branch
     65   selected_branch=$(get_branch 'Select a branch to checkout')
     66   [[ -z "$selected_branch" ]] && exit 1
     67   command git checkout "${selected_branch}"
     68 
     69 elif [[ "$action_type" = "commit" ]]; then
     70   # Checkout commit
     71   selected_commit=$(get_commit 'Select a commit to checkout')
     72   [[ -z "${selected_commit}" ]] && exit 1
     73   command git checkout "${selected_commit}"
     74 
     75 elif [[ "$action_type" = modified ]]; then
     76   # Checkout modified file back to version in HEAD
     77   selected_files=( ${(@f)"$(get_modified_file 'select files to checkout version in HEAD')"} )
     78   (( $#selected_files )) || exit 1
     79   [[ -z "$confirm" ]] && \
     80     builtin print -P "(%F{3}dryrun%f) %F{2}git%f checkout --" "${selected_files[@]}"
     81   [[ -z "$confirm" ]] && confirm=$(get_confirmation "Confirm?")
     82   [[ "$confirm" != y ]] && exit 1
     83   command git checkout -- "$selected_files[@]"
     84 
     85 elif [[ "$action_type" = select ]]; then
     86   # Checkout selected files to a selected commit
     87   selected_files=( ${(@f)"$(get_git_file 'select files to checkout to previous commit')"} )
     88   (( $#selected_files )) || exit 1
     89   # Continue select a commit and then checkout the file back to the selected commit
     90   selected_commit=$(get_commit 'select the target commit' "${selected_files[@]}")
     91   [[ -z "$selected_commit" ]] && exit 1
     92   [[ -z "$confirm" ]] && \
     93     builtin print -P "(%F{3}dryrun%f) %F{2}git%f checkout ${selected_commit} --" "${selected_files[@]}"
     94   [[ -z "$confirm" ]] && confirm=$(get_confirmation "Confirm?")
     95   [[ "$confirm" != y ]] && exit 0
     96   command git checkout "$selected_commit" "$selected_files[@]"
     97 fi