{"thread":{"id":"64557","subject":"[PATCH] add -p: show hunk selection state when selecting hunks","startedAt":"2025-11-30T15:06:06Z","lastAt":"2026-01-11T11:04:11Z","messageCount":25,"participants":["Abraham Samuel Adekunle","Junio C Hamano","Samuel Abraham","SZEDER Gábor","Kristoffer Haugsbakk","Phillip Wood","Ben Knoble"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"531470","messageId":"aSxQhqwzT34hIjV8@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":null,"subject":"[PATCH] add -p: show hunk selection state when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2025-11-30T15:06:15Z","receivedAt":"2025-11-30T15:06:06Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When selecting hunks to stage or not to stage, there is no way to know\nif a hunk has been selected or not when navigating through the previous\nand next hunks using K/J respectively.\n\nImprove the UI to show whether a particular hunk has been selected\nor deselected to improve clarity and aid the navigation process.\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\n add-patch.c | 16 ++++++++++++++--\n 1 file changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..e70e390506 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {\n \t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n \t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n \t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?] %s? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -1564,7 +1564,19 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n-\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n+\t\tif (prompt_mode_type == PROMPT_HUNK) {\n+\t\t\tconst char *state = \"\";\n+\t\t\tif (file_diff->hunk_nr) {\n+\t\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\t\tstate = _(\"[selected]\");\n+\t\t\t\telse if (hunk->use == SKIP_HUNK)\n+\t\t\t\t\tstate = _(\"[deselected]\");\n+\t\t\t}\n+\t\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n+\t\t\t\ts->buf.buf, state);\n+\t\t}\n+\t\telse\n+\t\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n \t\t       s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"531473","messageId":"xmqqqztfbcbr.fsf@gitster.g","threadId":"64557","inReplyTo":"aSxQhqwzT34hIjV8@Adekunles-MacBook-Air.local","subject":"Re: [PATCH] add -p: show hunk selection state when selecting hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-30T18:32:56Z","receivedAt":"2025-11-30T18:32:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n\n> diff --git a/add-patch.c b/add-patch.c\n> index 173a53241e..e70e390506 100644\n> --- a/add-patch.c\n> +++ b/add-patch.c\n> @@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {\n>  \t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n>  \t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n>  \t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n> -\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n> +\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?] %s? \")\n>  \t},\n\nThree comments:\n\n * These sets of prompts exist for each front-end that uses the\n   interactive patch machinery, and we are looking at the set used\n   by \"git add -p\".  But the \"I came back here with K, or I do not\n   remember which between k and K I came back here with, and I\n   cannot easily tell if the hunk I am looking at is already\n   selected\" issue is shared with other users like \"git reset -p\".\n\n * \"chmod +x Makefile && echo >>Makefile && git add -p\" would ask if\n   you want to stage the mode change of the path and content change\n   for the path separately.  You may skip, and later come back with\n   K to this question.  The same \"hmph, have I selected to use\n   this?\" issue exists, no?\n\n * The existing \"[choices]? \" was designed to be at the very end of\n   the question, so that the answer given by the user will come\n   immediately after the offered choices.  Adding an overly long\n   \"selected\" or \"deselected\" to make it \"[choices] selected?\" does\n   not give us a pleasant end-user experience.\n\nAlso, after you decided on one hunk when you have two hunks, typing\n'j' or 'k' would tell you \"No other undecided hunk\".  The phrase\nused here, \"undecided\", refers to the choice between USE or SKIP.\nTo convey the intent clearly, \"Select\"/\"Deselect\" feels a rather\nindirect way (i.e. \"selected for use\" vs \"selected to skip\") to say\nwhat is happening.\n\nIdeally, if we can convey\n\n    Stage this mode change (you previously decided to use it) [y,n,q,a,d%s,?]?\n    Stage this mode change (you previously decided to skip it) [y,n,q,a,d%s,?]?\n    Stage this deletion (you previously decided to use it) [y,n,q,a,d%sm,?]?\n    ...\n\nwithout wasting too many extra display width, that would be great,\nbut this patch is not quite there, I am afraid to say.\n\n> @@ -1564,7 +1564,19 @@ static int patch_update_file(struct add_p_state *s,\n>  \t\t\t      (uintmax_t)(file_diff->hunk_nr\n>  \t\t\t\t\t\t? file_diff->hunk_nr\n>  \t\t\t\t\t\t: 1));\n> -\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n> +\t\tif (prompt_mode_type == PROMPT_HUNK) {\n> +\t\t\tconst char *state = \"\";\n> +\t\t\tif (file_diff->hunk_nr) {\n> +\t\t\t\tif (hunk->use == USE_HUNK)\n> +\t\t\t\t\tstate = _(\"[selected]\");\n> +\t\t\t\telse if (hunk->use == SKIP_HUNK)\n> +\t\t\t\t\tstate = _(\"[deselected]\");\n> +\t\t\t}\n> +\t\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n> +\t\t\t\ts->buf.buf, state);\n> +\t\t}\n> +\t\telse\n> +\t\t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n>  \t\t       s->buf.buf);\n>  \t\tif (*s->s.reset_color_interactive)\n>  \t\t\tfputs(s->s.reset_color_interactive, stdout);\n"},{"id":"531495","messageId":"aS1nhwhZ6tZ3w9RT@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"xmqqqztfbcbr.fsf@gitster.g","subject":"Re: [PATCH] add -p: show hunk selection state when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2025-12-01T10:01:43Z","receivedAt":"2025-12-01T10:01:37Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Sun, Nov 30, 2025 at 10:32:56AM -0800, Junio C Hamano wrote:\n> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n> \n> > diff --git a/add-patch.c b/add-patch.c\n> > index 173a53241e..e70e390506 100644\n> > --- a/add-patch.c\n> > +++ b/add-patch.c\n> > @@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {\n> >  \t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n> >  \t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n> >  \t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n> > -\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n> > +\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?] %s? \")\n> >  \t},\n> \n> Three comments:\n> \n>  * These sets of prompts exist for each front-end that uses the\n>    interactive patch machinery, and we are looking at the set used\n>    by \"git add -p\".  But the \"I came back here with K, or I do not\n>    remember which between k and K I came back here with, and I\n>    cannot easily tell if the hunk I am looking at is already\n>    selected\" issue is shared with other users like \"git reset -p\".\n\nHello Junio,\nThank you for your review.\n\nOkay, are you suggesting I apply the tweak in all prompt_mode arrays\nused by other front-ends. I can see all the others modes (patch_mode_*)\nshown in the file.\n\n> \n>  * \"chmod +x Makefile && echo >>Makefile && git add -p\" would ask if\n>    you want to stage the mode change of the path and content change\n>    for the path separately.  You may skip, and later come back with\n>    K to this question.  The same \"hmph, have I selected to use\n>    this?\" issue exists, no?\n\nYes true, the issue does exist.\nI will fix the change for the others\n> \n>  * The existing \"[choices]? \" was designed to be at the very end of\n>    the question, so that the answer given by the user will come\n>    immediately after the offered choices.  Adding an overly long\n>    \"selected\" or \"deselected\" to make it \"[choices] selected?\" does\n>    not give us a pleasant end-user experience.\n\nOkay.\n\n> \n> Also, after you decided on one hunk when you have two hunks, typing\n> 'j' or 'k' would tell you \"No other undecided hunk\".  The phrase\n> used here, \"undecided\", refers to the choice between USE or SKIP.\n> To convey the intent clearly, \"Select\"/\"Deselect\" feels a rather\n> indirect way (i.e. \"selected for use\" vs \"selected to skip\") to say\n> what is happening.\n> \n> Ideally, if we can convey\n> \n>     Stage this mode change (you previously decided to use it) [y,n,q,a,d%s,?]?\n>     Stage this mode change (you previously decided to skip it) [y,n,q,a,d%s,?]?\n>     Stage this deletion (you previously decided to use it) [y,n,q,a,d%sm,?]?\n>     ...\n> \n> without wasting too many extra display width, that would be great,\n\nOkay this makes sense. But since the display width is something to watch out for,\nwould something like below siffice?\n\n\tStage this mode change (previous decision: stage) [y,n,q,a,d%s,?]?\n\tStage this mode change (previous decision: skip) [y,n,q,a,d%s,?]?\n\tStage this deletion (previous decision: stage) [y,n,q,a,d%s,?]?\n\n> but this patch is not quite there, I am afraid to say.\n\nThank you Junio, I will work towards getting it there.\n[...]\n\nAbraham\n"},{"id":"532883","messageId":"aVbgkySezz8YV6sN@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aSxQhqwzT34hIjV8@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-01T21:04:08Z","receivedAt":"2026-01-01T21:04:01Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity when and aid the navigation process for the\nuser.\n\nReported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\nChanges in v2:\n--------------\n- Modified subject to indicate GSoC participation and user's hunk decision.\n- Modified the code to detect the user's decision for each front-end set\n  that uses the interactive patch machinery\n- Changes the decision phrase to 'previous decision: _decision_' from\n  'Selected/Deselected'\n- Placed the decision phrase before the [choices] instead of after the [choices].\n add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------\n 1 file changed, 47 insertions(+), 37 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..bc7a340d21 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,\n \tssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;\n \tstruct hunk *hunk;\n \tchar ch;\n+\tconst char *hunk_use_decision;\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint colored = !!s->colored.len, quit = 0, use_pager = 0;\n \tenum prompt_mode_type prompt_mode_type;\n@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (file_diff->hunk_nr) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n+\t\t\telse if (hunk->use == SKIP_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = \" \";\n+\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"532891","messageId":"xmqqpl7tc5a9.fsf@gitster.g","threadId":"64557","inReplyTo":"aVbgkySezz8YV6sN@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-01T22:54:54Z","receivedAt":"2026-01-01T22:54:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n\n> When a user is interactively deciding which hunks to use or skip for\n> staging, unstaging, stashing etc, there is no way to know the\n> decision previously chosen for a hunk when navigating through the\n> previous and next hunks using K/J respectively.\n>\n> Improve the UI to explicitly show if a user has previously decided to\n> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> This will improve clarity when and aid the navigation process for the\n> user.\n>\n> Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> ---\n> Changes in v2:\n> --------------\n> - Modified subject to indicate GSoC participation and user's hunk decision.\n> - Modified the code to detect the user's decision for each front-end set\n>   that uses the interactive patch machinery\n> - Changes the decision phrase to 'previous decision: _decision_' from\n>   'Selected/Deselected'\n> - Placed the decision phrase before the [choices] instead of after the [choices].\n>  add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------\n>  1 file changed, 47 insertions(+), 37 deletions(-)\n\nDoesn't this break t3701?\n"},{"id":"532901","messageId":"CADYq+fZX4sQswQZ2dHe1MZTC0BgyEG8+OUzVDgbNhoPa=MoTiw@mail.gmail.com","threadId":"64557","inReplyTo":"xmqqpl7tc5a9.fsf@gitster.g","subject":"Re: [GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-02T07:20:37Z","receivedAt":"2026-01-02T07:20:36Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Thu, Jan 1, 2026 at 11:54 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n>\n> > When a user is interactively deciding which hunks to use or skip for\n> > staging, unstaging, stashing etc, there is no way to know the\n> > decision previously chosen for a hunk when navigating through the\n> > previous and next hunks using K/J respectively.\n> >\n> > Improve the UI to explicitly show if a user has previously decided to\n> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > This will improve clarity when and aid the navigation process for the\n> > user.\n> >\n> > Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\n> > Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> > ---\n> > Changes in v2:\n> > --------------\n> > - Modified subject to indicate GSoC participation and user's hunk decision.\n> > - Modified the code to detect the user's decision for each front-end set\n> >   that uses the interactive patch machinery\n> > - Changes the decision phrase to 'previous decision: _decision_' from\n> >   'Selected/Deselected'\n> > - Placed the decision phrase before the [choices] instead of after the [choices].\n> >  add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------\n> >  1 file changed, 47 insertions(+), 37 deletions(-)\n>\n> Doesn't this break t3701?\n\nThank you for the review Junio.\nYes it does break t3701.\nI will fix the broken test cases to conform to the new code and send an updated\nversion.\n\nThanks\nAbraham.\n"},{"id":"532924","messageId":"aVgTmYhosEiGG3th@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aVbgkySezz8YV6sN@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-02T18:51:05Z","receivedAt":"2026-01-02T18:51:00Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity when and aid the navigation process for the\nuser.\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\n\nChanges in v2:\n--------------\n- Modified t3701-add-interactive.sh for conform to new changes\n\n add-patch.c                | 84 +++++++++++++++++++++-----------------\n t/t3701-add-interactive.sh | 14 +++----\n 2 files changed, 54 insertions(+), 44 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..bc7a340d21 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,\n \tssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;\n \tstruct hunk *hunk;\n \tchar ch;\n+\tconst char *hunk_use_decision;\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint colored = !!s->colored.len, quit = 0, use_pager = 0;\n \tenum prompt_mode_type prompt_mode_type;\n@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (file_diff->hunk_nr) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n+\t\t\telse if (hunk->use == SKIP_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = \" \";\n+\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 4285314f35..e856683496 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g1 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y /1,2 | git add -p >actual &&\n \ttail -n 5 <actual >actual.trimmed &&\n@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y / 1,2 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n \ttr _ \" \" >expect <<-EOF &&\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n \t 10\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 p | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n \t<BOLD>-old<RESET>\n \t<BLUE>+new<RESET>\n \t<CYAN> more-context<RESET>\n-\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_cmp expect actual\n '\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"532977","messageId":"xmqqzf6tncde.fsf@gitster.g","threadId":"64557","inReplyTo":"aVgTmYhosEiGG3th@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-04T06:03:09Z","receivedAt":"2026-01-04T06:03:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n\n> When a user is interactively deciding which hunks to use or skip for\n> staging, unstaging, stashing etc, there is no way to know the\n> decision previously chosen for a hunk when navigating through the\n> previous and next hunks using K/J respectively.\n>\n> Improve the UI to explicitly show if a user has previously decided to\n> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> This will improve clarity when and aid the navigation process for the\n> user.\n>\n> Reported-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> ---\n>\n> Changes in v2:\n> --------------\n> - Modified t3701-add-interactive.sh for conform to new changes\n\nHere is how \"cd t && sh t3701-add-interactive.sh -i -v\" ends for me.\n\nexpecting success of 3701.50 'print again the hunk (PAGER)':\n        test_when_finished \"git reset\" &&\n        cat >expect <<-EOF &&\n        <GREEN>+<RESET><GREEN>15<RESET>\n         20<RESET>\n        <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n        PAGER  10<RESET>\n        PAGER <GREEN>+<RESET><GREEN>15<RESET>\n        PAGER  20<RESET>\n        <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n        EOF\n        test_write_lines s y g 1 P |\n        (\n                GIT_PAGER=\"sed s/^/PAGER\\ /\" &&\n                export GIT_PAGER &&\n                test_terminal git add -p >actual\n        ) &&\n        tail -n 7 <actual | test_decode_color >actual.trimmed &&\n        test_cmp expect actual.trimmed\n\n--- expect      2026-01-04 06:01:25.931220332 +0000\n+++ actual.trimmed      2026-01-04 06:01:26.079845771 +0000\n@@ -1,7 +1,7 @@\n <GREEN>+<RESET><GREEN>15<RESET>\n  20<RESET>\n-<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n+<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n PAGER  10<RESET>\n PAGER <GREEN>+<RESET><GREEN>15<RESET>\n PAGER  20<RESET>\n-<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\nnot ok 50 - print again the hunk (PAGER)\n#\n#               test_when_finished \"git reset\" &&\n#               cat >expect <<-EOF &&\n#               <GREEN>+<RESET><GREEN>15<RESET>\n#                20<RESET>\n#               <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n#               PAGER  10<RESET>\n#               PAGER <GREEN>+<RESET><GREEN>15<RESET>\n#               PAGER  20<RESET>\n#               <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n#               EOF\n#               test_write_lines s y g 1 P |\n#               (\n#                       GIT_PAGER=\"sed s/^/PAGER\\ /\" &&\n#                       export GIT_PAGER &&\n#                       test_terminal git add -p >actual\n#               ) &&\n#               tail -n 7 <actual | test_decode_color >actual.trimmed &&\n#               test_cmp expect actual.trimmed\n#\n1..50\n"},{"id":"532983","messageId":"CADYq+fZZAwavfi0qDxTMSGuVt41nh7vaKNngv_p93s+cwj++Cw@mail.gmail.com","threadId":"64557","inReplyTo":"xmqqzf6tncde.fsf@gitster.g","subject":"Re: [GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-04T10:36:03Z","receivedAt":"2026-01-04T10:36:02Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Sun, Jan 4, 2026 at 7:03 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n>\n> > When a user is interactively deciding which hunks to use or skip for\n> > staging, unstaging, stashing etc, there is no way to know the\n> > decision previously chosen for a hunk when navigating through the\n> > previous and next hunks using K/J respectively.\n> >\n> > Improve the UI to explicitly show if a user has previously decided to\n> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > This will improve clarity when and aid the navigation process for the\n> > user.\n> >\n> > Reported-by: Junio C Hamano <gitster@pobox.com>\n> > Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> > ---\n> >\n> > Changes in v2:\n> > --------------\n> > - Modified t3701-add-interactive.sh for conform to new changes\n>\n> Here is how \"cd t && sh t3701-add-interactive.sh -i -v\" ends for me.\n>\n> expecting success of 3701.50 'print again the hunk (PAGER)':\n>         test_when_finished \"git reset\" &&\n>         cat >expect <<-EOF &&\n>         <GREEN>+<RESET><GREEN>15<RESET>\n>          20<RESET>\n>         <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n>         PAGER  10<RESET>\n>         PAGER <GREEN>+<RESET><GREEN>15<RESET>\n>         PAGER  20<RESET>\n>         <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n>         EOF\n>         test_write_lines s y g 1 P |\n>         (\n>                 GIT_PAGER=\"sed s/^/PAGER\\ /\" &&\n>                 export GIT_PAGER &&\n>                 test_terminal git add -p >actual\n>         ) &&\n>         tail -n 7 <actual | test_decode_color >actual.trimmed &&\n>         test_cmp expect actual.trimmed\n>\n> --- expect      2026-01-04 06:01:25.931220332 +0000\n> +++ actual.trimmed      2026-01-04 06:01:26.079845771 +0000\n> @@ -1,7 +1,7 @@\n>  <GREEN>+<RESET><GREEN>15<RESET>\n>   20<RESET>\n> -<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n> +<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n>  PAGER  10<RESET>\n>  PAGER <GREEN>+<RESET><GREEN>15<RESET>\n>  PAGER  20<RESET>\n> -<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n> +<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n> not ok 50 - print again the hunk (PAGER)\n> #\n> #               test_when_finished \"git reset\" &&\n> #               cat >expect <<-EOF &&\n> #               <GREEN>+<RESET><GREEN>15<RESET>\n> #                20<RESET>\n> #               <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n> #               PAGER  10<RESET>\n> #               PAGER <GREEN>+<RESET><GREEN>15<RESET>\n> #               PAGER  20<RESET>\n> #               <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n> #               EOF\n> #               test_write_lines s y g 1 P |\n> #               (\n> #                       GIT_PAGER=\"sed s/^/PAGER\\ /\" &&\n> #                       export GIT_PAGER &&\n> #                       test_terminal git add -p >actual\n> #               ) &&\n> #               tail -n 7 <actual | test_decode_color >actual.trimmed &&\n> #               test_cmp expect actual.trimmed\n> #\n> 1..50\n\nThank you Junio for the reviews.\nI get the output when I run \"cd t && ./t3701-add-interactive.sh -i -v\"\n\n[...]\nok 49 - print again the hunk\nchecking prerequisite: TTY\nmkdir -p \"$TRASH_DIRECTORY/prereq-test-dir-TTY\" &&\n(\ncd \"$TRASH_DIRECTORY/prereq-test-dir-TTY\" &&\ntest_have_prereq PERL &&\n# Reading from the pty master seems to get stuck _sometimes_\n# on Mac OS X 10.5.0, using Perl 5.10.0 or 5.8.9.\n#\n# Reproduction recipe: run\n#\n# i=0\n# while ./test-terminal.perl echo hi $i\n# do\n# : $((i = $i + 1))\n# done\n#\n# After 2000 iterations or so it hangs.\n# https://rt.cpan.org/Ticket/Display.html?id=65692\n#\ntest \"$(uname -s)\" != Darwin &&\nperl \"$TEST_DIRECTORY\"/test-terminal.perl \\\nsh -c \"test -t 1 && test -t 2\"\n)\nprerequisite TTY not satisfied\nok 50 # skip print again the hunk (PAGER) (missing TTY)\nok 51 # skip P handles SIGPIPE when writing to pager (missing TTY)\n\nSo that test skipped on my end because of this `test \"$(uname -s)\" != Darwin &&`\nsince I am working on a MacOS.\n\nI will correct it and send an updated version.\nThanks\n\nAbraham\n"},{"id":"532986","messageId":"aVpI36nPuZAEchuM@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aVgTmYhosEiGG3th@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-04T11:02:55Z","receivedAt":"2026-01-04T11:02:47Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity when and aid the navigation process for the\nuser.\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\nChanges in v4:\n--------------\n- Modified the test case\n  \"expecting success of 3701.50 'print again the hunk (PAGER)'\"\n  which was skipped in v3 due to the test being run on a MacOs\n\n add-patch.c                | 84 +++++++++++++++++++++-----------------\n t/t3701-add-interactive.sh | 18 ++++----\n 2 files changed, 56 insertions(+), 46 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..bc7a340d21 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,\n \tssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;\n \tstruct hunk *hunk;\n \tchar ch;\n+\tconst char *hunk_use_decision;\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint colored = !!s->colored.len, quit = 0, use_pager = 0;\n \tenum prompt_mode_type prompt_mode_type;\n@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (file_diff->hunk_nr) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n+\t\t\telse if (hunk->use == SKIP_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = \" \";\n+\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 4285314f35..cc3986a9d7 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g1 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y /1,2 | git add -p >actual &&\n \ttail -n 5 <actual >actual.trimmed &&\n@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y / 1,2 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n \ttr _ \" \" >expect <<-EOF &&\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n \t 10\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 p | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '\n \tcat >expect <<-EOF &&\n \t<GREEN>+<RESET><GREEN>15<RESET>\n \t 20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n \tPAGER  10<RESET>\n \tPAGER <GREEN>+<RESET><GREEN>15<RESET>\n \tPAGER  20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_write_lines s y g 1 P |\n \t(\n@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n \t<BOLD>-old<RESET>\n \t<BLUE>+new<RESET>\n \t<CYAN> more-context<RESET>\n-\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_cmp expect actual\n '\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"533067","messageId":"aVwShWyoGBq4BcGR@szeder.dev","threadId":"64557","inReplyTo":"aVpI36nPuZAEchuM@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2026-01-05T19:35:33Z","receivedAt":"2026-01-05T19:35:48Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Sun, Jan 04, 2026 at 12:02:55PM +0100, Abraham Samuel Adekunle wrote:\n> diff --git a/add-patch.c b/add-patch.c\n> index 173a53241e..bc7a340d21 100644\n> --- a/add-patch.c\n> +++ b/add-patch.c\n\n> @@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,\n>  \tssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;\n>  \tstruct hunk *hunk;\n>  \tchar ch;\n> +\tconst char *hunk_use_decision;\n\n'hunk_use_decision' is defined here, but is left uninitialized.\n\n>  \tstruct child_process cp = CHILD_PROCESS_INIT;\n>  \tint colored = !!s->colored.len, quit = 0, use_pager = 0;\n>  \tenum prompt_mode_type prompt_mode_type;\n> @@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,\n>  \t\t\t      (uintmax_t)(file_diff->hunk_nr\n>  \t\t\t\t\t\t? file_diff->hunk_nr\n>  \t\t\t\t\t\t: 1));\n> +\t\tif (file_diff->hunk_nr) {\n> +\t\t\tif (hunk->use == USE_HUNK)\n> +\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n> +\t\t\telse if (hunk->use == SKIP_HUNK)\n> +\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n> +\t\t\telse\n> +\t\t\t\thunk_use_decision = \" \";\n\n'hunk_use_decision' is set here, but only if 'file_diff->hunk_nr' is\nnon-zero.\n\n> +`\n> +\t\t}\n\nNit: unnecessary empty line before the closing brace.\n\n>  \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n> -\t\t       s->buf.buf);\n> +\t\t\thunk_use_decision, s->buf.buf);\n\nSo 'hunk_use_decision' is used uninitialized here if\n'file_diff->hunk_nr' is zero.\n\n>  \t\tif (*s->s.reset_color_interactive)\n>  \t\t\tfputs(s->s.reset_color_interactive, stdout);\n>  \t\tfflush(stdout);\n"},{"id":"533082","messageId":"CADYq+fbntOOmcb+7cg_VDt24UzsU0UfBzFPMVxVdtL0sAMrHbg@mail.gmail.com","threadId":"64557","inReplyTo":"aVwShWyoGBq4BcGR@szeder.dev","subject":"Re: [GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-05T21:52:18Z","receivedAt":"2026-01-05T21:52:17Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Mon, Jan 5, 2026 at 8:35 PM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n>\n> On Sun, Jan 04, 2026 at 12:02:55PM +0100, Abraham Samuel Adekunle wrote:\n> > diff --git a/add-patch.c b/add-patch.c\n> > index 173a53241e..bc7a340d21 100644\n> > --- a/add-patch.c\n> > +++ b/add-patch.c\n>\n> > @@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,\n> >       ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;\n> >       struct hunk *hunk;\n> >       char ch;\n> > +     const char *hunk_use_decision;\n>\n> 'hunk_use_decision' is defined here, but is left uninitialized.\n>\n> >       struct child_process cp = CHILD_PROCESS_INIT;\n> >       int colored = !!s->colored.len, quit = 0, use_pager = 0;\n> >       enum prompt_mode_type prompt_mode_type;\n> > @@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,\n> >                             (uintmax_t)(file_diff->hunk_nr\n> >                                               ? file_diff->hunk_nr\n> >                                               : 1));\n> > +             if (file_diff->hunk_nr) {\n> > +                     if (hunk->use == USE_HUNK)\n> > +                             hunk_use_decision = _(\" (previous decision: use) \");\n> > +                     else if (hunk->use == SKIP_HUNK)\n> > +                             hunk_use_decision = _(\" (previous decision: skip) \");\n> > +                     else\n> > +                             hunk_use_decision = \" \";\n>\n> 'hunk_use_decision' is set here, but only if 'file_diff->hunk_nr' is\n> non-zero.\n>\n> > +`\n> > +             }\n>\n> Nit: unnecessary empty line before the closing brace.\n>\n> >               printf(_(s->mode->prompt_mode[prompt_mode_type]),\n> > -                    s->buf.buf);\n> > +                     hunk_use_decision, s->buf.buf);\n>\n> So 'hunk_use_decision' is used uninitialized here if\n> 'file_diff->hunk_nr' is zero.\n>\n\nhello SZEDER,\nThank you very much for the review\nYes, you are right, `hunk_use_decision` is left uninitialized if\n`file_diff->hunk` is zero\nI will fix the patch and send an updated version.\n\nAbraham.\n"},{"id":"533129","messageId":"aVzsltM5imOSvW2G@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aVpI36nPuZAEchuM@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-06T11:05:58Z","receivedAt":"2026-01-06T11:05:50Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity when and aid the navigation process for the\nuser.\n\nReported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\nChanges in v5:\n===============\n- Modified code to handle uninitialized variable `hunk_use_decision`\n  observed by SZEDER Gábor.\n- Removed an unnecessary empty line\n\n add-patch.c                | 81 +++++++++++++++++++++-----------------\n t/t3701-add-interactive.sh | 18 ++++-----\n 2 files changed, 53 insertions(+), 46 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..a383ea7f45 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,\n \trender_diff_header(s, file_diff, colored, &s->buf);\n \tfputs(s->buf.buf, stdout);\n \tfor (;;) {\n+\t\tconst char *hunk_use_decision = \" \";\n \t\tenum {\n \t\t\tALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,\n \t\t\tALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,\n@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 4285314f35..cc3986a9d7 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g1 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y /1,2 | git add -p >actual &&\n \ttail -n 5 <actual >actual.trimmed &&\n@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y / 1,2 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n \ttr _ \" \" >expect <<-EOF &&\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n \t 10\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 p | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '\n \tcat >expect <<-EOF &&\n \t<GREEN>+<RESET><GREEN>15<RESET>\n \t 20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n \tPAGER  10<RESET>\n \tPAGER <GREEN>+<RESET><GREEN>15<RESET>\n \tPAGER  20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_write_lines s y g 1 P |\n \t(\n@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n \t<BOLD>-old<RESET>\n \t<BLUE>+new<RESET>\n \t<CYAN> more-context<RESET>\n-\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_cmp expect actual\n '\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"533130","messageId":"dae478ce-d5ba-4649-a6ab-61be29321131@app.fastmail.com","threadId":"64557","inReplyTo":"aVzsltM5imOSvW2G@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-01-06T11:08:43Z","receivedAt":"2026-01-06T11:09:04Z","isPatch":true,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"On Tue, Jan 6, 2026, at 12:05, Abraham Samuel Adekunle wrote:\n> When a user is interactively deciding which hunks to use or skip for\n> staging, unstaging, stashing etc, there is no way to know the\n> decision previously chosen for a hunk when navigating through the\n> previous and next hunks using K/J respectively.\n>\n> Improve the UI to explicitly show if a user has previously decided to\n> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> This will improve clarity when and aid the navigation process for the\n> user.\n>\n> Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\n\nThis is doubled again like it was in the first version.\n\n> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n>[snip]\n"},{"id":"533135","messageId":"CADYq+fYLoarsgHWZsxBZoijRCdTzYm0VOZ1MFmVX5901akVpYw@mail.gmail.com","threadId":"64557","inReplyTo":"dae478ce-d5ba-4649-a6ab-61be29321131@app.fastmail.com","subject":"Re: [GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-06T11:46:31Z","receivedAt":"2026-01-06T11:46:29Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Tue, Jan 6, 2026 at 12:09 PM Kristoffer Haugsbakk\n<kristofferhaugsbakk@fastmail.com> wrote:\n>\n> On Tue, Jan 6, 2026, at 12:05, Abraham Samuel Adekunle wrote:\n> > When a user is interactively deciding which hunks to use or skip for\n> > staging, unstaging, stashing etc, there is no way to know the\n> > decision previously chosen for a hunk when navigating through the\n> > previous and next hunks using K/J respectively.\n> >\n> > Improve the UI to explicitly show if a user has previously decided to\n> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > This will improve clarity when and aid the navigation process for the\n> > user.\n> >\n> > Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>\n>\n> This is doubled again like it was in the first version.\n\nAh!!\nI'm sorry about this\nI will fix it now.\n\nThanks\nAbraham\n"},{"id":"533139","messageId":"aVz5kf6eLsMZ6WQQ@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aVzsltM5imOSvW2G@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-06T12:01:21Z","receivedAt":"2026-01-06T12:01:18Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity and aid the navigation process for the\nuser.\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\nChanges in v6:\n==============\n- Corrected duplicate Reported-by tag\n\n add-patch.c                | 81 +++++++++++++++++++++-----------------\n t/t3701-add-interactive.sh | 18 ++++-----\n 2 files changed, 53 insertions(+), 46 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..a383ea7f45 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s[y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s[y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,\n \trender_diff_header(s, file_diff, colored, &s->buf);\n \tfputs(s->buf.buf, stdout);\n \tfor (;;) {\n+\t\tconst char *hunk_use_decision = \" \";\n \t\tenum {\n \t\t\tALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,\n \t\t\tALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,\n@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 4285314f35..cc3986a9d7 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g1 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y /1,2 | git add -p >actual &&\n \ttail -n 5 <actual >actual.trimmed &&\n@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y / 1,2 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n \ttr _ \" \" >expect <<-EOF &&\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n \t 10\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 p | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '\n \tcat >expect <<-EOF &&\n \t<GREEN>+<RESET><GREEN>15<RESET>\n \t 20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n \tPAGER  10<RESET>\n \tPAGER <GREEN>+<RESET><GREEN>15<RESET>\n \tPAGER  20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_write_lines s y g 1 P |\n \t(\n@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n \t<BOLD>-old<RESET>\n \t<BLUE>+new<RESET>\n \t<CYAN> more-context<RESET>\n-\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_cmp expect actual\n '\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"533150","messageId":"54e48ac4-7151-4378-b95f-8f22279d6761@gmail.com","threadId":"64557","inReplyTo":"aVz5kf6eLsMZ6WQQ@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-01-06T16:10:24Z","receivedAt":"2026-01-06T16:10:33Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Abraham\n\nOn 06/01/2026 12:01, Abraham Samuel Adekunle wrote:\n> When a user is interactively deciding which hunks to use or skip for\n> staging, unstaging, stashing etc, there is no way to know the\n> decision previously chosen for a hunk when navigating through the\n> previous and next hunks using K/J respectively.\n> \n> Improve the UI to explicitly show if a user has previously decided to\n> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> This will improve clarity and aid the navigation process for the\n> user.\n\nI like the idea of telling the user if the hunk is currently selected \nbut say \"(previous decision: use)\" makes the prompt rather long (some of \nthe prompts in the tests below are 80 characters long). I wonder if we \ncan find a more compact notation. \"(currently selected)\" is a bit \nshorter and takes us under 80 characters but is still longer than I'd \nlike - maybe someone reading this will have a better suggestion.\n\n> diff --git a/add-patch.c b/add-patch.c\n> index 173a53241e..a383ea7f45 100644\n> --- a/add-patch.c\n> +++ b/add-patch.c\n> @@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n>   \t.apply_args = { \"--cached\", NULL },\n>   \t.apply_check_args = { \"--cached\", NULL },\n>   \t.prompt_mode = {\n> -\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n> -\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n> -\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n> -\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n> +\t\tN_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n> +\t\tN_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n> +\t\tN_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n> +\t\tN_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n\nI'd find these strings easier to read if we kept the space and just \npassed an empty string when the hunk is undecided.\n\n> @@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,\n>   \t\t\t      (uintmax_t)(file_diff->hunk_nr\n>   \t\t\t\t\t\t? file_diff->hunk_nr\n>   \t\t\t\t\t\t: 1));\n> +\t\tif (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {\n\nWhy do we need to check hunk_nr here?\n\nThanks\n\nPhillip\n\n> +\t\t\tif (hunk->use == USE_HUNK)\n> +\t\t\t\thunk_use_decision = _(\" (previous decision: use) \");\n> +\t\t\telse\n> +\t\t\t\thunk_use_decision = _(\" (previous decision: skip) \");\n> +\t\t}\n>   \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n> -\t\t       s->buf.buf);\n> +\t\t\thunk_use_decision, s->buf.buf);\n>   \t\tif (*s->s.reset_color_interactive)\n>   \t\t\tfputs(s->s.reset_color_interactive, stdout);\n>   \t\tfflush(stdout);\n> diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\n> index 4285314f35..cc3986a9d7 100755\n> --- a/t/t3701-add-interactive.sh\n> +++ b/t/t3701-add-interactive.sh\n> @@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n>   \t_10\n>   \t+15\n>   \t_20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n>   \tEOF\n>   \ttest_write_lines s y g 1 | git add -p >actual &&\n>   \ttail -n 7 <actual >actual.trimmed &&\n> @@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n>   \t_10\n>   \t+15\n>   \t_20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n>   \tEOF\n>   \ttest_write_lines s y g1 | git add -p >actual &&\n>   \ttail -n 4 <actual >actual.trimmed &&\n> @@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n>   \t_10\n>   \t+15\n>   \t_20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n>   \tEOF\n>   \ttest_write_lines s y /1,2 | git add -p >actual &&\n>   \ttail -n 5 <actual >actual.trimmed &&\n> @@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n>   \t_10\n>   \t+15\n>   \t_20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n>   \tEOF\n>   \ttest_write_lines s y / 1,2 | git add -p >actual &&\n>   \ttail -n 4 <actual >actual.trimmed &&\n> @@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n>   \ttr _ \" \" >expect <<-EOF &&\n>   \t+15\n>   \t 20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n>   \t 10\n>   \t+15\n>   \t 20\n> -\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n> +\t(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n>   \tEOF\n>   \ttest_write_lines s y g 1 p | git add -p >actual &&\n>   \ttail -n 7 <actual >actual.trimmed &&\n> @@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '\n>   \tcat >expect <<-EOF &&\n>   \t<GREEN>+<RESET><GREEN>15<RESET>\n>   \t 20<RESET>\n> -\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n> +\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n>   \tPAGER  10<RESET>\n>   \tPAGER <GREEN>+<RESET><GREEN>15<RESET>\n>   \tPAGER  20<RESET>\n> -\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n> +\t<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n>   \tEOF\n>   \ttest_write_lines s y g 1 P |\n>   \t(\n> @@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n>   \t<BOLD>-old<RESET>\n>   \t<BLUE>+new<RESET>\n>   \t<CYAN> more-context<RESET>\n> -\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n> +\t<YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n>   \tEOF\n>   \ttest_cmp expect actual\n>   '\n\n"},{"id":"533157","messageId":"ADCF604A-A3F1-48B9-B29E-777CE7026EAA@gmail.com","threadId":"64557","inReplyTo":"54e48ac4-7151-4378-b95f-8f22279d6761@gmail.com","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-01-06T19:01:31Z","receivedAt":"2026-01-06T19:01:44Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 6 janv. 2026 à 11:13, Phillip Wood <phillip.wood123@gmail.com> a écrit :\n> \n> ﻿Hi Abraham\n> \n>> On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:\n>> When a user is interactively deciding which hunks to use or skip for\n>> staging, unstaging, stashing etc, there is no way to know the\n>> decision previously chosen for a hunk when navigating through the\n>> previous and next hunks using K/J respectively.\n>> Improve the UI to explicitly show if a user has previously decided to\n>> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n>> This will improve clarity and aid the navigation process for the\n>> user.\n> \n> I like the idea of telling the user if the hunk is currently selected but say \"(previous decision: use)\" makes the prompt rather long (some of the prompts in the tests below are 80 characters long). I wonder if we can find a more compact notation. \"(currently selected)\" is a bit shorter and takes us under 80 characters but is still longer than I'd like - maybe someone reading this will have a better suggestion.\n\nI haven’t looked carefully, so apologies if this is nonsense.\n\nWhat if the marker of current state were on a separate line before the prompt? That would allow more room, right?"},{"id":"533163","messageId":"CADYq+fafH-cwc7Ego1fDdNRgSnrOeGzCz_vCqszajVYEx1FV-w@mail.gmail.com","threadId":"64557","inReplyTo":"54e48ac4-7151-4378-b95f-8f22279d6761@gmail.com","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-06T22:02:28Z","receivedAt":"2026-01-06T22:02:27Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> Hi Abraham\n\nHello Phillip,\n\n>\n> On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:\n> > When a user is interactively deciding which hunks to use or skip for\n> > staging, unstaging, stashing etc, there is no way to know the\n> > decision previously chosen for a hunk when navigating through the\n> > previous and next hunks using K/J respectively.\n> >\n> > Improve the UI to explicitly show if a user has previously decided to\n> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > This will improve clarity and aid the navigation process for the\n> > user.\n>\n> I like the idea of telling the user if the hunk is currently selected\n> but say \"(previous decision: use)\" makes the prompt rather long (some of\n> the prompts in the tests below are 80 characters long). I wonder if we\n> can find a more compact notation. \"(currently selected)\" is a bit\n> shorter and takes us under 80 characters but is still longer than I'd\n> like - maybe someone reading this will have a better suggestion.\n\nThank you for the review\nSo I previously used selected/deselected. But Junio was not okay with those\nchoice of words because they did not clearly tell If the user selected\nto skip or\nor selected to use the hunk.\n\nBut how about\n\nStage this mode change (you chose: use) [y,n,q,a,d%s,?]?\nStage this mode change (you chose: skip) [y,n,q,a,d%s,?]?\nStage this deletion (you chose: use) [y,n,q,a,d%sm,?]?\n\nor\nStage this mode change (choice: use) [y,n,q,a,d%s,?]?\nStage this mode change (choice: skip)[y,n,q,a,d%s,?]?\nStage this deletion (choice: skip)\" [y,n,q,a,d%sm,?]?\n\nor\nStage this mode change (use: yes) [y,n,q,a,d%s,?]?\nStage this mode change (use: no) [y,n,q,a,d%s,?]?\nStage this deletion (use: no) [y,n,q,a,d%sm,?]?\n\nThough I feel the last one does not fully tell what is happening\nat a glance.\nI can wait for more suggestions from other members if these do not\nsuffice.\n\n>\n> > diff --git a/add-patch.c b/add-patch.c\n> > index 173a53241e..a383ea7f45 100644\n> > --- a/add-patch.c\n> > +++ b/add-patch.c\n> > @@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n> >       .apply_args = { \"--cached\", NULL },\n> >       .apply_check_args = { \"--cached\", NULL },\n> >       .prompt_mode = {\n> > -             N_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n> > -             N_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n> > -             N_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n> > -             N_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n> > +             N_(\"Stage mode change%s[y,n,q,a,d%s,?]? \"),\n> > +             N_(\"Stage deletion%s[y,n,q,a,d%s,?]? \"),\n> > +             N_(\"Stage addition%s[y,n,q,a,d%s,?]? \"),\n> > +             N_(\"Stage this hunk%s[y,n,q,a,d%s,?]? \")\n>\n> I'd find these strings easier to read if we kept the space and just\n> passed an empty string when the hunk is undecided.\n\nOkay I understand.\nThank you. I will do that\n\n>\n> > @@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,\n> >                             (uintmax_t)(file_diff->hunk_nr\n> >                                               ? file_diff->hunk_nr\n> >                                               : 1));\n> > +             if (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {\n>\n> Why do we need to check hunk_nr here?\n\nOkay it is actually not necessary to check `hunk_nr` since\n`hunk` is set to `file_diff->head` if `file_diff->hunk_nr` is zero\nThank you for the observation.\n\nAbraham.\n"},{"id":"533164","messageId":"CADYq+fZDyJWzuJ_DZUc0-uEXJnJc-3mjg=xecaRZ+XqOF1zd1w@mail.gmail.com","threadId":"64557","inReplyTo":"CADYq+fafH-cwc7Ego1fDdNRgSnrOeGzCz_vCqszajVYEx1FV-w@mail.gmail.com","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-06T22:19:50Z","receivedAt":"2026-01-06T22:19:51Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Tue, Jan 6, 2026 at 11:02 PM Samuel Abraham\n<abrahamadekunle50@gmail.com> wrote:\n>\n> On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:\n> >\n> > Hi Abraham\n>\n> Hello Phillip,\n>\n> >\n> > On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:\n> > > When a user is interactively deciding which hunks to use or skip for\n> > > staging, unstaging, stashing etc, there is no way to know the\n> > > decision previously chosen for a hunk when navigating through the\n> > > previous and next hunks using K/J respectively.\n> > >\n> > > Improve the UI to explicitly show if a user has previously decided to\n> > > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > > This will improve clarity and aid the navigation process for the\n> > > user.\n> >\n> > I like the idea of telling the user if the hunk is currently selected\n> > but say \"(previous decision: use)\" makes the prompt rather long (some of\n> > the prompts in the tests below are 80 characters long). I wonder if we\n> > can find a more compact notation. \"(currently selected)\" is a bit\n> > shorter and takes us under 80 characters but is still longer than I'd\n> > like - maybe someone reading this will have a better suggestion.\n>\n> Thank you for the review\n> So I previously used selected/deselected. But Junio was not okay with those\n> choice of words because they did not clearly tell If the user selected\n> to skip or\n> or selected to use the hunk.\n>\n> But how about\n>\n> Stage this mode change (you chose: use) [y,n,q,a,d%s,?]?\n> Stage this mode change (you chose: skip) [y,n,q,a,d%s,?]?\n> Stage this deletion (you chose: use) [y,n,q,a,d%sm,?]?\n>\n> or\n> Stage this mode change (choice: use) [y,n,q,a,d%s,?]?\n> Stage this mode change (choice: skip)[y,n,q,a,d%s,?]?\n> Stage this deletion (choice: skip)\" [y,n,q,a,d%sm,?]?\n>\n> or\n> Stage this mode change (use: yes) [y,n,q,a,d%s,?]?\n> Stage this mode change (use: no) [y,n,q,a,d%s,?]?\n> Stage this deletion (use: no) [y,n,q,a,d%sm,?]?\n>\n\nAlso \"(you chose yes)\" i think is an option also.\nStage this mode change (you chose yes) [y,n,q,a,d%s,?]?\nStage this mode change (you chose no) [y,n,q,a,d%s,?]?\nStage this deletion (you chose no) [y,n,q,a,d%sm,?]?\n\nAbraham.\n"},{"id":"533172","messageId":"xmqq7btujn3s.fsf@gitster.g","threadId":"64557","inReplyTo":"ADCF604A-A3F1-48B9-B29E-777CE7026EAA@gmail.com","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-07T00:13:59Z","receivedAt":"2026-01-07T00:14:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ben Knoble <ben.knoble@gmail.com> writes:\n\n>> I like the idea of telling the user if the hunk is currently\n>> selected but say \"(previous decision: use)\" makes the prompt\n>> rather long (some of the prompts in the tests below are 80\n>> characters long). I wonder if we can find a more compact\n>> notation. \"(currently selected)\" is a bit shorter and takes us\n>> under 80 characters but is still longer than I'd like - maybe\n>> someone reading this will have a better suggestion.\n>\n> I haven’t looked carefully, so apologies if this is nonsense.\n>\n> What if the marker of current state were on a separate line before\n> the prompt? That would allow more room, right?\n\nVertical screen real estate is also a limited resource.  Also, while\nit is good if we let users know what the current selection status\nis, I personally do not think the benefit outweighs the downside of\ncluttering the prompt unless it is kept to the minimum.  So I very\nmuch appreciate that Phillip raised this point.\n\nThanks.\n"},{"id":"533187","messageId":"CADYq+fYRbdMOo-bZ9bQ0uVpthNKrxKB-fDama5xN-kukprS01w@mail.gmail.com","threadId":"64557","inReplyTo":"CADYq+fZDyJWzuJ_DZUc0-uEXJnJc-3mjg=xecaRZ+XqOF1zd1w@mail.gmail.com","subject":"Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-07T08:49:57Z","receivedAt":"2026-01-07T08:49:57Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Tue, Jan 6, 2026 at 11:19 PM Samuel Abraham\n<abrahamadekunle50@gmail.com> wrote:\n>\n> On Tue, Jan 6, 2026 at 11:02 PM Samuel Abraham\n> <abrahamadekunle50@gmail.com> wrote:\n> >\n> > On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:\n> > >\n> > > Hi Abraham\n> >\n> > Hello Phillip,\n> >\n> > >\n> > > On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:\n> > > > When a user is interactively deciding which hunks to use or skip for\n> > > > staging, unstaging, stashing etc, there is no way to know the\n> > > > decision previously chosen for a hunk when navigating through the\n> > > > previous and next hunks using K/J respectively.\n> > > >\n> > > > Improve the UI to explicitly show if a user has previously decided to\n> > > > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > > > This will improve clarity and aid the navigation process for the\n> > > > user.\n> > >\n> > > I like the idea of telling the user if the hunk is currently selected\n> > > but say \"(previous decision: use)\" makes the prompt rather long (some of\n> > > the prompts in the tests below are 80 characters long). I wonder if we\n> > > can find a more compact notation. \"(currently selected)\" is a bit\n> > > shorter and takes us under 80 characters but is still longer than I'd\n> > > like - maybe someone reading this will have a better suggestion.\n> >\n> > Thank you for the review\n> > So I previously used selected/deselected. But Junio was not okay with those\n> > choice of words because they did not clearly tell If the user selected\n> > to skip or\n> > or selected to use the hunk.\n> >\n> > But how about\n> >\n> > Stage this mode change (you chose: use) [y,n,q,a,d%s,?]?\n> > Stage this mode change (you chose: skip) [y,n,q,a,d%s,?]?\n> > Stage this deletion (you chose: use) [y,n,q,a,d%sm,?]?\n> >\n> > or\n> > Stage this mode change (choice: use) [y,n,q,a,d%s,?]?\n> > Stage this mode change (choice: skip)[y,n,q,a,d%s,?]?\n> > Stage this deletion (choice: skip)\" [y,n,q,a,d%sm,?]?\n> >\n> > or\n> > Stage this mode change (use: yes) [y,n,q,a,d%s,?]?\n> > Stage this mode change (use: no) [y,n,q,a,d%s,?]?\n> > Stage this deletion (use: no) [y,n,q,a,d%sm,?]?\n> >\n>\n> Also \"(you chose yes)\" i think is an option also.\n> Stage this mode change (you chose yes) [y,n,q,a,d%s,?]?\n> Stage this mode change (you chose no) [y,n,q,a,d%s,?]?\n> Stage this deletion (you chose no) [y,n,q,a,d%sm,?]?\n>\n> Abraham.\n\nI also think \"(was: y)\" or \"(was: n)\" is considerably shorter\nStage this mode change (was: y) [y,n,q,a,d%s,?]?\nStage this mode change (was: n) [y,n,q,a,d%s,?]?\nStage this deletion (was: y) [y,n,q,a,d%sm,?]?\n"},{"id":"533285","messageId":"aV_IGCld5T_dBxTs@Adekunles-MacBook-Air.local","threadId":"64557","inReplyTo":"aVz5kf6eLsMZ6WQQ@Adekunles-MacBook-Air.local","subject":"[GSoC PATCH v7] add -p: show user's hunk decision when selecting hunks","fromName":"Abraham Samuel Adekunle","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-08T15:07:04Z","receivedAt":"2026-01-08T15:06:56Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"When a user is interactively deciding which hunks to use or skip for\nstaging, unstaging, stashing etc, there is no way to know the\ndecision previously chosen for a hunk when navigating through the\nprevious and next hunks using K/J respectively.\n\nImprove the UI to explicitly show if a user has previously decided to\nuse a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\nThis will improve clarity when and aid the navigation process for the\nuser.\n\nReported-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n---\nChanges in v7:\n==============\n- changed hunk selection state message to reduce prompt width\n- Removed redundant `file_diff->hunk_nr` in hunk->use check\n- Made the prompt mode more readable by retaining the space before choices\n- set `hunk_use_decision` to empty string if `hunk->use == UNDECIDED` to match\n  the prompt mode.\n\n add-patch.c                | 81 +++++++++++++++++++++-----------------\n t/t3701-add-interactive.sh | 18 ++++-----\n 2 files changed, 53 insertions(+), 46 deletions(-)\n\ndiff --git a/add-patch.c b/add-patch.c\nindex 173a53241e..df8f2e6d74 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stage this hunk [y,n,q,a,d%s,?]? \")\n+\t\tN_(\"Stage mode change%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage deletion%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage addition%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stage this hunk%s [y,n,q,a,d%s,?]? \")\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for staging.\"),\n@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {\n \t.apply_args = { \"--cached\", NULL },\n \t.apply_check_args = { \"--cached\", NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Stash mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Stash this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash mode change%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash deletion%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash addition%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Stash this hunk%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for stashing.\"),\n@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {\n \t.is_reverse = 1,\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Unstage mode change [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage deletion [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage addition [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Unstage this hunk [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage mode change%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage deletion%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage addition%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Unstage this hunk%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for unstaging.\"),\n@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {\n \t.apply_check_args = { \"--cached\", NULL },\n \t.index_only = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from index and worktree%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {\n \t.apply_for_checkout = 1,\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to index and worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to index and worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to index and worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to index and worktree%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {\n \t.apply_check_args = { \"-R\", NULL },\n \t.is_reverse = 1,\n \t.prompt_mode = {\n-\t\tN_(\"Discard mode change from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard deletion from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard addition from worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Discard this hunk from worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard mode change from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard deletion from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard addition from worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Discard this hunk from worktree%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for discarding.\"),\n@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {\n \t.apply_args = { NULL },\n \t.apply_check_args = { NULL },\n \t.prompt_mode = {\n-\t\tN_(\"Apply mode change to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply deletion to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply addition to worktree [y,n,q,a,d%s,?]? \"),\n-\t\tN_(\"Apply this hunk to worktree [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply mode change to worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply deletion to worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply addition to worktree%s [y,n,q,a,d%s,?]? \"),\n+\t\tN_(\"Apply this hunk to worktree%s [y,n,q,a,d%s,?]? \"),\n \t},\n \t.edit_hunk_hint = N_(\"If the patch applies cleanly, the edited hunk \"\n \t\t\t     \"will immediately be marked for applying.\"),\n@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,\n \trender_diff_header(s, file_diff, colored, &s->buf);\n \tfputs(s->buf.buf, stdout);\n \tfor (;;) {\n+\t\tconst char *hunk_use_decision = \"\";\n \t\tenum {\n \t\t\tALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,\n \t\t\tALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,\n@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,\n \t\t\t      (uintmax_t)(file_diff->hunk_nr\n \t\t\t\t\t\t? file_diff->hunk_nr\n \t\t\t\t\t\t: 1));\n+\t\tif (hunk->use != UNDECIDED_HUNK) {\n+\t\t\tif (hunk->use == USE_HUNK)\n+\t\t\t\thunk_use_decision = _(\" (was: y)\");\n+\t\t\telse\n+\t\t\t\thunk_use_decision = _(\" (was: n)\");\n+\t\t}\n \t\tprintf(_(s->mode->prompt_mode[prompt_mode_type]),\n-\t\t       s->buf.buf);\n+\t\t\thunk_use_decision, s->buf.buf);\n \t\tif (*s->s.reset_color_interactive)\n \t\t\tfputs(s->s.reset_color_interactive, stdout);\n \t\tfflush(stdout);\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 4285314f35..5ce9c6dd60 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with \"g 1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with \"g1\"' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g1 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y /1,2 | git add -p >actual &&\n \ttail -n 5 <actual >actual.trimmed &&\n@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '\n \t_10\n \t+15\n \t_20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y / 1,2 | git add -p >actual &&\n \ttail -n 4 <actual >actual.trimmed &&\n@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '\n \ttr _ \" \" >expect <<-EOF &&\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@\n \t 10\n \t+15\n \t 20\n-\t(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n+\t(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_\n \tEOF\n \ttest_write_lines s y g 1 p | git add -p >actual &&\n \ttail -n 7 <actual >actual.trimmed &&\n@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '\n \tcat >expect <<-EOF &&\n \t<GREEN>+<RESET><GREEN>15<RESET>\n \t 20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>\n \tPAGER  10<RESET>\n \tPAGER <GREEN>+<RESET><GREEN>15<RESET>\n \tPAGER  20<RESET>\n-\t<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_write_lines s y g 1 P |\n \t(\n@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '\n \t<BOLD>-old<RESET>\n \t<BLUE>+new<RESET>\n \t<CYAN> more-context<RESET>\n-\t<YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n+\t<YELLOW>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>\n \tEOF\n \ttest_cmp expect actual\n '\n-- \n2.39.5 (Apple Git-154)\n\n"},{"id":"533509","messageId":"xmqqpl7grebf.fsf@gitster.g","threadId":"64557","inReplyTo":"aV_IGCld5T_dBxTs@Adekunles-MacBook-Air.local","subject":"Re: [GSoC PATCH v7] add -p: show user's hunk decision when selecting hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-11T03:57:56Z","receivedAt":"2026-01-11T03:57:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n\n> When a user is interactively deciding which hunks to use or skip for\n> staging, unstaging, stashing etc, there is no way to know the\n> decision previously chosen for a hunk when navigating through the\n> previous and next hunks using K/J respectively.\n>\n> Improve the UI to explicitly show if a user has previously decided to\n> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> This will improve clarity when and aid the navigation process for the\n> user.\n>\n> Reported-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> ---\n> Changes in v7:\n> ==============\n> - changed hunk selection state message to reduce prompt width\n> - Removed redundant `file_diff->hunk_nr` in hunk->use check\n> - Made the prompt mode more readable by retaining the space before choices\n> - set `hunk_use_decision` to empty string if `hunk->use == UNDECIDED` to match\n>   the prompt mode.\n\nThe latest \"was: X\" does look short and sweet.\n\nLet's wait for a few days to see if others have more input and then\nmark the topic for 'next'.\n\nThanks.\n"},{"id":"533522","messageId":"CADYq+faxjsY4cpz9JpyV4G2ufxjdkoHBrmkAhs6uFrp79_Fc3A@mail.gmail.com","threadId":"64557","inReplyTo":"xmqqpl7grebf.fsf@gitster.g","subject":"Re: [GSoC PATCH v7] add -p: show user's hunk decision when selecting hunks","fromName":"Samuel Abraham","fromEmail":"abrahamadekunle50@gmail.com","sentAt":"2026-01-11T11:04:12Z","receivedAt":"2026-01-11T11:04:11Z","isPatch":true,"sender":{"key":"abrahamadekunle50@gmail.com","avatar":"https://avatars.githubusercontent.com/u/110066922?v=4"},"body":"On Sun, Jan 11, 2026 at 4:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:\n>\n> > When a user is interactively deciding which hunks to use or skip for\n> > staging, unstaging, stashing etc, there is no way to know the\n> > decision previously chosen for a hunk when navigating through the\n> > previous and next hunks using K/J respectively.\n> >\n> > Improve the UI to explicitly show if a user has previously decided to\n> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').\n> > This will improve clarity when and aid the navigation process for the\n> > user.\n> >\n> > Reported-by: Junio C Hamano <gitster@pobox.com>\n> > Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>\n> > ---\n> > Changes in v7:\n> > ==============\n> > - changed hunk selection state message to reduce prompt width\n> > - Removed redundant `file_diff->hunk_nr` in hunk->use check\n> > - Made the prompt mode more readable by retaining the space before choices\n> > - set `hunk_use_decision` to empty string if `hunk->use == UNDECIDED` to match\n> >   the prompt mode.\n>\n> The latest \"was: X\" does look short and sweet.\n>\n> Let's wait for a few days to see if others have more input and then\n> mark the topic for 'next'.\n>\n> Thanks.\n\nThis sounds good.\nThanks\n\nAbraham.\n"}]}