From: René Scharfe Date: Mon, 6 Oct 2025 17:22:38 +0000 (+0200) Subject: add-patch: let options k and K roll over like j and J X-Git-Tag: v2.52.0-rc0~48^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1967b60681256ed452ed70dedf381b5380697901;p=thirdparty%2Fgit.git add-patch: let options k and K roll over like j and J 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 Signed-off-by: Junio C Hamano --- diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc index 596cdeff93..3116a2cac5 100644 --- a/Documentation/git-add.adoc +++ b/Documentation/git-add.adoc @@ -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 diff --git a/add-patch.c b/add-patch.c index 106bfcb275..4f314c16ec 100644 --- a/add-patch.c +++ b/add-patch.c @@ -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; diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 8086d3da71..385e55c783 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -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.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.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.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.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.trimmed && @@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' ' cat >expect <<-EOF && +15 20 - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? PAGER @@ -1,2 +1,3 @@ + (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? PAGER @@ -1,2 +1,3 @@ PAGER 10 PAGER +15 PAGER 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 | ( @@ -802,7 +802,7 @@ test_expect_success 'colors can be overridden' ' -old +new more-context - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? @@ -3 +3,2 @@ + (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,?]? @@ -3 +3,2 @@ more-context +another-one (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]? @@ -1,3 +1,3 @@ @@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' ' -old +new more-context - (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_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 K q | git add -p >out && + test_write_lines 1 2 1 2 >expect && sed -n -e "s-/.*--" -e "s/^(//p" 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 k q | git add -p >out && + test_write_lines 1 3 1 3 1 3 1 3 1 2 >expect && sed -n -e "s-/.*--" -e "s/^(//p" 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" actual && test_cmp expect actual '