mirror of
https://github.com/wfxr/forgit.git
synced 2026-09-10 07:16:23 -04:00
Refactor: Parse environment variables into arrays
Forgit allows specifying git options in environment variables that are passed along to the individual git commands. We currently treat those as strings. This commit adds a _forgit_parse_array function and uses it to parse all such environment variables into arrays instead. This will allow us to get rid of deferred code, since we can pass the parsed arrays directly to the git commands and don't have to rely on eval.
This commit is contained in:
parent
48e91dadb5
commit
d4efabb422
|
|
@ -71,6 +71,55 @@ hash emojify &>/dev/null && _forgit_emojify='|emojify'
|
|||
# extract the first git sha occurring in the input and strip trailing newline
|
||||
_forgit_extract_sha="grep -Eo '[a-f0-9]+' | head -1 | tr -d '[:space:]'"
|
||||
|
||||
# parse a space separated string into an array
|
||||
# arrays parsed with this function are global
|
||||
_forgit_parse_array() {
|
||||
${IFS+"false"} && unset old_IFS || old_IFS="$IFS"
|
||||
# read the value of the second argument
|
||||
# into an array that has the name of the first argument
|
||||
IFS=" " read -r -a "$1" <<< "$2"
|
||||
${old_IFS+"false"} && unset IFS || IFS="$old_IFS"
|
||||
}
|
||||
|
||||
# parse environment variables into global arrays
|
||||
# this allows using them properly quoted without word splitting or glob expansion
|
||||
_forgit_log_git_opts=()
|
||||
_forgit_parse_array _forgit_log_git_opts "$FORGIT_LOG_GIT_OPTS"
|
||||
_forgit_add_git_opts=()
|
||||
_forgit_parse_array _forgit_add_git_opts "$FORGIT_ADD_GIT_OPTS"
|
||||
_forgit_diff_git_opts=()
|
||||
_forgit_parse_array _forgit_diff_git_opts "$FORGIT_DIFF_GIT_OPTS"
|
||||
_forgit_reset_head_git_opts=()
|
||||
_forgit_parse_array _forgit_reset_head_git_opts "$FORGIT_RESET_HEAD_GIT_OPTS"
|
||||
_forgit_rebase_git_opts=()
|
||||
_forgit_parse_array _forgit_rebase_git_opts "$FORGIT_REBASE_GIT_OPTS"
|
||||
_forgit_fixup_git_opts=()
|
||||
_forgit_parse_array _forgit_fixup_git_opts "$FORGIT_FIXUP_GIT_OPTS"
|
||||
_forgit_blame_git_opts=()
|
||||
_forgit_parse_array _forgit_blame_git_opts "$FORGIT_BLAME_GIT_OPTS"
|
||||
_forgit_revert_commit_git_opts=()
|
||||
_forgit_parse_array _forgit_revert_commit_git_opts "$FORGIT_REVERT_COMMIT_GIT_OPTS"
|
||||
_forgit_branch_delete_git_opts=()
|
||||
_forgit_parse_array _forgit_branch_delete_git_opts "$FORGIT_BRANCH_DELETE_GIT_OPTS"
|
||||
_forgit_checkout_commit_git_opts=()
|
||||
_forgit_parse_array _forgit_checkout_commit_git_opts "$FORGIT_CHECKOUT_COMMIT_GIT_OPTS"
|
||||
_forgit_checkout_tag_git_opts=()
|
||||
_forgit_parse_array _forgit_checkout_tag_git_opts "$FORGIT_CHECKOUT_TAG_GIT_OPTS"
|
||||
_forgit_checkout_branch_git_opts=()
|
||||
_forgit_parse_array _forgit_checkout_branch_git_opts "$FORGIT_CHECKOUT_BRANCH_GIT_OPTS"
|
||||
_forgit_checkout_file_git_opts=()
|
||||
_forgit_parse_array _forgit_checkout_file_git_opts "$FORGIT_CHECKOUT_FILE_GIT_OPTS"
|
||||
_forgit_cherry_pick_git_opts=()
|
||||
_forgit_parse_array _forgit_cherry_pick_git_opts "$FORGIT_CHERRY_PICK_GIT_OPTS"
|
||||
_forgit_clean_git_opts=()
|
||||
_forgit_parse_array _forgit_clean_git_opts "$FORGIT_CLEAN_GIT_OPTS"
|
||||
_forgit_stash_push_git_opts=()
|
||||
_forgit_parse_array _forgit_stash_push_git_opts "$FORGIT_STASH_PUSH_GIT_OPTS"
|
||||
_forgit_stash_show_git_opts=()
|
||||
_forgit_parse_array _forgit_stash_show_git_opts "$FORGIT_STASH_SHOW_GIT_OPTS"
|
||||
_forgit_checkout_branch_branch_git_opts=()
|
||||
_forgit_parse_array _forgit_checkout_branch_branch_git_opts "$FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS"
|
||||
|
||||
_forgit_pager=${FORGIT_PAGER:-$(git config core.pager || echo 'cat')}
|
||||
_forgit_show_pager=${FORGIT_SHOW_PAGER:-$(git config pager.show || echo "$_forgit_pager")}
|
||||
_forgit_diff_pager=${FORGIT_DIFF_PAGER:-$(git config pager.diff || echo "$_forgit_pager")}
|
||||
|
|
@ -102,7 +151,7 @@ _forgit_log() {
|
|||
graph=--graph
|
||||
[[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph=
|
||||
log_format=${FORGIT_GLO_FORMAT:-$_forgit_log_format}
|
||||
eval "git log $graph --color=always --format='$log_format' $FORGIT_LOG_GIT_OPTS $* $_forgit_emojify" |
|
||||
eval "git log $graph --color=always --format='$log_format' ${_forgit_log_git_opts[*]} $* $_forgit_emojify" |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf
|
||||
fzf_exit_code=$?
|
||||
# exit successfully on 130 (ctrl-c/esc)
|
||||
|
|
@ -146,7 +195,7 @@ _forgit_diff() {
|
|||
# prevent fzf from interpreting this substring by escaping the opening bracket.
|
||||
# The string is evaluated a few subsequent times, so we need multiple escapes.
|
||||
escaped_commits=${commits//\{/\\\\\{}
|
||||
git_diff="git diff --color=always $FORGIT_DIFF_GIT_OPTS $escaped_commits"
|
||||
git_diff="git diff --color=always ${_forgit_diff_git_opts[*]} $escaped_commits"
|
||||
preview_cmd="cd '$repo' && $get_files | xargs -0 $git_diff -U$_forgit_preview_context -- | $_forgit_diff_pager"
|
||||
enter_cmd="cd '$repo' && $get_files | xargs -0 $git_diff -U$_forgit_fullscreen_context -- | $_forgit_diff_pager"
|
||||
opts="
|
||||
|
|
@ -157,7 +206,7 @@ _forgit_diff() {
|
|||
$FORGIT_DIFF_FZF_OPTS
|
||||
--prompt=\"$commits > \"
|
||||
"
|
||||
eval "git diff --name-status $FORGIT_DIFF_GIT_OPTS $commits -- ${files[*]} | sed -E 's/^([[:alnum:]]+)[[:space:]]+(.*)$/[\1] \2/'" |
|
||||
eval "git diff --name-status ${_forgit_diff_git_opts[*]} $commits -- ${files[*]} | sed -E 's/^([[:alnum:]]+)[[:space:]]+(.*)$/[\1] \2/'" |
|
||||
sed 's/ / -> /2' | expand -t 8 |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf
|
||||
fzf_exit_code=$?
|
||||
|
|
@ -170,7 +219,7 @@ _forgit_diff() {
|
|||
_forgit_add() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_add changed unmerged untracked files opts preview extract
|
||||
git_add="git add $FORGIT_ADD_GIT_OPTS"
|
||||
git_add="git add ${_forgit_add_git_opts[*]}"
|
||||
# Add files if passed as arguments
|
||||
[[ $# -ne 0 ]] && { $git_add "$@" && git status -su; return $?; }
|
||||
|
||||
|
|
@ -210,7 +259,7 @@ _forgit_add() {
|
|||
_forgit_reset_head() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_reset_head cmd files opts rootdir
|
||||
git_reset_head="git reset -q $FORGIT_RESET_HEAD_GIT_OPTS HEAD"
|
||||
git_reset_head="git reset -q ${_forgit_reset_head_git_opts[*]} HEAD"
|
||||
[[ $# -ne 0 ]] && { $git_reset_head "$@" && git status --short; return $?; }
|
||||
rootdir=$(git rev-parse --show-toplevel)
|
||||
cmd="git diff --staged --color=always -- $rootdir/{} | $_forgit_diff_pager "
|
||||
|
|
@ -232,7 +281,7 @@ _forgit_stash_show() {
|
|||
local git_stash_show git_stash_list cmd opts
|
||||
git_stash_show="git stash show --color=always --ext-diff"
|
||||
[[ $# -ne 0 ]] && { $git_stash_show "$@"; return $?; }
|
||||
git_stash_list="git stash list $FORGIT_STASH_SHOW_GIT_OPTS"
|
||||
git_stash_list="git stash list ${_forgit_stash_show_git_opts[*]}"
|
||||
cmd="echo {} |cut -d: -f1 |xargs -I% $git_stash_show % |$_forgit_diff_pager"
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -252,7 +301,7 @@ _forgit_stash_show() {
|
|||
_forgit_stash_push() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_stash_push msg args
|
||||
git_stash_push="git stash push $FORGIT_STASH_PUSH_GIT_OPTS"
|
||||
git_stash_push="git stash push ${_forgit_stash_push_git_opts[*]}"
|
||||
args=( "$@" )
|
||||
while (( "$#" )); do
|
||||
case "$1" in
|
||||
|
|
@ -291,7 +340,7 @@ _forgit_clean() {
|
|||
_forgit_inside_work_tree || return 1
|
||||
_forgit_contains_non_flags "$@" && { git clean -q "$@"; return $?; }
|
||||
local git_clean files opts
|
||||
git_clean="git clean $FORGIT_CLEAN_GIT_OPTS"
|
||||
git_clean="git clean ${_forgit_clean_git_opts[*]}"
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
-m -0
|
||||
|
|
@ -307,7 +356,7 @@ _forgit_clean() {
|
|||
_forgit_cherry_pick() {
|
||||
local git_cherry_pick base target preview opts fzf_selection fzf_exitval
|
||||
|
||||
git_cherry_pick="git cherry-pick $FORGIT_CHERRY_PICK_GIT_OPTS"
|
||||
git_cherry_pick="git cherry-pick ${_forgit_cherry_pick_git_opts[*]}"
|
||||
|
||||
base=$(git branch --show-current)
|
||||
[[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1
|
||||
|
|
@ -387,7 +436,7 @@ _forgit_cherry_pick_from_branch() {
|
|||
_forgit_rebase() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_rebase cmd preview opts graph files target_commit prev_commit
|
||||
git_rebase="git rebase -i $FORGIT_REBASE_GIT_OPTS"
|
||||
git_rebase="git rebase -i ${_forgit_rebase_git_opts[*]}"
|
||||
graph=--graph
|
||||
[[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph=
|
||||
cmd="git log $graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify"
|
||||
|
|
@ -412,7 +461,7 @@ _forgit_fixup() {
|
|||
_forgit_inside_work_tree || return 1
|
||||
git diff --cached --quiet && echo 'Nothing to fixup: there are no staged changes.' && return 1
|
||||
local git_fixup cmd preview opts graph files target_commit prev_commit
|
||||
git_fixup="git commit --fixup $FORGIT_FIXUP_GIT_OPTS"
|
||||
git_fixup="git commit --fixup ${_forgit_fixup_git_opts[*]}"
|
||||
graph=--graph
|
||||
[[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph=
|
||||
cmd="git log $graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify"
|
||||
|
|
@ -439,7 +488,7 @@ _forgit_fixup() {
|
|||
_forgit_checkout_file() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_checkout cmd files opts
|
||||
git_checkout="git checkout $FORGIT_CHECKOUT_FILE_GIT_OPTS"
|
||||
git_checkout="git checkout ${_forgit_checkout_file_git_opts[*]}"
|
||||
[[ $# -ne 0 ]] && { $git_checkout -- "$@"; return $?; }
|
||||
cmd="git diff --color=always -- {} | $_forgit_diff_pager"
|
||||
opts="
|
||||
|
|
@ -468,7 +517,7 @@ _forgit_checkout_branch() {
|
|||
fi
|
||||
|
||||
local git_checkout cmd preview opts branch
|
||||
cmd="git branch --color=always ${FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS:---all} | LC_ALL=C sort -k1.1,1.1 -rs"
|
||||
cmd="git branch --color=always ${_forgit_checkout_branch_branch_git_opts[*]:---all} | LC_ALL=C sort -k1.1,1.1 -rs"
|
||||
preview="git log {1} $_forgit_log_preview_options"
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -479,7 +528,7 @@ _forgit_checkout_branch() {
|
|||
branch="$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $1}')"
|
||||
[[ -z "$branch" ]] && return 1
|
||||
|
||||
git_checkout="git checkout $FORGIT_CHECKOUT_BRANCH_GIT_OPTS"
|
||||
git_checkout="git checkout ${_forgit_checkout_branch_git_opts[*]}"
|
||||
# track the remote branch if possible
|
||||
if [[ "$branch" == "remotes/origin/"* ]]; then
|
||||
if git branch | grep -qw "${branch#remotes/origin/}"; then
|
||||
|
|
@ -497,7 +546,7 @@ _forgit_checkout_branch() {
|
|||
_forgit_checkout_tag() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_checkout cmd opts preview
|
||||
git_checkout="git checkout $FORGIT_CHECKOUT_TAG_GIT_OPTS"
|
||||
git_checkout="git checkout ${_forgit_checkout_tag_git_opts[*]}"
|
||||
[[ $# -ne 0 ]] && { $git_checkout "$@"; return $?; }
|
||||
cmd="git tag -l --sort=-v:refname"
|
||||
preview="git log {1} $_forgit_log_preview_options"
|
||||
|
|
@ -516,7 +565,7 @@ _forgit_checkout_tag() {
|
|||
_forgit_checkout_commit() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_checkout cmd opts graph
|
||||
git_checkout="git checkout $FORGIT_CHECKOUT_COMMIT_GIT_OPTS"
|
||||
git_checkout="git checkout ${_forgit_checkout_commit_git_opts[*]}"
|
||||
[[ $# -ne 0 ]] && { $git_checkout "$@"; return $?; }
|
||||
cmd="echo {} | $_forgit_extract_sha |xargs -I% git show --color=always % | $_forgit_show_pager"
|
||||
opts="
|
||||
|
|
@ -536,7 +585,7 @@ _forgit_checkout_commit() {
|
|||
_forgit_branch_delete() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_branch preview opts cmd branches
|
||||
git_branch="git branch $FORGIT_BRANCH_DELETE_GIT_OPTS"
|
||||
git_branch="git branch ${_forgit_branch_delete_git_opts[*]}"
|
||||
[[ $# -ne 0 ]] && { $git_branch -D "$@"; return $?; }
|
||||
preview="git log {1} $_forgit_log_preview_options"
|
||||
|
||||
|
|
@ -557,7 +606,7 @@ _forgit_branch_delete() {
|
|||
_forgit_revert_commit() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_revert cmd opts files preview commits IFS
|
||||
git_revert="git revert $FORGIT_REVERT_COMMIT_GIT_OPTS"
|
||||
git_revert="git revert ${_forgit_revert_commit_git_opts[*]}"
|
||||
[[ $# -ne 0 ]] && { $git_revert "$@"; return $?; }
|
||||
|
||||
cmd="git log --graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify"
|
||||
|
|
@ -596,7 +645,7 @@ _forgit_revert_commit() {
|
|||
_forgit_blame() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local git_blame opts flags preview file
|
||||
git_blame="git blame $FORGIT_BLAME_GIT_OPTS"
|
||||
git_blame="git blame ${_forgit_blame_git_opts[*]}"
|
||||
_forgit_contains_non_flags "$@" && { $git_blame "$@"; return $?; }
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -605,7 +654,7 @@ _forgit_blame() {
|
|||
flags=$(git rev-parse --flags "$@")
|
||||
preview="
|
||||
if $_forgit_is_file_tracked; then
|
||||
git blame {} --date=short $FORGIT_BLAME_GIT_OPTS $flags | $_forgit_blame_pager
|
||||
git blame {} --date=short ${_forgit_blame_git_opts[*]} $flags | $_forgit_blame_pager
|
||||
else
|
||||
echo File not tracked
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in a new issue