Merge pull request #223 from carlfriedrich/rebase-on-parent

grb: rebase on parent of the selected commit
This commit is contained in:
Wenxuan 2022-07-28 16:24:31 +08:00 committed by GitHub
commit 76b5d5cc86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 17 deletions

View file

@ -21,6 +21,15 @@ function forgit::reverse_lines
end
end
function forgit::previous_commit
# "SHA~" is invalid when the commit is the first commit, but we can use "--root" instead
if test (git rev-parse $argv) = (git rev-list --max-parents=0 HEAD)
echo "--root"
else
echo "$argv~"
end
end
# extract the first git sha occuring in the input and strip trailing newline
set -g forgit_extract_sha "grep -Eo '[a-f0-9]+' | head -1 | tr -d '[:space:]'"
@ -399,11 +408,7 @@ function forgit::fixup -d "git fixup"
set target_commit (eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
if test -n "$target_commit" && git commit --fixup "$target_commit"
# "$target_commit~" is invalid when the commit is the first commit, but we can use "--root" instead
set prev_commit "$target_commit~"
if test "(git rev-parse '$target_commit')" = "(git rev-list --max-parents=0 HEAD)"
set prev_commit "--root"
end
set prev_commit (forgit::previous_commit $target_commit)
GIT_SEQUENCE_EDITOR=: git rebase --autostash -i --autosquash "$prev_commit"
end
@ -437,10 +442,12 @@ function forgit::rebase -d "git rebase"
--preview=\"$preview\"
$FORGIT_REBASE_FZF_OPTS
"
set commit (eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
set target_commit (eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
if test $commit
git rebase -i "$commit"
if test $target_commit
set prev_commit (forgit::previous_commit $target_commit)
git rebase -i "$prev_commit"
end
end

View file

@ -6,6 +6,15 @@ forgit::inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null; }
# 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::previous_commit() {
# "SHA~" is invalid when the commit is the first commit, but we can use "--root" instead
if [[ "$(git rev-parse "$1")" == "$(git rev-list --max-parents=0 HEAD)" ]]; then
echo "--root"
else
echo "$1~"
fi
}
# optional render emoji characters (https://github.com/wfxr/emoji-cli)
hash emojify &>/dev/null && forgit_emojify='|emojify'
@ -177,7 +186,7 @@ forgit::cherry::pick() {
forgit::rebase() {
forgit::inside_work_tree || return 1
local cmd preview opts graph files commit
local cmd preview opts graph files target_commit prev_commit
graph=--graph
[[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph=
cmd="git log $graph --color=always --format='$forgit_log_format' $* $forgit_emojify"
@ -190,8 +199,12 @@ forgit::rebase() {
--preview=\"$preview\"
$FORGIT_REBASE_FZF_OPTS
"
commit=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
[[ -n "$commit" ]] && git rebase -i "$commit"
target_commit=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
if [[ -n "$target_commit" ]]; then
prev_commit=$(forgit::previous_commit $target_commit)
git rebase -i "$prev_commit"
fi
}
forgit::fixup() {
@ -212,12 +225,7 @@ forgit::fixup() {
"
target_commit=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$forgit_extract_sha")
if [[ -n "$target_commit" ]] && git commit --fixup "$target_commit"; then
# "$target_commit~" is invalid when the commit is the first commit, but we can use "--root" instead
if [[ "$(git rev-parse "$target_commit")" == "$(git rev-list --max-parents=0 HEAD)" ]]; then
prev_commit="--root"
else
prev_commit="$target_commit~"
fi
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
GIT_SEQUENCE_EDITOR=: git rebase --autostash -i --autosquash "$prev_commit"