From f8c0edfc17e41a9699b2242c6e89b22ae98895da Mon Sep 17 00:00:00 2001 From: sandr01d <88739791+sandr01d@users.noreply.github.com> Date: Wed, 14 Dec 2022 15:53:52 +0100 Subject: [PATCH] Added git stash push selector 'gsp' (#251) A message can be passed via named argument (-m or --message). All other arguments (e.g. file paths) will cause git stash push to be run directly without invoking fzf. --- README.md | 4 ++++ bin/git-forgit | 41 ++++++++++++++++++++++++++++++++++++++- conf.d/forgit.plugin.fish | 10 ++++++++++ forgit.plugin.zsh | 5 +++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 50d1b2e..20418ab 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ Install `forgit` in just one click. - **Interactive `git stash` viewer** (`gss`) +- **Interactive `git stash push` selector** (`gsp`) + - **Interactive `git clean` selector** (`gclean`) - **Interactive `git cherry-pick` selector** (`gcp`) @@ -150,6 +152,7 @@ forgit_checkout_commit=gco forgit_revert_commit=grc forgit_clean=gclean forgit_stash_show=gss +forgit_stash_push=gsp forgit_cherry_pick=gcp forgit_rebase=grb forgit_blame=gbl @@ -233,6 +236,7 @@ Customizing fzf options for each command individually is also supported: | `gco` | `FORGIT_CHECKOUT_COMMIT_FZF_OPTS` | | `grc` | `FORGIT_REVERT_COMMIT_OPTS` | | `gss` | `FORGIT_STASH_FZF_OPTS` | +| `gsp` | `FORGIT_STASH_PUSH_OPTS` | | `gclean` | `FORGIT_CLEAN_FZF_OPTS` | | `grb` | `FORGIT_REBASE_FZF_OPTS` | | `gbl` | `FORGIT_BLAME_FZF_OPTS` | diff --git a/bin/git-forgit b/bin/git-forgit index d397924..85821bc 100755 --- a/bin/git-forgit +++ b/bin/git-forgit @@ -65,6 +65,7 @@ _forgit_log_format=${FORGIT_LOG_FORMAT:-%C(auto)%h%d %s %C(black)%C(bold)%cr%Cre _forgit_log_preview_options="--graph --pretty=format:'$_forgit_log_format' --color=always --abbrev-commit --date=relative" _forgit_fullscreen_context=${FORGIT_FULLSCREEN_CONTEXT:-10} _forgit_preview_context=${FORGIT_PREVIEW_CONTEXT:-3} +_forgit_is_file_tracked="(git ls-files {} --error-unmatch) &> /dev/null" # git commit viewer _forgit_log() { @@ -204,6 +205,43 @@ _forgit_stash_show() { return $fzf_exit_code } +# git stash push selector +_forgit_stash_push() { + _forgit_inside_work_tree || return 1 + local msg args + args=( "$@" ) + while (( "$#" )); do + case "$1" in + # allow message as argument + -m|--message) + msg="$2" + shift 2 + ;; + # ignore -u as it's used implicitly + -u|--include-untracked) shift ;; + # pass to git directly when encountering anything else + *) git stash push "${args[@]}" && return $? + esac + done + local opts preview files + opts=" + $FORGIT_FZF_DEFAULT_OPTS + -m + $FORGIT_STASH_PUSH_OPTS + " + preview=" + if $_forgit_is_file_tracked; then + git diff --color=always {} | $_forgit_diff_pager + else + git diff --color=always /dev/null {} | $_forgit_diff_pager + fi + " + # Show both modified and untracked files + files=$(git ls-files --exclude-standard --modified --others | FZF_DEFAULT_OPTS="$opts" fzf --preview="$preview") + [[ -z "$files" ]] && return 1 + echo "${files[@]}" | tr '\n' '\0' | git stash push ${msg:+-m "$msg"} -u --pathspec-file-nul --pathspec-from-file - +} + # git clean selector _forgit_clean() { _forgit_inside_work_tree || return 1 @@ -473,7 +511,7 @@ _forgit_blame() { " flags=$(git rev-parse --flags "$@") preview=" - if (git ls-files {} --error-unmatch) &>/dev/null; then + if $_forgit_is_file_tracked; then git blame {} --date=short $flags | $_forgit_blame_pager else echo File not tracked @@ -551,6 +589,7 @@ valid_commands=( "reset_head" "revert_commit" "stash_show" + "stash_push" ) cmd="$1" diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index fd6c426..3fda363 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -42,6 +42,10 @@ function forgit::stash::show -d "git stash viewer" "$FORGIT" stash_show $argv end +function forgit::stash::push -d "git stash push selector" () + "$FORGIT" stash_push $argv +end + function forgit::clean -d "git clean selector" "$FORGIT" clean $argv end @@ -173,6 +177,12 @@ if test -z "$FORGIT_NO_ALIASES" alias gss 'forgit::stash::show' end + if test -n "$forgit_stash_push" + alias $forgit_stash_push 'forgit::stash::push' + else + alias gsp 'forgit::stash::push' + end + if test -n "$forgit_cherry_pick" alias $forgit_cherry_pick 'forgit::cherry::pick::from::branch' else diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 84696ee..1fe7419 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -58,6 +58,10 @@ forgit::stash::show() { "$FORGIT" stash_show "$@" } +forgit::stash::push() { + "$FORGIT" stash_push "$@" +} + forgit::clean() { "$FORGIT" clean "$@" } @@ -142,6 +146,7 @@ if [[ -z "$FORGIT_NO_ALIASES" ]]; then alias "${forgit_checkout_tag:-gct}"='forgit::checkout::tag' alias "${forgit_clean:-gclean}"='forgit::clean' alias "${forgit_stash_show:-gss}"='forgit::stash::show' + alias "${forgit_stash_push:-gsp}"='forgit::stash::push' alias "${forgit_cherry_pick:-gcp}"='forgit::cherry::pick::from::branch' alias "${forgit_rebase:-grb}"='forgit::rebase' alias "${forgit_fixup:-gfu}"='forgit::fixup'