]> git.ipfire.org Git - thirdparty/git.git/commitdiff
add-patch: let options k and K roll over like j and J
authorRené Scharfe <l.s.r@web.de>
Mon, 6 Oct 2025 17:22:38 +0000 (19:22 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 6 Oct 2025 17:51:42 +0000 (10:51 -0700)
Options j and J roll over at the bottom and go to the first undecided
hunk and hunk 1, respectively.  Let options k and K do the same when
they reach the top of the hunk array, so let them go to the last
undecided hunk and the last hunk, respectively, for consistency.  Also
use the same direction-neutral error messages.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-add.adoc
add-patch.c
t/t3701-add-interactive.sh

index 596cdeff93de8b7b8f3d65b05338a4615465947b..3116a2cac548d9b1f85bdb6252fb8a31aa5777c3 100644 (file)
@@ -344,8 +344,8 @@ patch::
        / - search for a hunk matching the given regex
        j - go to the next undecided hunk, roll over at the bottom
        J - go to the next hunk, roll over at the bottom
-       k - go to the previous undecided hunk
-       K - go to the previous hunk
+       k - go to the previous undecided hunk, roll over at the top
+       K - go to the previous hunk, roll over at the top
        s - split the current hunk into smaller hunks
        e - manually edit the current hunk
        p - print the current hunk
index 106bfcb275377b93ec9f26d0038c4c0bdf1c161c..4f314c16ec824f72ed61a4d0c85c172faeb226e6 100644 (file)
@@ -1399,8 +1399,8 @@ static size_t display_hunks(struct add_p_state *s,
 static const char help_patch_remainder[] =
 N_("j - go to the next undecided hunk, roll over at the bottom\n"
    "J - go to the next hunk, roll over at the bottom\n"
-   "k - go to the previous undecided hunk\n"
-   "K - go to the previous hunk\n"
+   "k - go to the previous undecided hunk, roll over at the top\n"
+   "K - go to the previous hunk, roll over at the top\n"
    "g - select a hunk to go to\n"
    "/ - search for a hunk matching the given regex\n"
    "s - split the current hunk into smaller hunks\n"
@@ -1408,6 +1408,11 @@ N_("j - go to the next undecided hunk, roll over at the bottom\n"
    "p - print the current hunk, 'P' to use the pager\n"
    "? - print help\n");
 
+static size_t dec_mod(size_t a, size_t m)
+{
+       return a > 0 ? a - 1 : m - 1;
+}
+
 static size_t inc_mod(size_t a, size_t m)
 {
        return a < m - 1 ? a + 1 : 0;
@@ -1450,7 +1455,9 @@ static int patch_update_file(struct add_p_state *s,
                undecided_next = -1;
 
                if (file_diff->hunk_nr) {
-                       for (i = hunk_index - 1; i >= 0; i--)
+                       for (i = dec_mod(hunk_index, file_diff->hunk_nr);
+                            i != hunk_index;
+                            i = dec_mod(i, file_diff->hunk_nr))
                                if (file_diff->hunk[i].use == UNDECIDED_HUNK) {
                                        undecided_previous = i;
                                        break;
@@ -1492,7 +1499,7 @@ static int patch_update_file(struct add_p_state *s,
                                permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK;
                                strbuf_addstr(&s->buf, ",k");
                        }
-                       if (hunk_index) {
+                       if (file_diff->hunk_nr > 1) {
                                permitted |= ALLOW_GOTO_PREVIOUS_HUNK;
                                strbuf_addstr(&s->buf, ",K");
                        }
@@ -1584,9 +1591,10 @@ soft_increment:
                        }
                } else if (s->answer.buf[0] == 'K') {
                        if (permitted & ALLOW_GOTO_PREVIOUS_HUNK)
-                               hunk_index--;
+                               hunk_index = dec_mod(hunk_index,
+                                                    file_diff->hunk_nr);
                        else
-                               err(s, _("No previous hunk"));
+                               err(s, _("No other hunk"));
                } else if (s->answer.buf[0] == 'J') {
                        if (permitted & ALLOW_GOTO_NEXT_HUNK)
                                hunk_index++;
@@ -1596,7 +1604,7 @@ soft_increment:
                        if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK)
                                hunk_index = undecided_previous;
                        else
-                               err(s, _("No previous hunk"));
+                               err(s, _("No other undecided hunk"));
                } else if (s->answer.buf[0] == 'j') {
                        if (permitted & ALLOW_GOTO_NEXT_UNDECIDED_HUNK)
                                hunk_index = undecided_next;
index 8086d3da71405d449e1702f6210e29e837b3c555..385e55c783a164b6ad5d24d40615f0baf5d9192f 100755 (executable)
@@ -333,7 +333,7 @@ test_expect_success 'different prompts for mode change/deleted' '
        sed -n "s/^\(([0-9/]*) Stage .*?\).*/\1/p" actual >actual.filtered &&
        cat >expect <<-\EOF &&
        (1/1) Stage deletion [y,n,q,a,d,p,?]?
-       (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,p,?]?
+       (1/2) Stage mode change [y,n,q,a,d,k,K,j,J,g,/,p,?]?
        (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]?
        EOF
        test_cmp expect actual.filtered
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
        _10
        +15
        _20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]?_
        EOF
        test_write_lines s y g 1 | git add -p >actual &&
        tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
        _10
        +15
        _20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]?_
        EOF
        test_write_lines s y g1 | git add -p >actual &&
        tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
        _10
        +15
        _20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]?_
        EOF
        test_write_lines s y /1,2 | git add -p >actual &&
        tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
        _10
        +15
        _20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]?_
        EOF
        test_write_lines s y / 1,2 | git add -p >actual &&
        tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
        tr _ " " >expect <<-EOF &&
        +15
         20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? @@ -1,2 +1,3 @@
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? @@ -1,2 +1,3 @@
         10
        +15
         20
-       (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_
+       (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]?_
        EOF
        test_write_lines s y g 1 p | git add -p >actual &&
        tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
        cat >expect <<-EOF &&
        <GREEN>+<RESET><GREEN>15<RESET>
         20<RESET>
-       <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+       <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
        PAGER  10<RESET>
        PAGER <GREEN>+<RESET><GREEN>15<RESET>
        PAGER  20<RESET>
-       <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET>
+       <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? <RESET>
        EOF
        test_write_lines s y g 1 P |
        (
@@ -802,7 +802,7 @@ test_expect_success 'colors can be overridden' '
        <BOLD>-old<RESET>
        <BLUE>+<RESET><BLUE>new<RESET>
        <CYAN> more-context<RESET>
-       <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET><MAGENTA>@@ -3 +3,2 @@<RESET>
+       <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? <RESET><MAGENTA>@@ -3 +3,2 @@<RESET>
        <CYAN> more-context<RESET>
        <BLUE>+<RESET><BLUE>another-one<RESET>
        <YELLOW>(2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]? <RESET><MAGENTA>@@ -1,3 +1,3 @@<RESET>
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
        <BOLD>-old<RESET>
        <BLUE>+new<RESET>
        <CYAN> more-context<RESET>
-       <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET>
+       <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? <RESET>
        EOF
        test_cmp expect actual
 '
@@ -1354,34 +1354,34 @@ do
        '
 done
 
-test_expect_success 'option J rolls over' '
+test_expect_success 'options J, K roll over' '
        test_write_lines a b c d e f g h i >file &&
        git add file &&
        test_write_lines X b c d e f g h X >file &&
-       test_write_lines J J q | git add -p >out &&
-       test_write_lines 1 2 1 >expect &&
+       test_write_lines J J q | git add -p >out &&
+       test_write_lines 1 2 1 >expect &&
        sed -n -e "s-/.*--" -e "s/^(//p" <out >actual &&
        test_cmp expect actual
 '
 
-test_expect_success 'options y, n, j, e roll over to next undecided (1)' '
+test_expect_success 'options y, n, j, k, e roll over to next undecided (1)' '
        test_write_lines a b c d e f g h i j k l m n o p q >file &&
        git add file &&
        test_write_lines X b c d e f g h X j k l m n o p X >file &&
        test_set_editor : &&
-       test_write_lines g3 y g3 n g3 j g3 e q | git add -p >out &&
-       test_write_lines 1  3 1  3 1  3 1  3 1 >expect &&
+       test_write_lines g3 y g3 n g3 j g3 e q | git add -p >out &&
+       test_write_lines 1  3 1  3 1  3 1  3 1 >expect &&
        sed -n -e "s-/.*--" -e "s/^(//p" <out >actual &&
        test_cmp expect actual
 '
 
-test_expect_success 'options y, n, j, e roll over to next undecided (2)' '
+test_expect_success 'options y, n, j, k, e roll over to next undecided (2)' '
        test_write_lines a b c d e f g h i j k l m n o p q >file &&
        git add file &&
        test_write_lines X b c d e f g h X j k l m n o p X >file &&
        test_set_editor : &&
-       test_write_lines y g3 y g3 n g3 j g3 e q | git add -p >out &&
-       test_write_lines 1 2  3 2  3 2  3 2  3 2 >expect &&
+       test_write_lines y g3 y g3 n g3 j g3 e g1 k q | git add -p >out &&
+       test_write_lines 1 2  3 2  3 2  3 2  3 2  1 2 >expect &&
        sed -n -e "s-/.*--" -e "s/^(//p" <out >actual &&
        test_cmp expect actual
 '