Ensure that grc and gcp always have the correct ordering, regardless of how they were input (#261) (#253)

Closes #253. Essentially the idea is this:

    When cherry picking a group of commits, most of the time you want to cherry pick oldest to newest. This means you have the lowest chance of having a conflict or error
    when reverting a commit. You most often want to revert from newest to oldest. Similarly prevents errors

This commit does that, based on the wonderful suggestion on how to do that from @carlfriedrich in the linked ticket (#253).
This commit is contained in:
Chris Apple 2022-12-16 07:50:28 -07:00 committed by GitHub
parent 8ca463b5c6
commit 5a117b63cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -262,20 +262,30 @@ _forgit_clean() {
_forgit_cherry_pick() {
local base target preview opts fzf_selection fzf_exitval
base=$(git branch --show-current)
[[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1
[[ -z $1 ]] && echo "Please specify target branch" && return 1
target="$1"
preview="echo {} | $_forgit_extract_sha | xargs -I% git show --color=always % | $_forgit_show_pager"
# in this function, we do something interesting to maintain proper ordering as it's assumed
# you generally want to cherry pick oldest->newest when you multiselect
# The instances of "cut", "nl" and "sort" all serve this purpose
# Please see https://github.com/wfxr/forgit/issues/253 for more details
preview="echo {} | cut -f2- | $_forgit_extract_sha | xargs -I% git show --color=always % | $_forgit_show_pager"
opts="
$FORGIT_FZF_DEFAULT_OPTS
--preview=\"$preview\"
-m -0 --tiebreak=index
--multi --ansi --with-nth 2.. -0 --tiebreak=index
$FORGIT_CHERRY_PICK_FZF_OPTS
"
fzf_selection=$(git cherry "$base" "$target" --abbrev -v | _forgit_reverse_lines |
FZF_DEFAULT_OPTS="$opts" fzf)
fzf_selection=$(git cherry "$base" "$target" --abbrev -v | nl | _forgit_reverse_lines |
FZF_DEFAULT_OPTS="$opts" fzf | sort --numeric-sort --key=1 --reverse | cut -f2-)
fzf_exitval=$?
[[ $fzf_exitval != 0 ]] && return $fzf_exitval
[[ -z "$fzf_selection" ]] && return $fzf_exitval
commits=()
while IFS="" read -r line
@ -283,6 +293,8 @@ _forgit_cherry_pick() {
commits+=("$line")
done < <(echo "$fzf_selection" | _forgit_reverse_lines | cut -d' ' -f2)
[ ${#commits[@]} -eq 0 ] && return 1
git cherry-pick "${commits[@]}"
}
@ -484,23 +496,35 @@ _forgit_branch_delete() {
_forgit_revert_commit() {
_forgit_inside_work_tree || return 1
[[ $# -ne 0 ]] && { git revert "$@"; return $?; }
local cmd opts files preview commits IFS
cmd="git log --graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify"
opts="
$FORGIT_FZF_DEFAULT_OPTS
+s --tiebreak=index
--ansi --with-nth 2..
$FORGIT_REVERT_COMMIT_OPTS
"
# in this function, we do something interesting to maintain proper ordering as it's assumed
# you generally want to revert newest->oldest when you multiselect
# The instances of "cut", "nl" and "sort" all serve this purpose
# Please see https://github.com/wfxr/forgit/issues/253 for more details
files=$(sed -nE 's/.* -- (.*)/\1/p' <<< "$*") # extract files parameters for `git show` command
preview="echo {} | $_forgit_extract_sha | xargs -I% git show --color=always % -- $files | $_forgit_show_pager"
preview="echo {} | cut -f2- | $_forgit_extract_sha | xargs -I% git show --color=always % -- $files | $_forgit_show_pager"
# shellcheck disable=2207
IFS=$'\n' commits=($(eval "$cmd" |
FZF_DEFAULT_OPTS="$opts" fzf --preview="$preview" -m |
IFS=$'\n' commits=($(eval "$cmd" |
nl |
FZF_DEFAULT_OPTS="$opts" fzf --preview="$preview" -m |
sort --numeric-sort --key=1 |
cut -f2- |
sed 's/^[^a-f^0-9]*\([a-f0-9]*\).*/\1/'))
[ ${#commits[@]} -eq 0 ] && return 1
for commit in "${commits[@]}"; do
git revert "$commit"
done
git revert "${commits[@]}"
}
# git blame viewer