freset (2703B) - raw


      1 #!/usr/bin/env zsh
      2 
      3 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
      4 0="${${(M)0:#/*}:-$PWD/$0}"
      5 
      6 # Desc: unstage selected staged file || reset the commit to certain point
      7 #
      8 # @params
      9 # Globals:
     10 #   ${mydir}: current directory of the script
     11 #   ${reset_type}: reset type, modified files or commit
     12 #   ${reset_option}: git reset flag, --mixed | --soft | --hard
     13 #   ${selected_files}: selected file to reset
     14 #   ${selected_commit}: selected commit to reset
     15 #   ${confirm}: confirmation status of the user
     16 # Arguments:
     17 #   -h|--help: show help message and quit
     18 #   -c|--commit: reset commit
     19 #   -S|--soft: use --soft flag
     20 #   -H|--hard: use --hard flag
     21 #   -y|--yes: confirm action by default and skip confirmation
     22 
     23 emulate -LR zsh
     24 setopt warncreateglobal noshortloops
     25 
     26 local mydir; mydir=${0:h:A}
     27 builtin source ${mydir}/fgit_helper
     28 
     29 function usage() {
     30   builtin print -P -- "\
     31 %F{1}%BUsage%f%b: %F{2}freset%f [%F{13}-h%f] [%F{13}-c%f] [%F{13}-S%f] [%F{13}-H%f] [%F{13}-y%f] ...
     32 
     33 Reset(unstage) the selected staged files.
     34 Reset the HEAD to certain commits by using -c flag.
     35 
     36 %F{4}Default%f: unstage the selected files.
     37 
     38 %F{1}%BOptions%f%b:
     39   %F{13}-h%f, %F{13}--help%f   Show this help message and exit
     40   %F{13}-c%f, %F{13}--commit%f Reset HEAD to certain commit
     41                %F{4}Default%f: --mixed flag, reset HEAD to certain commit put all changes into modified state
     42   %F{13}-S%f, %F{13}--soft%f   Reset commit using --soft flag, reset HEAD to certain commit without modify working tree
     43   %F{13}-H%f, %F{13}--hard%f   Reset commit using --hard flag, reset HEAD to certain commit discard all changes from the working tree
     44   %F{13}-y%f, %F{13}--yes%f    Acknowledge all actions that will be taken and skip confirmation"
     45 }
     46 
     47 local reset_option reset_type
     48 local -a selected_files
     49 reset_option="--mixed"
     50 reset_type="modified"
     51 
     52 while (( $# )) {
     53   case "$1" in
     54     (-c|--commit) reset_type="commit";   shift   ;;
     55     (-S|--soft)   reset_option="--soft"; shift   ;;
     56     (-H|--hard)   reset_option="--hard"; 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 [[ "$reset_type" = "commit" ]]; then
     64   selected_commit=$(get_commit "Select the target commit")
     65   [[ -z "$selected_commit" ]] && exit 1
     66   [[ -z "$confirm" ]] && confirm=$(get_confirmation "Reset HEAD to $selected_commit $reset_option?")
     67   [[ "$confirm" != y ]] && exit 1
     68   command git reset "$selected_commit" "$reset_option"
     69 else
     70   selected_files=( ${(@f)"$(get_modified_file 'select files to unstage' 'staged')"} )
     71   (( $#selected_files )) || exit 1
     72   command git reset "${selected_files[@]}"
     73 
     74 fi