From a30cc59ebd9e034aedcd98c8b3ecad8ecb8f6f2a Mon Sep 17 00:00:00 2001 From: Martin Imre Date: Fri, 3 Jan 2025 10:03:49 +0100 Subject: [PATCH 1/4] feat: Allow sorting fixup candidates by author time (ASC/DESC) --- README.md | 11 ++++++++++- git-fixup | 32 +++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 266959c..4f5614a 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ script into your `$PATH` and `$fpath` respectively. ``` git-fixup [-s|--squash] [-f|--fixup] [-a|--amend] [-c|--commit] [--no-verify] - [--rebase] [-b|--base ] [] + [--rebase] [-b|--base ] [-S|--sort] [-r|--reverse] [] ``` For this tool to make any sense you should enable the `rebase.autosquash` @@ -143,6 +143,15 @@ If omitted, the default base commit is resolved in the following order: 4. Finally, the root commit (i.e. full history) if nothing of the above is satisfied. +### --sort + +Sorts the commits by author time ascending showing the oldest commit at index 1 +and the newest at the last index. + +### --reverse + +Reverses the sort order. + ## Configuration `git-fixup` uses configuration from the ENVIRONMENT or from `git config` diff --git a/git-fixup b/git-fixup index af66bb0..1b000e6 100755 --- a/git-fixup +++ b/git-fixup @@ -18,6 +18,8 @@ no-rebase Don't do a rebase after commit n,no-verify Bypass the pre-commit and commit-msg hooks b,base=rev Use as base of the revision range for the search A,all Show all candidates +S,sort Sort commits by time, newest first +r,reverse Reverse the sort " # shellcheck disable=SC2034 SUBDIRECTORY_OK=yes @@ -69,7 +71,11 @@ print_sha () { local sha=$1 local type=$2 - git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha" + if [ "$sort_by_time" = "true" ]; then + git --no-pager log --format="%ai %H [$type] %s <%ae>" -n 1 "$sha" + else + git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha" + fi } # Call git commit @@ -164,6 +170,18 @@ show_menu () { fi } +cut_time() { + awk '{print $4" "$5" "$6" "$7}' +} + +sort_commits () { + if [ "$sort_by_time" = "true" ]; then + sort -k1 $sort_flags | cut_time + else + awk '{print $0}' + fi +} + git_commit_args=() target= op=${GITFIXUPACTION:-$(git config --default=fixup fixup.action)} @@ -172,6 +190,8 @@ fixup_menu=${GITFIXUPMENU:-$(git config --default="" fixup.menu)} create_commit=${GITFIXUPCOMMIT:-$(git config --default=false --type bool fixup.commit)} base=${GITFIXUPBASE:-$(git config --default="" fixup.base)} show_all=false +sort_by_time=false +sort_flags="" while test $# -gt 0; do case "$1" in @@ -209,6 +229,12 @@ while test $# -gt 0; do -A|--all) show_all=true ;; + -S|--sort) + sort_by_time=true + ;; + -r|--reverse) + sort_flags="-r" + ;; --) shift break @@ -264,7 +290,7 @@ else fi if test "$create_commit" = "true"; then - target=$(print_candidates | show_menu) + target=$(print_candidates | sort_commits | show_menu) if test -z "$target"; then exit fi @@ -273,5 +299,5 @@ if test "$create_commit" = "true"; then call_rebase "${target%% *}" fi else - print_candidates + print_candidates | sort_commits fi From c47d9bd74c579e04d52ee8e3940f54b79946deef Mon Sep 17 00:00:00 2001 From: Martin Imre Date: Fri, 3 Jan 2025 10:04:43 +0100 Subject: [PATCH 2/4] feat: Allow displaying the commit time of fixup candidates This is a small quality of life improvement, but comes naturally when allowing to sort by time. --- README.md | 10 +++++++++- git-fixup | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f5614a..7640549 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ script into your `$PATH` and `$fpath` respectively. ``` git-fixup [-s|--squash] [-f|--fixup] [-a|--amend] [-c|--commit] [--no-verify] - [--rebase] [-b|--base ] [-S|--sort] [-r|--reverse] [] + [--rebase] [-b|--base ] [-S|--sort] [-r|--reverse] + [-t|--with-time] [] ``` For this tool to make any sense you should enable the `rebase.autosquash` @@ -152,6 +153,10 @@ and the newest at the last index. Reverses the sort order. +### --with-time + +Shows the commits in the menu with time in git's ISO 8601-like format (`%ai`). + ## Configuration `git-fixup` uses configuration from the ENVIRONMENT or from `git config` @@ -234,6 +239,9 @@ The following example is a fragment of a git config that makes `git fixup --prompt 'Select commit: ' ``` +If you want to use fzf's preview when showing the time, replace the `{+1}` with +a `{+4}` in the snippet above. + ## The default menu If you have not configured an external menu, the default menu is used. See the diff --git a/git-fixup b/git-fixup index 1b000e6..486ff93 100755 --- a/git-fixup +++ b/git-fixup @@ -20,6 +20,7 @@ b,base=rev Use as base of the revision range for the search A,all Show all candidates S,sort Sort commits by time, newest first r,reverse Reverse the sort +t,with-time Show the time of the commit " # shellcheck disable=SC2034 SUBDIRECTORY_OK=yes @@ -71,7 +72,7 @@ print_sha () { local sha=$1 local type=$2 - if [ "$sort_by_time" = "true" ]; then + if [[ "$sort_by_time" = "true" || "$show_time" = "true" ]]; then git --no-pager log --format="%ai %H [$type] %s <%ae>" -n 1 "$sha" else git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha" @@ -176,7 +177,11 @@ cut_time() { sort_commits () { if [ "$sort_by_time" = "true" ]; then - sort -k1 $sort_flags | cut_time + if [ "show_time" = "true"]; then + sort -k1 $sort_flags + else + sort -k1 $sort_flags | cut_time + fi else awk '{print $0}' fi @@ -192,6 +197,7 @@ base=${GITFIXUPBASE:-$(git config --default="" fixup.base)} show_all=false sort_by_time=false sort_flags="" +show_time=false while test $# -gt 0; do case "$1" in @@ -235,6 +241,9 @@ while test $# -gt 0; do -r|--reverse) sort_flags="-r" ;; + -t|--with-time) + show_time=true + ;; --) shift break @@ -294,6 +303,9 @@ if test "$create_commit" = "true"; then if test -z "$target"; then exit fi + if [ "$show_time" = "true" ]; then + target=$(echo $target | cut_time) + fi call_commit "${target%% *}" if test "$rebase" = "true"; then call_rebase "${target%% *}" From 3eb4e1893ead0fd6c3ad569d609093a02288cb84 Mon Sep 17 00:00:00 2001 From: Martin Imre Date: Sun, 5 Jan 2025 13:47:04 +0100 Subject: [PATCH 3/4] feat: Show commit ISO-time and sort commits by time This is now the default - for discussion check https://github.com/keis/git-fixup/pull/80. --- README.md | 31 ++++++++++++++++--------------- git-fixup | 40 ++++++---------------------------------- 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 7640549..1263ce8 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,7 @@ script into your `$PATH` and `$fpath` respectively. ``` git-fixup [-s|--squash] [-f|--fixup] [-a|--amend] [-c|--commit] [--no-verify] - [--rebase] [-b|--base ] [-S|--sort] [-r|--reverse] - [-t|--with-time] [] + [--rebase] [-b|--base ] [-r|--reverse] [] ``` For this tool to make any sense you should enable the `rebase.autosquash` @@ -144,18 +143,9 @@ If omitted, the default base commit is resolved in the following order: 4. Finally, the root commit (i.e. full history) if nothing of the above is satisfied. -### --sort - -Sorts the commits by author time ascending showing the oldest commit at index 1 -and the newest at the last index. - ### --reverse -Reverses the sort order. - -### --with-time - -Shows the commits in the menu with time in git's ISO 8601-like format (`%ai`). +Commits are sorted by time. `-r` reverses the sort order. ## Configuration @@ -207,6 +197,20 @@ a simple [default menu](the-default-menu) will be used. See [External menu](#external-menu) for more details and a more advanced example. +### fixup.additionalSortFlags + +Or `GITFIXUPADDITIONALSORTFLAGS` + +Sets the flags that are passed to sort in addition to the default sort flags +that enable sorting by time. + +For example, + +```bash +# Always sort the commits by time reversed +$ git config --global fixup.additionalSortFlags '-r' +``` + ## Tab completion Tab completion for zsh/fish is implemented. The suggestions for the tab completion @@ -239,9 +243,6 @@ The following example is a fragment of a git config that makes `git fixup --prompt 'Select commit: ' ``` -If you want to use fzf's preview when showing the time, replace the `{+1}` with -a `{+4}` in the snippet above. - ## The default menu If you have not configured an external menu, the default menu is used. See the diff --git a/git-fixup b/git-fixup index 486ff93..842ad09 100755 --- a/git-fixup +++ b/git-fixup @@ -18,9 +18,7 @@ no-rebase Don't do a rebase after commit n,no-verify Bypass the pre-commit and commit-msg hooks b,base=rev Use as base of the revision range for the search A,all Show all candidates -S,sort Sort commits by time, newest first r,reverse Reverse the sort -t,with-time Show the time of the commit " # shellcheck disable=SC2034 SUBDIRECTORY_OK=yes @@ -72,11 +70,7 @@ print_sha () { local sha=$1 local type=$2 - if [[ "$sort_by_time" = "true" || "$show_time" = "true" ]]; then - git --no-pager log --format="%ai %H [$type] %s <%ae>" -n 1 "$sha" - else - git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha" - fi + git --no-pager log --format="%H %ai [$type] %s <%ae>" -n 1 "$sha" } # Call git commit @@ -171,20 +165,9 @@ show_menu () { fi } -cut_time() { - awk '{print $4" "$5" "$6" "$7}' -} - sort_commits () { - if [ "$sort_by_time" = "true" ]; then - if [ "show_time" = "true"]; then - sort -k1 $sort_flags - else - sort -k1 $sort_flags | cut_time - fi - else - awk '{print $0}' - fi + # shellcheck disable=SC2086 + sort $sort_flags $additional_sort_flags } git_commit_args=() @@ -195,10 +178,8 @@ fixup_menu=${GITFIXUPMENU:-$(git config --default="" fixup.menu)} create_commit=${GITFIXUPCOMMIT:-$(git config --default=false --type bool fixup.commit)} base=${GITFIXUPBASE:-$(git config --default="" fixup.base)} show_all=false -sort_by_time=false -sort_flags="" -show_time=false - +sort_flags="-k2 -k3 -k4" # default flags to sort by time (eg 2025-01-03 10:04:43 +0100, hence 3 fields) +additional_sort_flags=${GITFIXUPADDITIONALSORTFLAGS:-$(git config --default="" fixup.additionalSortFlags)} while test $# -gt 0; do case "$1" in -s|--squash) @@ -235,14 +216,8 @@ while test $# -gt 0; do -A|--all) show_all=true ;; - -S|--sort) - sort_by_time=true - ;; -r|--reverse) - sort_flags="-r" - ;; - -t|--with-time) - show_time=true + additional_sort_flags="-r" ;; --) shift @@ -303,9 +278,6 @@ if test "$create_commit" = "true"; then if test -z "$target"; then exit fi - if [ "$show_time" = "true" ]; then - target=$(echo $target | cut_time) - fi call_commit "${target%% *}" if test "$rebase" = "true"; then call_rebase "${target%% *}" From 09e211150c88a21fd97a9086fa123a81ff4e6c6e Mon Sep 17 00:00:00 2001 From: Martin Imre Date: Sun, 5 Jan 2025 13:47:38 +0100 Subject: [PATCH 4/4] feat: Use short hash instead of long hash per default This is mainly to reduce the overcrowding of the output due to the time being added in the previous commit. --- git-fixup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-fixup b/git-fixup index 842ad09..f1a90cb 100755 --- a/git-fixup +++ b/git-fixup @@ -70,7 +70,7 @@ print_sha () { local sha=$1 local type=$2 - git --no-pager log --format="%H %ai [$type] %s <%ae>" -n 1 "$sha" + git --no-pager log --format="%h %ai [$type] %s <%ae>" -n 1 "$sha" } # Call git commit