add-patch: document that option J rolls over
The variable "permitted" is not reset after moving to a different hunk, so it only accumulates permission and doesn't necessarily reflect those of the current hunk. This may be a bug, but is actually useful with the option J, which can be used at the last hunk to roll over to the first hunk. Make this particular behavior official. Also adjust the error message, as it will only be shown if there's just a single hunk. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Oct 6, 2025 at 19:20 UTC
c309b65a7c8a0dc8a1566ac3587d37d935632e4d
3 files changed
+18
-8
Documentation/git-add.adoc
+1
-1
@@ -343,7 +343,7 @@ patch::
343
g - select a hunk to go to
344
/ - search for a hunk matching the given regex
345
j - go to the next undecided hunk
346
- J - go to the next hunk
346
+ J - go to the next hunk, roll over at the bottom
347
k - go to the previous undecided hunk
348
K - go to the previous hunk
349
s - split the current hunk into smaller hunks
add-patch.c
+3
-3
@@ -1398,7 +1398,7 @@ static size_t display_hunks(struct add_p_state *s,
1398
1399
static const char help_patch_remainder[] =
1400
N_("j - go to the next undecided hunk\n"
1401
- "J - go to the next hunk\n"
1401
+ "J - go to the next hunk, roll over at the bottom\n"
1402
"k - go to the previous undecided hunk\n"
1403
"K - go to the previous hunk\n"
1404
"g - select a hunk to go to\n"
@@ -1493,7 +1493,7 @@ static int patch_update_file(struct add_p_state *s,
1493
permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK;
1494
strbuf_addstr(&s->buf, ",j");
1495
}
1496
- if (hunk_index + 1 < file_diff->hunk_nr) {
1496
+ if (file_diff->hunk_nr > 1) {
1497
permitted |= ALLOW_GOTO_NEXT_HUNK;
1498
strbuf_addstr(&s->buf, ",J");
1499
}
@@ -1584,7 +1584,7 @@ soft_increment:
1584
if (permitted & ALLOW_GOTO_NEXT_HUNK)
1585
hunk_index++;
1586
else
1587
- err(s, _("No next hunk"));
1587
+ err(s, _("No other hunk"));
1588
} else if (s->answer.buf[0] == 'k') {
1589
if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK)
1590
hunk_index = undecided_previous;
t/t3701-add-interactive.sh
+14
-4
@@ -334,7 +334,7 @@ test_expect_success 'different prompts for mode change/deleted' '
334
cat >expect <<-\EOF &&
335
(1/1) Stage deletion [y,n,q,a,d,p,?]?
336
(1/2) Stage mode change [y,n,q,a,d,j,J,g,/,p,?]?
337
- (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]?
337
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]?
338
EOF
339
test_cmp expect actual.filtered
340
'
@@ -521,7 +521,7 @@ test_expect_success 'split hunk setup' '
521
test_expect_success 'goto hunk 1 with "g 1"' '
522
test_when_finished "git reset" &&
523
tr _ " " >expect <<-EOF &&
524
- (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? + 1: -1,2 +1,3 +15
524
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]? + 1: -1,2 +1,3 +15
525
_ 2: -2,4 +3,8 +21
526
go to which hunk? @@ -1,2 +1,3 @@
527
_10
@@ -550,7 +550,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
550
test_expect_success 'navigate to hunk via regex /pattern' '
551
test_when_finished "git reset" &&
552
tr _ " " >expect <<-EOF &&
553
- (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? @@ -1,2 +1,3 @@
553
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]? @@ -1,2 +1,3 @@
554
_10
555
+15
556
_20
@@ -805,7 +805,7 @@ test_expect_success 'colors can be overridden' '
805
<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? <RESET><MAGENTA>@@ -3 +3,2 @@<RESET>
806
<CYAN> more-context<RESET>
807
<BLUE>+<RESET><BLUE>another-one<RESET>
808
- <YELLOW>(2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? <RESET><MAGENTA>@@ -1,3 +1,3 @@<RESET>
808
+ <YELLOW>(2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,?]? <RESET><MAGENTA>@@ -1,3 +1,3 @@<RESET>
809
<CYAN> context<RESET>
810
<BOLD>-old<RESET>
811
<BLUE>+new<RESET>
@@ -1354,4 +1354,14 @@ do
1354
'
1355
done
1356
1357
+test_expect_success 'option J rolls over' '
1358
+ test_write_lines a b c d e f g h i >file &&
1359
+ git add file &&
1360
+ test_write_lines X b c d e f g h X >file &&
1361
+ test_write_lines J J q | git add -p >out &&
1362
+ test_write_lines 1 2 1 >expect &&
1363
+ sed -n -e "s-/.*--" -e "s/^(//p" <out >actual &&
1364
+ test_cmp expect actual
1365
+'
1366
+
1367
test_done