From 53d0ea2f3864067838e9b01fc33d2a66f569a90d Mon Sep 17 00:00:00 2001 From: carlfriedrich Date: Tue, 12 Jul 2022 15:18:40 +0200 Subject: [PATCH 1/4] Add FORGIT_CHERRY_PICK_FZF_OPTS The gcp (git cherry pick) command was the only command which did not have a variable to set command-specific fzf options. Add the according variable to source code and documentation. --- README.md | 3 ++- conf.d/forgit.plugin.fish | 1 + forgit.plugin.zsh | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e7fed8..a2d4452 100644 --- a/README.md +++ b/README.md @@ -243,8 +243,9 @@ Customizing fzf options for each command individually is also supported: | `gss` | `FORGIT_STASH_FZF_OPTS` | | `gclean` | `FORGIT_CLEAN_FZF_OPTS` | | `grb` | `FORGIT_REBASE_FZF_OPTS` | -| `gbl` | `FORGIT_BLAME_FZF_OPTS` | +| `gbl` | `FORGIT_BLAME_FZF_OPTS` | | `gfu` | `FORGIT_FIXUP_FZF_OPTS` | +| `gcp` | `FORGIT_CHERRY_PICK_FZF_OPTS` | Complete loading order of fzf options is: diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index 3ddde42..ab74abe 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -340,6 +340,7 @@ function forgit::cherry::pick -d "git cherry-picking" --argument-names 'target' --preview=\"$preview\" $FORGIT_FZF_DEFAULT_OPTS -m -0 + $FORGIT_CHERRY_PICK_FZF_OPTS " echo $base echo $target diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 694c0bd..8237d5c 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -157,6 +157,7 @@ forgit::cherry::pick() { $FORGIT_FZF_DEFAULT_OPTS --preview=\"$preview\" -m -0 + $FORGIT_CHERRY_PICK_FZF_OPTS " git cherry "$base" "$target" --abbrev -v | cut -d ' ' -f2- | FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f1 | From 52d79009d1b106ffb3aaae88ec924bf83686edcd Mon Sep 17 00:00:00 2001 From: carlfriedrich Date: Tue, 12 Jul 2022 15:43:43 +0200 Subject: [PATCH 2/4] Preserve commit order on cherry pick When using a fzf find string which maches multiple lines, the commits could appear in a wrong order. Add "--tiebreak=index" to ensure that the correct commit order is preserved. --- conf.d/forgit.plugin.fish | 2 +- forgit.plugin.zsh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index ab74abe..266a78e 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -339,7 +339,7 @@ function forgit::cherry::pick -d "git cherry-picking" --argument-names 'target' set opts " --preview=\"$preview\" $FORGIT_FZF_DEFAULT_OPTS - -m -0 + -m -0 --tiebreak=index $FORGIT_CHERRY_PICK_FZF_OPTS " echo $base diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 8237d5c..1541895 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -156,7 +156,7 @@ forgit::cherry::pick() { opts=" $FORGIT_FZF_DEFAULT_OPTS --preview=\"$preview\" - -m -0 + -m -0 --tiebreak=index $FORGIT_CHERRY_PICK_FZF_OPTS " git cherry "$base" "$target" --abbrev -v | cut -d ' ' -f2- | From 1b7db0fb6e6cba254a9702b51716666c98cb1883 Mon Sep 17 00:00:00 2001 From: carlfriedrich Date: Tue, 12 Jul 2022 15:47:28 +0200 Subject: [PATCH 3/4] Preserve +/- information on cherry pick The output of 'git cherry' which is used to build the fzf input list for forgit::cherry::pick usually prefixes every line with a '-' for commits that have an equivalent in the target branch, and a '+' for commits that do not. Previously forgit removed this information from the list. However, for the actual cherry-picking process this information is relevant, so we should keep it. --- conf.d/forgit.plugin.fish | 4 ++-- forgit.plugin.zsh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index 266a78e..ba167c8 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -344,8 +344,8 @@ function forgit::cherry::pick -d "git cherry-picking" --argument-names 'target' " echo $base echo $target - git cherry "$base" "$target" --abbrev -v | cut -d ' ' -f2- | - env FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f1 | + git cherry "$base" "$target" --abbrev -v | + env FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | xargs -I% git cherry-pick % end diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 1541895..3e6210c 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -159,8 +159,8 @@ forgit::cherry::pick() { -m -0 --tiebreak=index $FORGIT_CHERRY_PICK_FZF_OPTS " - git cherry "$base" "$target" --abbrev -v | cut -d ' ' -f2- | - FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f1 | + git cherry "$base" "$target" --abbrev -v | + FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | xargs -I% git cherry-pick % } From fe5c4d988198ad48019b9d8bdc051d996948062b Mon Sep 17 00:00:00 2001 From: carlfriedrich Date: Tue, 12 Jul 2022 16:27:23 +0200 Subject: [PATCH 4/4] Reverse order on cherry pick Git log displays the newest commits on top of the list, while git cherry pick displays the newest commits at the bottom. Reverse the order of git cherry pick so that it has the same order like git log. --- conf.d/forgit.plugin.fish | 9 +++++++-- forgit.plugin.zsh | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index ba167c8..1845d54 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -12,6 +12,11 @@ function forgit::inside_work_tree git rev-parse --is-inside-work-tree >/dev/null; end +function forgit::reverse_lines + # tac is not available on OSX, tail -r is not available on Linux, so we use either of them + tac 2> /dev/null || tail -r +end + set -g forgit_pager "$FORGIT_PAGER" set -g forgit_show_pager "$FORGIT_SHOW_PAGER" set -g forgit_diff_pager "$FORGIT_DIFF_PAGER" @@ -344,8 +349,8 @@ function forgit::cherry::pick -d "git cherry-picking" --argument-names 'target' " echo $base echo $target - git cherry "$base" "$target" --abbrev -v | - env FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | + git cherry "$base" "$target" --abbrev -v | forgit::reverse_lines | + env FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | forgit::reverse_lines | xargs -I% git cherry-pick % end diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 3e6210c..5c11806 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -3,6 +3,8 @@ forgit::warn() { printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$@" >&2; } forgit::info() { printf "%b[Info]%b %s\n" '\e[0;32m' '\e[0m' "$@" >&2; } 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) } # optional render emoji characters (https://github.com/wfxr/emoji-cli) hash emojify &>/dev/null && forgit_emojify='|emojify' @@ -159,8 +161,8 @@ forgit::cherry::pick() { -m -0 --tiebreak=index $FORGIT_CHERRY_PICK_FZF_OPTS " - git cherry "$base" "$target" --abbrev -v | - FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | + git cherry "$base" "$target" --abbrev -v | forgit::reverse_lines | + FZF_DEFAULT_OPTS="$opts" fzf | cut -d' ' -f2 | forgit::reverse_lines | xargs -I% git cherry-pick % }