mirror of
https://github.com/wfxr/forgit.git
synced 2026-09-09 23:06:25 -04:00
ci: enforce consistent shell formatting with shfmt (#514)
This commit is contained in:
parent
7663f3a809
commit
dfe682e113
|
|
@ -6,4 +6,7 @@ end_of_line = lf
|
|||
indent_style = space
|
||||
insert_final_newline = true
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
simplify = true
|
||||
switch_case_indent = true
|
||||
trim_trailing_whitespace = true
|
||||
|
|
|
|||
10
.github/workflows/ci.yaml
vendored
10
.github/workflows/ci.yaml
vendored
|
|
@ -78,3 +78,13 @@ jobs:
|
|||
run: npm install -g @commitlint/cli @commitlint/config-conventional
|
||||
- name: Validate PR commits
|
||||
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
|
||||
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Check format
|
||||
uses: mfinelli/setup-shfmt@v4
|
||||
with:
|
||||
shfmt-version: 3.13.1
|
||||
- run: shfmt --diff .
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ lib/bashunit .
|
|||
bash forgit.plugin.sh
|
||||
zsh forgit.plugin.zsh
|
||||
fish conf.d/forgit.plugin.fish
|
||||
shfmt --write .
|
||||
```
|
||||
|
||||
In your pull request, report which shells and operating systems you tested.
|
||||
|
|
|
|||
278
bin/git-forgit
278
bin/git-forgit
|
|
@ -39,8 +39,11 @@ _forgit_inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null 2>&1
|
|||
_forgit_inside_git_dir() { git rev-parse --is-inside-git-dir >/dev/null 2>&1; }
|
||||
_forgit_inside_git_repo() { _forgit_inside_work_tree || _forgit_inside_git_dir; }
|
||||
# tac is not available on OSX, tail -r is not available on Linux, so we use either of them
|
||||
_forgit_reverse_lines() { tac 2> /dev/null || tail -r; }
|
||||
_forgit_strip_ansi() { local ESC=$'\033'; sed "s/${ESC}\[[0-9;]*m//g"; }
|
||||
_forgit_reverse_lines() { tac 2>/dev/null || tail -r; }
|
||||
_forgit_strip_ansi() {
|
||||
local ESC=$'\033'
|
||||
sed "s/${ESC}\[[0-9;]*m//g"
|
||||
}
|
||||
|
||||
_forgit_previous_commit() {
|
||||
# "SHA~" is invalid when the commit is the first commit, but we can use "--root" instead
|
||||
|
|
@ -54,10 +57,10 @@ _forgit_previous_commit() {
|
|||
_forgit_contains_non_flags() {
|
||||
while (("$#")); do
|
||||
case "$1" in
|
||||
-*) shift ;;
|
||||
*)
|
||||
return 0
|
||||
;;
|
||||
-*) shift ;;
|
||||
*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return 1
|
||||
|
|
@ -98,7 +101,7 @@ _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"
|
||||
IFS=" " read -r -a "$1" <<<"$2"
|
||||
${old_IFS+"false"} && unset IFS || IFS="$old_IFS"
|
||||
}
|
||||
|
||||
|
|
@ -108,18 +111,18 @@ _forgit_quote_files() {
|
|||
local files add
|
||||
files=()
|
||||
add=false
|
||||
while (( "$#" )); do
|
||||
while (("$#")); do
|
||||
case "$1" in
|
||||
--)
|
||||
add=true
|
||||
shift
|
||||
;;
|
||||
add=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [ $add == true ]; then
|
||||
files+=("'$1'")
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
if [ $add == true ]; then
|
||||
files+=("'$1'")
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo "${files[*]}"
|
||||
|
|
@ -130,19 +133,19 @@ _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_dir_view=${FORGIT_DIR_VIEW:-$(hash tree &> /dev/null && echo 'tree' || echo 'find')}
|
||||
_forgit_dir_view=${FORGIT_DIR_VIEW:-$(hash tree &>/dev/null && echo 'tree' || echo 'find')}
|
||||
|
||||
_forgit_pager() {
|
||||
local pager
|
||||
# Preview mode must be marked explicitly by forgit. Inferred signals such
|
||||
# as FZF_PREVIEW_COLUMNS or a non-TTY stdout also show up in execute/fullscreen
|
||||
# paths, which would incorrectly route Enter actions to FORGIT_PREVIEW_PAGER.
|
||||
if [[ -n "$FORGIT_IN_PREVIEW" ]] && [[ -n "$FORGIT_PREVIEW_PAGER" ]]; then
|
||||
if [[ -n $FORGIT_IN_PREVIEW ]] && [[ -n $FORGIT_PREVIEW_PAGER ]]; then
|
||||
pager="$FORGIT_PREVIEW_PAGER"
|
||||
else
|
||||
pager=$(_forgit_get_pager "$1")
|
||||
fi
|
||||
[[ -z "${pager}" ]] && exit 1
|
||||
[[ -z ${pager} ]] && exit 1
|
||||
eval "${pager} ${*:2}"
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +174,7 @@ _forgit_get_pager() {
|
|||
}
|
||||
|
||||
_forgit_is_file_tracked() {
|
||||
git ls-files "$1" --error-unmatch &> /dev/null
|
||||
git ls-files "$1" --error-unmatch &>/dev/null
|
||||
}
|
||||
|
||||
# List branches with current branch first (for use as fzf header)
|
||||
|
|
@ -185,7 +188,7 @@ _forgit_is_file_tracked() {
|
|||
_forgit_branch_list() {
|
||||
local current
|
||||
current=$(git branch --show-current)
|
||||
if [[ -n "$current" ]]; then
|
||||
if [[ -n $current ]]; then
|
||||
_forgit_print_dim "* $current"
|
||||
else
|
||||
_forgit_print_dim "* (HEAD detached at $(git rev-parse --short HEAD))"
|
||||
|
|
@ -361,7 +364,10 @@ _forgit_log() {
|
|||
# git reflog viewer
|
||||
_forgit_reflog() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
_forgit_contains_non_flags "$@" && { git reflog "$@"; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
git reflog "$@"
|
||||
return $?
|
||||
}
|
||||
local opts reflog_format
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -426,7 +432,7 @@ _forgit_diff_view() {
|
|||
repo=$(git rev-parse --show-toplevel)
|
||||
cd "$repo" || return 1
|
||||
if [ $# -gt 2 ]; then
|
||||
IFS=" " read -r -a commits <<< "${*:3}"
|
||||
IFS=" " read -r -a commits <<<"${*:3}"
|
||||
fi
|
||||
echo "$input_line" | _forgit_get_files_from_diff_line | xargs -0 \
|
||||
"$FORGIT" exec_diff "${commits[@]}" -U"$diff_context" -- | _forgit_pager diff
|
||||
|
|
@ -453,7 +459,7 @@ _forgit_diff() {
|
|||
commits=()
|
||||
files=()
|
||||
[[ $# -ne 0 ]] && {
|
||||
if git rev-parse "$1" -- &>/dev/null ; then
|
||||
if git rev-parse "$1" -- &>/dev/null; then
|
||||
if [[ $# -gt 1 ]] && git rev-parse "$2" -- &>/dev/null; then
|
||||
commits=("$1" "$2") && files=("${@:3}")
|
||||
else
|
||||
|
|
@ -511,7 +517,7 @@ _forgit_show_preview() {
|
|||
local input_line=$1
|
||||
local diff_context=$2
|
||||
local commit=$3
|
||||
if [[ "$FZF_PREVIEW_LABEL" =~ "Diff" ]]; then
|
||||
if [[ $FZF_PREVIEW_LABEL =~ "Diff" ]]; then
|
||||
_forgit_show_view "${input_line}" "${diff_context}" "${commit}"
|
||||
else
|
||||
git show --quiet --color=always "${FZF_PROMPT%% *}"
|
||||
|
|
@ -543,7 +549,7 @@ _forgit_show() {
|
|||
local files opts commit escaped_commit
|
||||
files=()
|
||||
if [[ $# -ne 0 ]]; then
|
||||
if git rev-parse "$1" -- &>/dev/null ; then
|
||||
if git rev-parse "$1" -- &>/dev/null; then
|
||||
commit="$1" && files=("${@:2}")
|
||||
else
|
||||
commit="HEAD" && files=("$@")
|
||||
|
|
@ -577,11 +583,11 @@ _forgit_add_preview() {
|
|||
file=$1
|
||||
# $file can be a directory when status.showUntrackedFiles is set to 'normal'
|
||||
# When this is the case and the directory is not a submodule show the content of the directory and return
|
||||
if [[ -d "$file" ]] && ! _forgit_is_submodule "$file"; then
|
||||
if [[ -d $file ]] && ! _forgit_is_submodule "$file"; then
|
||||
eval "$_forgit_dir_view \"$file\""
|
||||
return 0
|
||||
fi
|
||||
if (git status -s -- "$file" | grep '^??') &>/dev/null; then # diff with /dev/null for untracked files
|
||||
if (git status -s -- "$file" | grep '^??') &>/dev/null; then # diff with /dev/null for untracked files
|
||||
git diff --color=always --no-index -- /dev/null "$file" | _forgit_pager diff | sed '2 s/added:/untracked:/'
|
||||
else
|
||||
git diff --color=always -- "$file" | _forgit_pager diff
|
||||
|
|
@ -605,7 +611,10 @@ _forgit_add() {
|
|||
_forgit_inside_work_tree || return 1
|
||||
local files opts
|
||||
# Add files if passed as arguments
|
||||
_forgit_contains_non_flags "$@" && { _forgit_git_add "$@" && git status -s; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
_forgit_git_add "$@" && git status -s
|
||||
return $?
|
||||
}
|
||||
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -621,7 +630,7 @@ _forgit_add() {
|
|||
while IFS='' read -r file; do
|
||||
files+=("$file")
|
||||
done < <(_forgit_worktree_changes | FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
[[ "${#files[@]}" -gt 0 ]] && _forgit_git_add "$@" "${files[@]}" && git status -s && return
|
||||
[[ ${#files[@]} -gt 0 ]] && _forgit_git_add "$@" "${files[@]}" && git status -s && return
|
||||
echo 'Nothing to add.'
|
||||
}
|
||||
|
||||
|
|
@ -640,7 +649,10 @@ _forgit_git_reset_head() {
|
|||
_forgit_reset_head() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local files opts rootdir
|
||||
[[ $# -ne 0 ]] && { _forgit_git_reset_head "$@" && git status --short; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_reset_head "$@" && git status --short
|
||||
return $?
|
||||
}
|
||||
rootdir=$(git rev-parse --show-toplevel)
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -678,7 +690,10 @@ _forgit_stash_show_enter() {
|
|||
_forgit_stash_show() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts
|
||||
[[ $# -ne 0 ]] && { "${FORGIT}" show "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
"${FORGIT}" show "$@"
|
||||
return $?
|
||||
}
|
||||
_forgit_stash_show_git_opts=()
|
||||
_forgit_parse_array _forgit_stash_show_git_opts "$FORGIT_STASH_SHOW_GIT_OPTS"
|
||||
opts="
|
||||
|
|
@ -713,18 +728,21 @@ _forgit_git_stash_push() {
|
|||
_forgit_stash_push() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local msg args
|
||||
args=( "$@" )
|
||||
while (( "$#" )); do
|
||||
args=("$@")
|
||||
while (("$#")); do
|
||||
case "$1" in
|
||||
# allow message as argument
|
||||
-m|--message)
|
||||
msg="$2"
|
||||
shift 2
|
||||
;;
|
||||
-m | --message)
|
||||
msg="$2"
|
||||
shift 2
|
||||
;;
|
||||
# ignore -u as it's used implicitly
|
||||
-u|--include-untracked) shift ;;
|
||||
-u | --include-untracked) shift ;;
|
||||
# pass to git directly when encountering anything else
|
||||
*) _forgit_git_stash_push "${args[@]}"; return $?
|
||||
*)
|
||||
_forgit_git_stash_push "${args[@]}"
|
||||
return $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
local opts files
|
||||
|
|
@ -740,14 +758,14 @@ _forgit_stash_push() {
|
|||
files+=("$file")
|
||||
done < <(_forgit_list_files --exclude-standard --modified --others |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf --exit-0)
|
||||
[[ "${#files[@]}" -eq 0 ]] && echo "Nothing to stash" && return 1
|
||||
[[ ${#files[@]} -eq 0 ]] && echo "Nothing to stash" && return 1
|
||||
_forgit_git_stash_push ${msg:+-m "$msg"} -u "${files[@]}"
|
||||
}
|
||||
|
||||
_forgit_clean_preview() {
|
||||
local path
|
||||
path=$1
|
||||
if [[ -d "$path" ]]; then
|
||||
if [[ -d $path ]]; then
|
||||
eval "$_forgit_dir_view \"$path\""
|
||||
else
|
||||
git diff --color=always /dev/null "$path" | _forgit_pager diff
|
||||
|
|
@ -771,12 +789,15 @@ _forgit_clean_select_files() {
|
|||
# git clean selector
|
||||
_forgit_clean() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
_forgit_contains_non_flags "$@" && { git clean -q "$@"; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
git clean -q "$@"
|
||||
return $?
|
||||
}
|
||||
local files
|
||||
_forgit_clean_git_opts=()
|
||||
_forgit_parse_array _forgit_clean_git_opts "$FORGIT_CLEAN_GIT_OPTS"
|
||||
files=$(_forgit_clean_select_files "$@")
|
||||
[[ -n "$files" ]] && echo "$files" | tr '\n' '\0' | xargs -0 -I% git clean "${_forgit_clean_git_opts[@]}" -xdff '%' && git status --short && return
|
||||
[[ -n $files ]] && echo "$files" | tr '\n' '\0' | xargs -0 -I% git clean "${_forgit_clean_git_opts[@]}" -xdff '%' && git status --short && return
|
||||
echo 'Nothing to clean.'
|
||||
}
|
||||
|
||||
|
|
@ -790,7 +811,7 @@ _forgit_cherry_pick() {
|
|||
local base target opts fzf_selection fzf_exitval
|
||||
|
||||
base=$(git branch --show-current)
|
||||
[[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1
|
||||
[[ -z $base ]] && echo "Current commit is not on a branch." && return 1
|
||||
|
||||
[[ -z $1 ]] && echo "Please specify target branch" && return 1
|
||||
target="$1"
|
||||
|
|
@ -812,7 +833,7 @@ _forgit_cherry_pick() {
|
|||
FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
fzf_exitval=$?
|
||||
[[ $fzf_exitval != 0 ]] && return $fzf_exitval
|
||||
[[ -z "$fzf_selection" ]] && return $fzf_exitval
|
||||
[[ -z $fzf_selection ]] && return $fzf_exitval
|
||||
|
||||
commits=()
|
||||
while IFS='' read -r commit; do
|
||||
|
|
@ -836,7 +857,7 @@ _forgit_cherry_pick_from_branch() {
|
|||
local opts branch exitval input_branch args base
|
||||
|
||||
base=$(git branch --show-current)
|
||||
[[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1
|
||||
[[ -z $base ]] && echo "Current commit is not on a branch." && return 1
|
||||
|
||||
args=("$@")
|
||||
if [[ $# -ne 0 ]]; then
|
||||
|
|
@ -850,8 +871,7 @@ _forgit_cherry_pick_from_branch() {
|
|||
"
|
||||
# loop until either the branch selector is closed or a commit to be cherry
|
||||
# picked has been selected from within a branch
|
||||
while true
|
||||
do
|
||||
while true; do
|
||||
if [[ -z $input_branch ]]; then
|
||||
branch="$(_forgit_branch_list --all | FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name)"
|
||||
else
|
||||
|
|
@ -859,7 +879,7 @@ _forgit_cherry_pick_from_branch() {
|
|||
fi
|
||||
|
||||
unset input_branch
|
||||
[[ -z "$branch" ]] && return 1
|
||||
[[ -z $branch ]] && return 1
|
||||
|
||||
_forgit_cherry_pick "$branch"
|
||||
|
||||
|
|
@ -870,7 +890,10 @@ _forgit_cherry_pick_from_branch() {
|
|||
|
||||
_forgit_rebase() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
_forgit_contains_non_flags "$@" && { git rebase "$@"; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
git rebase "$@"
|
||||
return $?
|
||||
}
|
||||
local opts graph target_commit prev_commit
|
||||
graph=()
|
||||
[[ $_forgit_log_graph_enable == true ]] && graph=(--graph)
|
||||
|
|
@ -885,10 +908,11 @@ _forgit_rebase() {
|
|||
"
|
||||
target_commit=$(
|
||||
git log "${graph[@]}" --color=always --format="$_forgit_log_format" |
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha)
|
||||
if [[ -n "$target_commit" ]]; then
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha
|
||||
)
|
||||
if [[ -n $target_commit ]]; then
|
||||
prev_commit=$(_forgit_previous_commit "$target_commit")
|
||||
git rebase -i "${_forgit_rebase_git_opts[@]}" "$@" "$prev_commit"
|
||||
fi
|
||||
|
|
@ -932,11 +956,12 @@ _forgit_edit_commit() {
|
|||
"
|
||||
target_commit=$(
|
||||
git log "${graph[@]}" --color=always --format="$_forgit_log_format" "$@" |
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha)
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha
|
||||
)
|
||||
# GIT_EDITOR=: is needed to skip the editor
|
||||
if [[ -n "$target_commit" ]] && GIT_EDITOR=: git commit "${git_opts[@]}" "$action" "$target_commit"; then
|
||||
if [[ -n $target_commit ]] && GIT_EDITOR=: git commit "${git_opts[@]}" "$action" "$target_commit"; then
|
||||
prev_commit=$(_forgit_previous_commit "$target_commit")
|
||||
# rebase will fail if there are unstaged changes so --autostash is needed to temporarily stash them
|
||||
# GIT_SEQUENCE_EDITOR=: is needed to skip the editor
|
||||
|
|
@ -961,10 +986,11 @@ _forgit_reword() {
|
|||
"
|
||||
target_commit=$(
|
||||
git log "${graph[@]}" --color=always --format="$_forgit_log_format" "$@" |
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha)
|
||||
if [[ -n "$target_commit" ]] && git commit "${git_opts[@]}" --fixup=reword:"$target_commit"; then
|
||||
_forgit_emojify |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha
|
||||
)
|
||||
if [[ -n $target_commit ]] && git commit "${git_opts[@]}" --fixup=reword:"$target_commit"; then
|
||||
prev_commit=$(_forgit_previous_commit "$target_commit")
|
||||
# rebase will fail if there are unstaged changes so --autostash is needed to temporarily stash them
|
||||
# GIT_SEQUENCE_EDITOR=: is needed to skip the editor
|
||||
|
|
@ -986,7 +1012,10 @@ _forgit_git_checkout_file() {
|
|||
_forgit_checkout_file() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local files opts
|
||||
_forgit_contains_non_flags "$@" && { _forgit_git_checkout_file "$@"; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
_forgit_git_checkout_file "$@"
|
||||
return $?
|
||||
}
|
||||
[[ $(_forgit_list_files --modified | wc -l) -eq 0 ]] && echo 'Nothing to checkout.' && return 1
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -999,7 +1028,7 @@ _forgit_checkout_file() {
|
|||
files+=("$file")
|
||||
done < <(_forgit_list_files --modified |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
[[ "${#files[@]}" -gt 0 ]] && _forgit_git_checkout_file "$@" "${files[@]}"
|
||||
[[ ${#files[@]} -gt 0 ]] && _forgit_git_checkout_file "$@" "${files[@]}"
|
||||
}
|
||||
|
||||
# git checkout-file from commit selector
|
||||
|
|
@ -1025,7 +1054,7 @@ _forgit_checkout_file_from_commit() {
|
|||
commit=$(_forgit_git_log "$_forgit_log_format" "$branch" "$@" |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
_forgit_extract_sha)
|
||||
[[ -n "$commit" ]] || return 0
|
||||
[[ -n $commit ]] || return 0
|
||||
|
||||
# select the file interactively
|
||||
opts="
|
||||
|
|
@ -1040,11 +1069,11 @@ _forgit_checkout_file_from_commit() {
|
|||
--prompt=\"${commit} > \"
|
||||
"
|
||||
file=$(_forgit_git_show "$commit" | FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
[[ -n "$file" ]] || return 0
|
||||
[[ -n $file ]] || return 0
|
||||
|
||||
# special case: when the file was deleted in the commit
|
||||
# check out the file from the previous commit.
|
||||
[[ "$file" =~ ^\[D\] ]] && commit="$commit~"
|
||||
[[ $file =~ ^\[D\] ]] && commit="$commit~"
|
||||
file=$(echo "$file" | _forgit_get_single_file_from_diff_line)
|
||||
|
||||
_forgit_git_checkout_file "$commit" -- "$file"
|
||||
|
|
@ -1061,7 +1090,7 @@ _forgit_checkout_branch() {
|
|||
_forgit_inside_work_tree || return 1
|
||||
# if called with arguments, check if branch exists, else create a new one
|
||||
if [[ $# -ne 0 ]]; then
|
||||
if [[ "$*" == "-" ]] || git show-branch "$@" &>/dev/null; then
|
||||
if [[ $* == "-" ]] || git show-branch "$@" &>/dev/null; then
|
||||
git switch "$@"
|
||||
else
|
||||
git switch -c "$@"
|
||||
|
|
@ -1082,10 +1111,10 @@ _forgit_checkout_branch() {
|
|||
_forgit_parse_array _forgit_checkout_branch_branch_git_opts "$FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS"
|
||||
branch="$(_forgit_branch_list "${_forgit_checkout_branch_branch_git_opts[@]:---all}" |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name)"
|
||||
[[ -z "$branch" ]] && return 1
|
||||
[[ -z $branch ]] && return 1
|
||||
|
||||
# track the remote branch if possible
|
||||
if [[ "$branch" == "remotes/"* ]]; then
|
||||
if [[ $branch == "remotes/"* ]]; then
|
||||
if git branch | grep -qw "${branch#remotes/*/}"; then
|
||||
# hack to force creating a new branch which tracks the remote if a local branch already exists
|
||||
_forgit_git_checkout_branch -b "track/${branch#remotes/*/}" --track "$branch"
|
||||
|
|
@ -1107,7 +1136,7 @@ _forgit_switch_branch() {
|
|||
_forgit_inside_work_tree || return 1
|
||||
# if called with arguments, check if branch exists, else create a new one
|
||||
if [[ $# -ne 0 ]]; then
|
||||
if [[ "$*" == "-" ]] || git show-branch "$@" &>/dev/null; then
|
||||
if [[ $* == "-" ]] || git show-branch "$@" &>/dev/null; then
|
||||
git switch "$@"
|
||||
else
|
||||
git switch -c "$@"
|
||||
|
|
@ -1128,10 +1157,10 @@ _forgit_switch_branch() {
|
|||
_forgit_parse_array _forgit_switch_branch_branch_git_opts "$FORGIT_SWITCH_BRANCH_BRANCH_GIT_OPTS"
|
||||
branch="$(_forgit_branch_list "${_forgit_switch_branch_branch_git_opts[@]:---all}" |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name)"
|
||||
[[ -z "$branch" ]] && return 1
|
||||
[[ -z $branch ]] && return 1
|
||||
|
||||
# track the remote branch if possible
|
||||
if [[ "$branch" == "remotes/"* ]]; then
|
||||
if [[ $branch == "remotes/"* ]]; then
|
||||
if git branch | grep -qw "${branch#remotes/*/}"; then
|
||||
# hack to force creating a new branch which tracks the remote if a local branch already exists
|
||||
_forgit_git_switch_branch --create "track/${branch#remotes/*/}" --track "$branch"
|
||||
|
|
@ -1153,7 +1182,10 @@ _forgit_git_checkout_tag() {
|
|||
_forgit_checkout_tag() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts tag
|
||||
[[ $# -ne 0 ]] && { _forgit_git_checkout_tag "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_checkout_tag "$@"
|
||||
return $?
|
||||
}
|
||||
[[ $(git tag -l | wc -l) -eq 0 ]] && echo 'Nothing to checkout: there are no tags.' && return 1
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1162,7 +1194,7 @@ _forgit_checkout_tag() {
|
|||
$FORGIT_CHECKOUT_TAG_FZF_OPTS
|
||||
"
|
||||
tag="$(git tag -l --sort=-v:refname | FZF_DEFAULT_OPTS="$opts" fzf)"
|
||||
[[ -z "$tag" ]] && return 1
|
||||
[[ -z $tag ]] && return 1
|
||||
_forgit_git_checkout_tag "$tag"
|
||||
}
|
||||
|
||||
|
|
@ -1182,7 +1214,10 @@ _forgit_git_checkout_commit() {
|
|||
_forgit_checkout_commit() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts graph commit
|
||||
[[ $# -ne 0 ]] && { _forgit_git_checkout_commit "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_checkout_commit "$@"
|
||||
return $?
|
||||
}
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
+s +m --tiebreak=index
|
||||
|
|
@ -1215,7 +1250,10 @@ _forgit_git_branch_delete() {
|
|||
_forgit_branch_delete() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts
|
||||
[[ $# -ne 0 ]] && { _forgit_git_branch_delete "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_branch_delete "$@"
|
||||
return $?
|
||||
}
|
||||
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1223,8 +1261,7 @@ _forgit_branch_delete() {
|
|||
--preview=\"$FORGIT preview branch_preview {}\"
|
||||
$FORGIT_BRANCH_DELETE_FZF_OPTS
|
||||
"
|
||||
for branch in $(_forgit_branch_list | FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name)
|
||||
do
|
||||
for branch in $(_forgit_branch_list | FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name); do
|
||||
_forgit_git_branch_delete "$branch"
|
||||
done
|
||||
}
|
||||
|
|
@ -1245,7 +1282,10 @@ _forgit_git_revert() {
|
|||
_forgit_revert_commit() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts commits IFS
|
||||
[[ $# -ne 0 ]] && { _forgit_git_revert "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_revert "$@"
|
||||
return $?
|
||||
}
|
||||
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1267,12 +1307,13 @@ _forgit_revert_commit() {
|
|||
commits+=("$commit")
|
||||
done < <(
|
||||
git log "${graph[@]}" --color=always --format="$_forgit_log_format" |
|
||||
_forgit_emojify |
|
||||
nl |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
sort -n -k 1 |
|
||||
cut -f2- |
|
||||
sed 's/^[^a-f^0-9]*\([a-f0-9]*\).*/\1/')
|
||||
_forgit_emojify |
|
||||
nl |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf |
|
||||
sort -n -k 1 |
|
||||
cut -f2- |
|
||||
sed 's/^[^a-f^0-9]*\([a-f0-9]*\).*/\1/'
|
||||
)
|
||||
|
||||
[ ${#commits[@]} -eq 0 ] && return 1
|
||||
|
||||
|
|
@ -1299,7 +1340,10 @@ _forgit_git_blame() {
|
|||
_forgit_blame() {
|
||||
_forgit_inside_work_tree || return 1
|
||||
local opts flags file
|
||||
_forgit_contains_non_flags "$@" && { _forgit_git_blame "$@"; return $?; }
|
||||
_forgit_contains_non_flags "$@" && {
|
||||
_forgit_git_blame "$@"
|
||||
return $?
|
||||
}
|
||||
flags=()
|
||||
while IFS='' read -r flag; do
|
||||
flags+=("$flag")
|
||||
|
|
@ -1312,7 +1356,7 @@ _forgit_blame() {
|
|||
# flags is not quoted here, which is fine given that they are retrieved
|
||||
# with git rev-parse and can only contain flags
|
||||
file=$(FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
[[ -z "$file" ]] && return 1
|
||||
[[ -z $file ]] && return 1
|
||||
_forgit_git_blame "$file" "${flags[@]}"
|
||||
}
|
||||
|
||||
|
|
@ -1335,8 +1379,8 @@ _forgit_path_preview() {
|
|||
}
|
||||
|
||||
_forgit_ignore() {
|
||||
[ -d "$FORGIT_GI_REPO_LOCAL" ] \
|
||||
|| _forgit_repo_update "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL"
|
||||
[ -d "$FORGIT_GI_REPO_LOCAL" ] ||
|
||||
_forgit_repo_update "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL"
|
||||
local IFS args opts
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1363,8 +1407,8 @@ export FORGIT_ATTR_REPO_LOCAL=${FORGIT_ATTR_REPO_LOCAL:-${XDG_CACHE_HOME:-$HOME/
|
|||
export FORGIT_ATTR_TEMPLATES=${FORGIT_ATTR_TEMPLATES:-$FORGIT_ATTR_REPO_LOCAL}
|
||||
|
||||
_forgit_attributes() {
|
||||
[ -d "$FORGIT_ATTR_REPO_LOCAL" ] \
|
||||
|| _forgit_repo_update "$FORGIT_ATTR_REPO_REMOTE" "$FORGIT_ATTR_REPO_LOCAL"
|
||||
[ -d "$FORGIT_ATTR_REPO_LOCAL" ] ||
|
||||
_forgit_repo_update "$FORGIT_ATTR_REPO_REMOTE" "$FORGIT_ATTR_REPO_LOCAL"
|
||||
local IFS args opts
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1389,7 +1433,7 @@ _forgit_repo_update() {
|
|||
local remote path
|
||||
remote=$1
|
||||
path=$2
|
||||
if [[ -d "$path" ]]; then
|
||||
if [[ -d $path ]]; then
|
||||
_forgit_info 'Updating repo...'
|
||||
(cd "$path" && git pull --no-rebase --ff) || return 1
|
||||
else
|
||||
|
|
@ -1405,7 +1449,7 @@ _forgit_path_get() {
|
|||
shift 2
|
||||
for item in "$@"; do
|
||||
if filename=$(find -L "$path" -type f \( -iname "${item}$ext" -o -iname "${item}" \) -print -quit); then
|
||||
[[ -z "$filename" ]] && _forgit_warn "No template found for '$item'." && continue
|
||||
[[ -z $filename ]] && _forgit_warn "No template found for '$item'." && continue
|
||||
header="${filename##*/}" && header="${header%"$ext"}"
|
||||
echo "### $header" && cat "$filename" && echo
|
||||
fi
|
||||
|
|
@ -1416,7 +1460,7 @@ _forgit_paths_list() {
|
|||
local path ext
|
||||
path=$1
|
||||
ext=$2
|
||||
find "$path" -name "*$ext" -print |sed -e "s#$ext\$##" -e 's#.*/##' -e '/^$/d' | sort -fu
|
||||
find "$path" -name "*$ext" -print | sed -e "s#$ext\$##" -e 's#.*/##' -e '/^$/d' | sort -fu
|
||||
}
|
||||
|
||||
# Get the root path of the main worktree (not the current worktree)
|
||||
|
|
@ -1458,9 +1502,9 @@ _forgit_worktree_list() {
|
|||
"")
|
||||
relative_date=$(git log -1 --format='%cr' "$head" 2>/dev/null)
|
||||
local current_marker=" " lock_marker=" "
|
||||
[[ "$worktree" == "$current_worktree" ]] && current_marker="*"
|
||||
[[ -n "$prunable" ]] && lock_marker="$prunable"
|
||||
[[ -n "$locked" ]] && lock_marker="$locked"
|
||||
[[ $worktree == "$current_worktree" ]] && current_marker="*"
|
||||
[[ -n $prunable ]] && lock_marker="$prunable"
|
||||
[[ -n $locked ]] && lock_marker="$locked"
|
||||
printf "[%s%s] %s ${_cyan}(%s)${_reset} ${_gray}%s${_reset}\n" \
|
||||
"$current_marker" "$lock_marker" "$worktree" "${branch:-HEAD}" "$relative_date"
|
||||
;;
|
||||
|
|
@ -1491,7 +1535,7 @@ _forgit_worktree_toggle_lock() {
|
|||
local line="$1" worktree stripped
|
||||
worktree=$(echo "$line" | _forgit_extract_worktree_path)
|
||||
stripped=$(echo "$line" | _forgit_strip_ansi)
|
||||
if [[ "${stripped:2:1}" == "L" ]]; then
|
||||
if [[ ${stripped:2:1} == "L" ]]; then
|
||||
git worktree unlock "$worktree"
|
||||
else
|
||||
git worktree lock "$worktree"
|
||||
|
|
@ -1502,11 +1546,11 @@ _forgit_worktree_toggle_lock() {
|
|||
_forgit_worktree_preview() {
|
||||
local worktree
|
||||
worktree=$(echo "$1" | _forgit_extract_worktree_path)
|
||||
[[ ! -d "$worktree" ]] && echo "Worktree directory not found: $worktree" && return 1
|
||||
[[ ! -d $worktree ]] && echo "Worktree directory not found: $worktree" && return 1
|
||||
|
||||
local status_output
|
||||
status_output=$(git -c color.status=always -C "$worktree" status -s 2>/dev/null)
|
||||
[[ -n "$status_output" ]] && echo "$status_output" && echo ""
|
||||
[[ -n $status_output ]] && echo "$status_output" && echo ""
|
||||
git -C "$worktree" log --oneline -n 200 --color=always 2>/dev/null
|
||||
}
|
||||
|
||||
|
|
@ -1523,7 +1567,10 @@ _forgit_git_worktree_delete() {
|
|||
_forgit_worktree() {
|
||||
_forgit_inside_git_repo || return 1
|
||||
local opts worktree
|
||||
[[ $# -ne 0 ]] && { git worktree "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
git worktree "$@"
|
||||
return $?
|
||||
}
|
||||
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1534,7 +1581,7 @@ _forgit_worktree() {
|
|||
$FORGIT_WORKTREE_FZF_OPTS
|
||||
"
|
||||
worktree=$(_forgit_worktree_list | FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
[[ -z "$worktree" ]] && return 1
|
||||
[[ -z $worktree ]] && return 1
|
||||
echo "$worktree" | _forgit_extract_worktree_path
|
||||
}
|
||||
|
||||
|
|
@ -1542,11 +1589,14 @@ _forgit_worktree() {
|
|||
_forgit_worktree_delete() {
|
||||
_forgit_inside_git_repo || return 1
|
||||
local opts worktrees
|
||||
[[ $# -ne 0 ]] && { _forgit_git_worktree_delete "$@"; return $?; }
|
||||
[[ $# -ne 0 ]] && {
|
||||
_forgit_git_worktree_delete "$@"
|
||||
return $?
|
||||
}
|
||||
|
||||
local candidates
|
||||
candidates=$(_forgit_worktree_list_deletable)
|
||||
if [[ -z "$candidates" ]]; then
|
||||
if [[ -z $candidates ]]; then
|
||||
echo "Nothing to delete."
|
||||
return 1
|
||||
fi
|
||||
|
|
@ -1562,7 +1612,7 @@ _forgit_worktree_delete() {
|
|||
|
||||
worktrees=()
|
||||
while IFS='' read -r line; do
|
||||
[[ -n "$line" ]] && worktrees+=("$(echo "$line" | _forgit_extract_worktree_path)")
|
||||
[[ -n $line ]] && worktrees+=("$(echo "$line" | _forgit_extract_worktree_path)")
|
||||
done < <(echo "$candidates" | FZF_DEFAULT_OPTS="$opts" fzf)
|
||||
|
||||
[[ ${#worktrees[@]} -eq 0 ]] && return 1
|
||||
|
|
@ -1591,7 +1641,7 @@ _forgit_worktree_add() {
|
|||
_forgit_parse_array _forgit_worktree_add_branch_git_opts "$FORGIT_WORKTREE_ADD_BRANCH_GIT_OPTS"
|
||||
|
||||
local header_opt=""
|
||||
[[ -z "$new_branch" ]] && header_opt="--header-lines=1"
|
||||
[[ -z $new_branch ]] && header_opt="--header-lines=1"
|
||||
|
||||
opts="
|
||||
$FORGIT_FZF_DEFAULT_OPTS
|
||||
|
|
@ -1601,12 +1651,12 @@ _forgit_worktree_add() {
|
|||
"
|
||||
branch=$(_forgit_branch_list "${_forgit_worktree_add_branch_git_opts[@]:---all}" |
|
||||
FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_branch_name)
|
||||
[[ -z "$branch" ]] && return 1
|
||||
[[ -z $branch ]] && return 1
|
||||
|
||||
# Strip remotes/<remote>/ prefix for remote branches
|
||||
local local_branch="${branch#remotes/*/}"
|
||||
|
||||
if [[ -n "$new_branch" ]]; then
|
||||
if [[ -n $new_branch ]]; then
|
||||
# gwa <new-branch>: create new branch from selected base
|
||||
local target="$wt_dir/$new_branch"
|
||||
git worktree add -b "$new_branch" "$target" "$branch" >&2 && echo "$target"
|
||||
|
|
@ -1623,14 +1673,14 @@ check_prequisites() {
|
|||
|
||||
# Check if fzf is installed
|
||||
installed_fzf_version=$(fzf --version 2>/dev/null | awk '{print $1}')
|
||||
if [[ -z "$installed_fzf_version" ]]; then
|
||||
if [[ -z $installed_fzf_version ]]; then
|
||||
echo "fzf is not installed. Please install fzf first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check fzf version
|
||||
higher_fzf_version=$(printf '%s\n' "$REQUIRED_FZF_VERSION" "$installed_fzf_version" | sort -V | tail -n1)
|
||||
if [[ "$higher_fzf_version" != "$installed_fzf_version" ]]; then
|
||||
if [[ $higher_fzf_version != "$installed_fzf_version" ]]; then
|
||||
echo "fzf version $REQUIRED_FZF_VERSION or higher is required. You have $installed_fzf_version."
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -1651,7 +1701,7 @@ main() {
|
|||
|
||||
# shellcheck disable=SC2076
|
||||
if [[ ! " ${PUBLIC_COMMANDS[*]} " =~ " ${cmd} " ]] && [[ ! " ${PRIVATE_COMMANDS[*]} " =~ " ${cmd} " ]]; then
|
||||
if [[ -z "$cmd" ]]; then
|
||||
if [[ -z $cmd ]]; then
|
||||
printf "forgit: missing command\n\n"
|
||||
else
|
||||
printf "forgit: '%s' is not a valid forgit command.\n\n" "$cmd"
|
||||
|
|
@ -1718,7 +1768,7 @@ PRIVATE_COMMANDS=(
|
|||
|
||||
# Check if the script is being sourced. This is necessary for unit tests where
|
||||
# we do not want to execute the main function.
|
||||
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
|
||||
if [[ ${BASH_SOURCE[0]} != "$0" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -10,36 +10,30 @@
|
|||
# When using forgit via the shell plugin, source this file explicitly after
|
||||
# forgit.plugin.zsh to enable tab completion for shell functions and aliases.
|
||||
|
||||
_git_branch_delete()
|
||||
{
|
||||
_git_branch_delete() {
|
||||
__gitcomp_nl "$(__git_heads)"
|
||||
}
|
||||
|
||||
_git_checkout_branch()
|
||||
{
|
||||
_git_checkout_branch() {
|
||||
__gitcomp_nl "$(__git branch -a --format '%(refname:short)')"
|
||||
}
|
||||
|
||||
_git_checkout_file()
|
||||
{
|
||||
_git_checkout_file() {
|
||||
__gitcomp_nl "$(__git ls-files --modified)"
|
||||
}
|
||||
|
||||
_git_checkout_tag()
|
||||
{
|
||||
_git_checkout_tag() {
|
||||
__gitcomp_nl "$(__git_tags)"
|
||||
}
|
||||
|
||||
_git_stash_show()
|
||||
{
|
||||
_git_stash_show() {
|
||||
__gitcomp_nl "$(__git stash list | sed -n -e 's/:.*//p')"
|
||||
}
|
||||
|
||||
_git_worktrees()
|
||||
{
|
||||
_git_worktrees() {
|
||||
local wt_list="" field
|
||||
while IFS= read -r -d '' field; do
|
||||
[[ "$field" == worktree\ * ]] && wt_list+="${field#worktree }"$'\n'
|
||||
[[ $field == worktree\ * ]] && wt_list+="${field#worktree }"$'\n'
|
||||
done < <(__git worktree list --porcelain -z 2>/dev/null)
|
||||
__gitcomp_nl "$wt_list"
|
||||
}
|
||||
|
|
@ -47,20 +41,18 @@ _git_worktrees()
|
|||
# Completion for git-forgit
|
||||
# This includes git aliases, e.g. "alias.cb=forgit checkout_branch" will
|
||||
# correctly complete available branches on "git cb".
|
||||
_git_forgit()
|
||||
{
|
||||
_git_forgit() {
|
||||
local subcommand cword cur prev cmds
|
||||
|
||||
subcommand="${COMP_WORDS[1]}"
|
||||
if [[ "$subcommand" != "forgit" ]]
|
||||
then
|
||||
if [[ $subcommand != "forgit" ]]; then
|
||||
# Forgit is obviously called via a git alias. Get the original
|
||||
# aliased subcommand and proceed as if it was the previous word.
|
||||
prev=$(git config --get "alias.$subcommand" | cut -d' ' -f 2)
|
||||
cword=$((${COMP_CWORD} + 1))
|
||||
cword=$((COMP_CWORD + 1))
|
||||
else
|
||||
cword=${COMP_CWORD}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
prev=${COMP_WORDS[COMP_CWORD - 1]}
|
||||
fi
|
||||
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
|
@ -140,8 +132,7 @@ _git_forgit()
|
|||
}
|
||||
|
||||
# Check if forgit plugin is loaded
|
||||
if [[ $(type -t forgit::add) == function ]]
|
||||
then
|
||||
if [[ $(type -t forgit::add) == function ]]; then
|
||||
# We're reusing existing git completion functions, so load those first
|
||||
# and check if completion function exists afterwards.
|
||||
_completion_loader git
|
||||
|
|
@ -175,7 +166,7 @@ then
|
|||
__git_complete forgit::worktree::delete _git_worktrees
|
||||
|
||||
# Completion for forgit plugin shell aliases
|
||||
if [[ -z "$FORGIT_NO_ALIASES" ]]; then
|
||||
if [[ -z $FORGIT_NO_ALIASES ]]; then
|
||||
__git_complete "${forgit_add}" _git_add
|
||||
__git_complete "${forgit_branch_delete}" _git_branch_delete
|
||||
__git_complete "${forgit_checkout_branch}" _git_checkout_branch
|
||||
|
|
|
|||
|
|
@ -5,17 +5,20 @@
|
|||
# These shell built-ins prevent the wrong commands getting executed in case a
|
||||
# user added a shell alias with the same name.
|
||||
|
||||
forgit::error() { command printf "%b[Error]%b %s\n" '\e[0;31m' '\e[0m' "$@" >&2; builtin return 1; }
|
||||
forgit::error() {
|
||||
command printf "%b[Error]%b %s\n" '\e[0;31m' '\e[0m' "$@" >&2
|
||||
builtin return 1
|
||||
}
|
||||
forgit::warn() { command printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$@" >&2; }
|
||||
|
||||
# determine installation path
|
||||
if [[ -n "$ZSH_VERSION" ]]; then
|
||||
if [[ -n $ZSH_VERSION ]]; then
|
||||
# shellcheck disable=2277,2296,2299
|
||||
0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}"
|
||||
# shellcheck disable=2277,2296,2298
|
||||
0="${${(M)0:#/*}:-$PWD/$0}"
|
||||
FORGIT_INSTALL_DIR="${0:h}"
|
||||
elif [[ -n "$BASH_VERSION" ]]; then
|
||||
elif [[ -n $BASH_VERSION ]]; then
|
||||
FORGIT_INSTALL_DIR="$(command dirname -- "${BASH_SOURCE[0]}")"
|
||||
else
|
||||
forgit::error "Only zsh and bash are supported"
|
||||
|
|
@ -28,9 +31,10 @@ FORGIT="$FORGIT_INSTALL_DIR/bin/git-forgit"
|
|||
# export all user-defined FORGIT variables to make them available in git-forgit
|
||||
unexported_vars=0
|
||||
# Set posix mode in bash to only get variables, see #256.
|
||||
[[ -n "$BASH_VERSION" ]] && builtin set -o posix
|
||||
[[ -n $BASH_VERSION ]] && builtin set -o posix
|
||||
builtin set | command awk -F '=' '{ print $1 }' | command grep FORGIT_ | while builtin read -r var; do
|
||||
if ! builtin export | command grep -q "\(^$var=\|^export $var=\)"; then if [[ $unexported_vars == 0 ]]; then
|
||||
if ! builtin export | command grep -q "\(^$var=\|^export $var=\)"; then
|
||||
if [[ $unexported_vars == 0 ]]; then
|
||||
forgit::warn "Config options have to be exported in future versions of forgit."
|
||||
forgit::warn "Please update your config accordingly:"
|
||||
fi
|
||||
|
|
@ -41,7 +45,7 @@ builtin set | command awk -F '=' '{ print $1 }' | command grep FORGIT_ | while b
|
|||
fi
|
||||
done
|
||||
builtin unset unexported_vars
|
||||
[[ -n "$BASH_VERSION" ]] && builtin set +o posix
|
||||
[[ -n $BASH_VERSION ]] && builtin set +o posix
|
||||
|
||||
# register shell functions
|
||||
forgit::log() {
|
||||
|
|
@ -165,16 +169,19 @@ forgit::attributes() {
|
|||
}
|
||||
|
||||
forgit::worktree() {
|
||||
if [[ $# -ne 0 ]]; then "$FORGIT" worktree "$@"; return $?; fi
|
||||
if [[ $# -ne 0 ]]; then
|
||||
"$FORGIT" worktree "$@"
|
||||
return $?
|
||||
fi
|
||||
local tree
|
||||
tree=$("$FORGIT" worktree) || return $?
|
||||
[[ -d "$tree" ]] && builtin cd "$tree" || return 1
|
||||
[[ -d $tree ]] && builtin cd "$tree" || return 1
|
||||
}
|
||||
|
||||
forgit::worktree::add() {
|
||||
local tree
|
||||
tree=$("$FORGIT" worktree_add "$@") || return $?
|
||||
[[ -d "$tree" ]] || return 0
|
||||
[[ -d $tree ]] || return 0
|
||||
builtin cd "$tree" || return 1
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +191,7 @@ forgit::worktree::delete() {
|
|||
|
||||
# register aliases
|
||||
# shellcheck disable=SC2139
|
||||
if [[ -z "$FORGIT_NO_ALIASES" ]]; then
|
||||
if [[ -z $FORGIT_NO_ALIASES ]]; then
|
||||
|
||||
builtin export forgit_add="${forgit_add:-ga}"
|
||||
builtin export forgit_reset_head="${forgit_reset_head:-grh}"
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ function test_forgit_clean_select_files_preview() {
|
|||
assert_file_exists "$file"
|
||||
}
|
||||
|
||||
function provider_clean_select_files() {
|
||||
bashunit::data_set 1
|
||||
bashunit::data_set 2
|
||||
bashunit::data_set 3
|
||||
bashunit::data_set 4
|
||||
}
|
||||
function provider_clean_select_files() {
|
||||
bashunit::data_set 1
|
||||
bashunit::data_set 2
|
||||
bashunit::data_set 3
|
||||
bashunit::data_set 4
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ function set_up_before_script() {
|
|||
git config user.email "test@example.com"
|
||||
git config user.name "Test User"
|
||||
# Create an initial commit so we have a valid repo
|
||||
echo "initial" > README.md
|
||||
echo "initial" >README.md
|
||||
git add README.md
|
||||
git commit -q -m "Initial commit"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ function test_forgit_get_files_from_diff_line() {
|
|||
local i
|
||||
|
||||
while IFS= read -r line; do
|
||||
actual+=( "$line" )
|
||||
done < <( echo -n "$input" | _forgit_get_files_from_diff_line | xargs -0 -n 1 echo )
|
||||
actual+=("$line")
|
||||
done < <(echo -n "$input" | _forgit_get_files_from_diff_line | xargs -0 -n 1 echo)
|
||||
|
||||
# Compare array sizes
|
||||
assert_same "${#expected[@]}" "${#actual[@]}"
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ function test_forgit_pager_uses_preview_pager_only_in_explicit_preview_context()
|
|||
|
||||
without_marker=$(
|
||||
FORGIT_DIFF_PAGER="printf diff" \
|
||||
FORGIT_PREVIEW_PAGER="printf preview" \
|
||||
FZF_PREVIEW_COLUMNS=80 \
|
||||
_forgit_pager diff
|
||||
FORGIT_PREVIEW_PAGER="printf preview" \
|
||||
FZF_PREVIEW_COLUMNS=80 \
|
||||
_forgit_pager diff
|
||||
)
|
||||
with_marker=$(
|
||||
FORGIT_DIFF_PAGER="printf diff" \
|
||||
FORGIT_PREVIEW_PAGER="printf preview" \
|
||||
FORGIT_IN_PREVIEW=1 \
|
||||
_forgit_pager diff
|
||||
FORGIT_PREVIEW_PAGER="printf preview" \
|
||||
FORGIT_IN_PREVIEW=1 \
|
||||
_forgit_pager diff
|
||||
)
|
||||
|
||||
assert_same "diff" "$without_marker"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
FORGIT_REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
|
||||
function set_up_before_script() {
|
||||
function set_up_before_script() {
|
||||
source bin/git-forgit
|
||||
|
||||
# Ignore global git config files
|
||||
|
|
@ -19,123 +19,122 @@ FORGIT_REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|||
git add .
|
||||
git commit -m "init" --quiet
|
||||
|
||||
echo modified > "modified file.txt"
|
||||
echo modified >"modified file.txt"
|
||||
|
||||
touch "staged file.txt"
|
||||
git add "staged file.txt"
|
||||
|
||||
touch "untracked_file.txt"
|
||||
touch 'untracked_with_\backslash'
|
||||
}
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_contains_modified() {
|
||||
local output
|
||||
function test_forgit_worktree_changes_contains_modified() {
|
||||
local output
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
assert_contains "modified file.txt" "$output"
|
||||
}
|
||||
assert_contains "modified file.txt" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_contains_untracked() {
|
||||
local output
|
||||
function test_forgit_worktree_changes_contains_untracked() {
|
||||
local output
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
assert_contains "untracked_file.txt" "$output"
|
||||
}
|
||||
assert_contains "untracked_file.txt" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_excludes_staged() {
|
||||
local output
|
||||
function test_forgit_worktree_changes_excludes_staged() {
|
||||
local output
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_not_contains "staged file.txt" "$output"
|
||||
}
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_not_contains "staged file.txt" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_excludes_tracked() {
|
||||
local output
|
||||
|
||||
function test_forgit_worktree_changes_excludes_tracked() {
|
||||
local output
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_not_contains "tracked file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_not_contains "tracked file.txt" "$output"
|
||||
}
|
||||
function test_forgit_worktree_changes_supports_backslashes() {
|
||||
local output
|
||||
|
||||
function test_forgit_worktree_changes_supports_backslashes() {
|
||||
local output
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains 'untracked_with_\backslash' "$output"
|
||||
}
|
||||
|
||||
assert_contains 'untracked_with_\backslash' "$output"
|
||||
}
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_within_subdirectories() {
|
||||
local output
|
||||
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_within_subdirectories() {
|
||||
local output
|
||||
mkdir -p dir
|
||||
touch dir/file.txt
|
||||
cd dir || return 1
|
||||
|
||||
mkdir -p dir
|
||||
touch dir/file.txt
|
||||
cd dir || return 1
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains "file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_contains "file.txt" "$output"
|
||||
}
|
||||
function test_forgit_build_status_entries_prefixes_parent_paths_for_entries_outside_cwd() {
|
||||
local output
|
||||
|
||||
function test_forgit_build_status_entries_prefixes_parent_paths_for_entries_outside_cwd() {
|
||||
local output
|
||||
mkdir -p dir other
|
||||
touch other/file.txt
|
||||
cd dir || return 1
|
||||
|
||||
mkdir -p dir other
|
||||
touch other/file.txt
|
||||
cd dir || return 1
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains "../other/file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_contains "../other/file.txt" "$output"
|
||||
}
|
||||
function test_forgit_build_status_entries_keeps_repo_relative_paths_at_repo_root() {
|
||||
local output
|
||||
|
||||
function test_forgit_build_status_entries_keeps_repo_relative_paths_at_repo_root() {
|
||||
local output
|
||||
mkdir -p dir
|
||||
touch dir/file.txt
|
||||
|
||||
mkdir -p dir
|
||||
touch dir/file.txt
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains "dir/file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_contains "dir/file.txt" "$output"
|
||||
}
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_for_sibling_entries() {
|
||||
local output
|
||||
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_for_sibling_entries() {
|
||||
local output
|
||||
mkdir -p dir1 dir2
|
||||
touch dir1/file.txt
|
||||
cd dir2 || return 1
|
||||
|
||||
mkdir -p dir1 dir2
|
||||
touch dir1/file.txt
|
||||
cd dir2 || return 1
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains "../dir1/file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_contains "../dir1/file.txt" "$output"
|
||||
}
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_from_logical_symlink_paths() {
|
||||
local output sandbox
|
||||
|
||||
function test_forgit_build_status_entries_uses_cwd_relative_display_paths_from_logical_symlink_paths() {
|
||||
local output sandbox
|
||||
sandbox=$(bashunit::temp_dir)
|
||||
mkdir -p "$sandbox/real/dir1" "$sandbox/real/dir2"
|
||||
(
|
||||
cd "$sandbox/real" || exit 1
|
||||
git init --quiet
|
||||
git config user.name "Test User"
|
||||
git config user.email "test@example.com"
|
||||
) || return 1
|
||||
ln -s "$sandbox/real" "$sandbox/link"
|
||||
cd "$sandbox/link/dir2" || return 1
|
||||
touch ../dir1/file.txt
|
||||
|
||||
sandbox=$(bashunit::temp_dir)
|
||||
mkdir -p "$sandbox/real/dir1" "$sandbox/real/dir2"
|
||||
(
|
||||
cd "$sandbox/real" || exit 1
|
||||
git init --quiet
|
||||
git config user.name "Test User"
|
||||
git config user.email "test@example.com"
|
||||
) || return 1
|
||||
ln -s "$sandbox/real" "$sandbox/link"
|
||||
cd "$sandbox/link/dir2" || return 1
|
||||
touch ../dir1/file.txt
|
||||
output=$(_forgit_worktree_changes)
|
||||
|
||||
output=$(_forgit_worktree_changes)
|
||||
assert_contains "../dir1/file.txt" "$output"
|
||||
}
|
||||
|
||||
assert_contains "../dir1/file.txt" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_emits_absolute_payloads_for_subdir_entries() {
|
||||
function test_forgit_worktree_changes_emits_absolute_payloads_for_subdir_entries() {
|
||||
local output rootdir
|
||||
|
||||
mkdir dir
|
||||
|
|
@ -148,24 +147,24 @@ FORGIT_REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|||
assert_contains $'with_\\backslash'"$_ffsep""$rootdir/dir/with_\\backslash" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_restore_untracked_color_colorizes_plain_untracked_lines() {
|
||||
local output
|
||||
function test_forgit_restore_untracked_color_colorizes_plain_untracked_lines() {
|
||||
local output
|
||||
|
||||
output=$(printf '?? plain.txt\n' | _forgit_restore_untracked_color '<u>' '<r>')
|
||||
output=$(printf '?? plain.txt\n' | _forgit_restore_untracked_color '<u>' '<r>')
|
||||
|
||||
assert_same '<u>??<r> plain.txt' "$output"
|
||||
}
|
||||
assert_same '<u>??<r> plain.txt' "$output"
|
||||
}
|
||||
|
||||
function test_forgit_restore_untracked_color_leaves_colored_lines_unchanged() {
|
||||
local colored output
|
||||
function test_forgit_restore_untracked_color_leaves_colored_lines_unchanged() {
|
||||
local colored output
|
||||
|
||||
colored=$'\033[33m??\033[m plain.txt'
|
||||
output=$(printf '%s\n' "$colored" | _forgit_restore_untracked_color '<u>' '<r>')
|
||||
colored=$'\033[33m??\033[m plain.txt'
|
||||
output=$(printf '%s\n' "$colored" | _forgit_restore_untracked_color '<u>' '<r>')
|
||||
|
||||
assert_same "$colored" "$output"
|
||||
}
|
||||
assert_same "$colored" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_preserves_special_characters_in_payload() {
|
||||
function test_forgit_worktree_changes_preserves_special_characters_in_payload() {
|
||||
local output path rootdir
|
||||
|
||||
path=$'tab\t space \\ name.txt'
|
||||
|
|
@ -177,28 +176,28 @@ FORGIT_REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|||
assert_contains "${path}${_ffsep}${rootdir}/${path}" "$output"
|
||||
}
|
||||
|
||||
function test_forgit_fzf_separator_does_not_use_literal_tabs() {
|
||||
function test_forgit_fzf_separator_does_not_use_literal_tabs() {
|
||||
local delimiter
|
||||
|
||||
delimiter=$_ffsep
|
||||
|
||||
assert_not_contains $'\t' "$delimiter"
|
||||
}
|
||||
}
|
||||
|
||||
function test_forgit_worktree_changes_works_in_zsh() {
|
||||
local output
|
||||
function test_forgit_worktree_changes_works_in_zsh() {
|
||||
local output
|
||||
|
||||
output=$(
|
||||
zsh -c '
|
||||
output=$(
|
||||
zsh -c '
|
||||
source "'"$FORGIT_REPO_ROOT"'/bin/git-forgit"
|
||||
cd "$(mktemp -d)" || exit 1
|
||||
git init --quiet
|
||||
touch "space name.txt" "back\\slash.txt" $'"'"'tab\tname.txt'"'"'
|
||||
_forgit_worktree_changes
|
||||
'
|
||||
)
|
||||
)
|
||||
|
||||
assert_contains 'space name.txt' "$output"
|
||||
assert_contains 'back\slash.txt' "$output"
|
||||
assert_contains 'tab' "$output"
|
||||
}
|
||||
assert_contains 'space name.txt' "$output"
|
||||
assert_contains 'back\slash.txt' "$output"
|
||||
assert_contains 'tab' "$output"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue