* [PATCH] add -p: show hunk selection state when selecting hunks
@ 2025-11-30 15:06 Abraham Samuel Adekunle
2025-11-30 18:32 ` Junio C Hamano
2026-01-01 21:04 ` [GSoC PATCH v2] add -p: show user's hunk decision " Abraham Samuel Adekunle
0 siblings, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2025-11-30 15:06 UTC (permalink / raw)
To: git; +Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano
When selecting hunks to stage or not to stage, there is no way to know
if a hunk has been selected or not when navigating through the previous
and next hunks using K/J respectively.
Improve the UI to show whether a particular hunk has been selected
or deselected to improve clarity and aid the navigation process.
Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
add-patch.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..e70e390506 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {
N_("Stage mode change [y,n,q,a,d%s,?]? "),
N_("Stage deletion [y,n,q,a,d%s,?]? "),
N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage this hunk [y,n,q,a,d%s,?] %s? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -1564,7 +1564,19 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
- printf(_(s->mode->prompt_mode[prompt_mode_type]),
+ if (prompt_mode_type == PROMPT_HUNK) {
+ const char *state = "";
+ if (file_diff->hunk_nr) {
+ if (hunk->use == USE_HUNK)
+ state = _("[selected]");
+ else if (hunk->use == SKIP_HUNK)
+ state = _("[deselected]");
+ }
+ printf(_(s->mode->prompt_mode[prompt_mode_type]),
+ s->buf.buf, state);
+ }
+ else
+ printf(_(s->mode->prompt_mode[prompt_mode_type]),
s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] add -p: show hunk selection state when selecting hunks
2025-11-30 15:06 [PATCH] add -p: show hunk selection state when selecting hunks Abraham Samuel Adekunle
@ 2025-11-30 18:32 ` Junio C Hamano
2025-12-01 10:01 ` Abraham Samuel Adekunle
2026-01-01 21:04 ` [GSoC PATCH v2] add -p: show user's hunk decision " Abraham Samuel Adekunle
1 sibling, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2025-11-30 18:32 UTC (permalink / raw)
To: Abraham Samuel Adekunle; +Cc: git, Patrick Steinhardt, Phillip Wood
Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
> diff --git a/add-patch.c b/add-patch.c
> index 173a53241e..e70e390506 100644
> --- a/add-patch.c
> +++ b/add-patch.c
> @@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {
> N_("Stage mode change [y,n,q,a,d%s,?]? "),
> N_("Stage deletion [y,n,q,a,d%s,?]? "),
> N_("Stage addition [y,n,q,a,d%s,?]? "),
> - N_("Stage this hunk [y,n,q,a,d%s,?]? ")
> + N_("Stage this hunk [y,n,q,a,d%s,?] %s? ")
> },
Three comments:
* These sets of prompts exist for each front-end that uses the
interactive patch machinery, and we are looking at the set used
by "git add -p". But the "I came back here with K, or I do not
remember which between k and K I came back here with, and I
cannot easily tell if the hunk I am looking at is already
selected" issue is shared with other users like "git reset -p".
* "chmod +x Makefile && echo >>Makefile && git add -p" would ask if
you want to stage the mode change of the path and content change
for the path separately. You may skip, and later come back with
K to this question. The same "hmph, have I selected to use
this?" issue exists, no?
* The existing "[choices]? " was designed to be at the very end of
the question, so that the answer given by the user will come
immediately after the offered choices. Adding an overly long
"selected" or "deselected" to make it "[choices] selected?" does
not give us a pleasant end-user experience.
Also, after you decided on one hunk when you have two hunks, typing
'j' or 'k' would tell you "No other undecided hunk". The phrase
used here, "undecided", refers to the choice between USE or SKIP.
To convey the intent clearly, "Select"/"Deselect" feels a rather
indirect way (i.e. "selected for use" vs "selected to skip") to say
what is happening.
Ideally, if we can convey
Stage this mode change (you previously decided to use it) [y,n,q,a,d%s,?]?
Stage this mode change (you previously decided to skip it) [y,n,q,a,d%s,?]?
Stage this deletion (you previously decided to use it) [y,n,q,a,d%sm,?]?
...
without wasting too many extra display width, that would be great,
but this patch is not quite there, I am afraid to say.
> @@ -1564,7 +1564,19 @@ static int patch_update_file(struct add_p_state *s,
> (uintmax_t)(file_diff->hunk_nr
> ? file_diff->hunk_nr
> : 1));
> - printf(_(s->mode->prompt_mode[prompt_mode_type]),
> + if (prompt_mode_type == PROMPT_HUNK) {
> + const char *state = "";
> + if (file_diff->hunk_nr) {
> + if (hunk->use == USE_HUNK)
> + state = _("[selected]");
> + else if (hunk->use == SKIP_HUNK)
> + state = _("[deselected]");
> + }
> + printf(_(s->mode->prompt_mode[prompt_mode_type]),
> + s->buf.buf, state);
> + }
> + else
> + printf(_(s->mode->prompt_mode[prompt_mode_type]),
> s->buf.buf);
> if (*s->s.reset_color_interactive)
> fputs(s->s.reset_color_interactive, stdout);
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] add -p: show hunk selection state when selecting hunks
2025-11-30 18:32 ` Junio C Hamano
@ 2025-12-01 10:01 ` Abraham Samuel Adekunle
0 siblings, 0 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2025-12-01 10:01 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Patrick Steinhardt, Phillip Wood
On Sun, Nov 30, 2025 at 10:32:56AM -0800, Junio C Hamano wrote:
> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
>
> > diff --git a/add-patch.c b/add-patch.c
> > index 173a53241e..e70e390506 100644
> > --- a/add-patch.c
> > +++ b/add-patch.c
> > @@ -45,7 +45,7 @@ static struct patch_mode patch_mode_add = {
> > N_("Stage mode change [y,n,q,a,d%s,?]? "),
> > N_("Stage deletion [y,n,q,a,d%s,?]? "),
> > N_("Stage addition [y,n,q,a,d%s,?]? "),
> > - N_("Stage this hunk [y,n,q,a,d%s,?]? ")
> > + N_("Stage this hunk [y,n,q,a,d%s,?] %s? ")
> > },
>
> Three comments:
>
> * These sets of prompts exist for each front-end that uses the
> interactive patch machinery, and we are looking at the set used
> by "git add -p". But the "I came back here with K, or I do not
> remember which between k and K I came back here with, and I
> cannot easily tell if the hunk I am looking at is already
> selected" issue is shared with other users like "git reset -p".
Hello Junio,
Thank you for your review.
Okay, are you suggesting I apply the tweak in all prompt_mode arrays
used by other front-ends. I can see all the others modes (patch_mode_*)
shown in the file.
>
> * "chmod +x Makefile && echo >>Makefile && git add -p" would ask if
> you want to stage the mode change of the path and content change
> for the path separately. You may skip, and later come back with
> K to this question. The same "hmph, have I selected to use
> this?" issue exists, no?
Yes true, the issue does exist.
I will fix the change for the others
>
> * The existing "[choices]? " was designed to be at the very end of
> the question, so that the answer given by the user will come
> immediately after the offered choices. Adding an overly long
> "selected" or "deselected" to make it "[choices] selected?" does
> not give us a pleasant end-user experience.
Okay.
>
> Also, after you decided on one hunk when you have two hunks, typing
> 'j' or 'k' would tell you "No other undecided hunk". The phrase
> used here, "undecided", refers to the choice between USE or SKIP.
> To convey the intent clearly, "Select"/"Deselect" feels a rather
> indirect way (i.e. "selected for use" vs "selected to skip") to say
> what is happening.
>
> Ideally, if we can convey
>
> Stage this mode change (you previously decided to use it) [y,n,q,a,d%s,?]?
> Stage this mode change (you previously decided to skip it) [y,n,q,a,d%s,?]?
> Stage this deletion (you previously decided to use it) [y,n,q,a,d%sm,?]?
> ...
>
> without wasting too many extra display width, that would be great,
Okay this makes sense. But since the display width is something to watch out for,
would something like below siffice?
Stage this mode change (previous decision: stage) [y,n,q,a,d%s,?]?
Stage this mode change (previous decision: skip) [y,n,q,a,d%s,?]?
Stage this deletion (previous decision: stage) [y,n,q,a,d%s,?]?
> but this patch is not quite there, I am afraid to say.
Thank you Junio, I will work towards getting it there.
[...]
Abraham
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks
2025-11-30 15:06 [PATCH] add -p: show hunk selection state when selecting hunks Abraham Samuel Adekunle
2025-11-30 18:32 ` Junio C Hamano
@ 2026-01-01 21:04 ` Abraham Samuel Adekunle
2026-01-01 22:54 ` Junio C Hamano
2026-01-02 18:51 ` [GSoC PATCH v3] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-01 21:04 UTC (permalink / raw)
To: git; +Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity when and aid the navigation process for the
user.
Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v2:
--------------
- Modified subject to indicate GSoC participation and user's hunk decision.
- Modified the code to detect the user's decision for each front-end set
that uses the interactive patch machinery
- Changes the decision phrase to 'previous decision: _decision_' from
'Selected/Deselected'
- Placed the decision phrase before the [choices] instead of after the [choices].
add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 47 insertions(+), 37 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..bc7a340d21 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,
ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
struct hunk *hunk;
char ch;
+ const char *hunk_use_decision;
struct child_process cp = CHILD_PROCESS_INIT;
int colored = !!s->colored.len, quit = 0, use_pager = 0;
enum prompt_mode_type prompt_mode_type;
@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (file_diff->hunk_nr) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (previous decision: use) ");
+ else if (hunk->use == SKIP_HUNK)
+ hunk_use_decision = _(" (previous decision: skip) ");
+ else
+ hunk_use_decision = " ";
+
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks
2026-01-01 21:04 ` [GSoC PATCH v2] add -p: show user's hunk decision " Abraham Samuel Adekunle
@ 2026-01-01 22:54 ` Junio C Hamano
2026-01-02 7:20 ` Samuel Abraham
2026-01-02 18:51 ` [GSoC PATCH v3] " Abraham Samuel Adekunle
1 sibling, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2026-01-01 22:54 UTC (permalink / raw)
To: Abraham Samuel Adekunle; +Cc: git, Patrick Steinhardt, Phillip Wood
Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
> When a user is interactively deciding which hunks to use or skip for
> staging, unstaging, stashing etc, there is no way to know the
> decision previously chosen for a hunk when navigating through the
> previous and next hunks using K/J respectively.
>
> Improve the UI to explicitly show if a user has previously decided to
> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> This will improve clarity when and aid the navigation process for the
> user.
>
> Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
> ---
> Changes in v2:
> --------------
> - Modified subject to indicate GSoC participation and user's hunk decision.
> - Modified the code to detect the user's decision for each front-end set
> that uses the interactive patch machinery
> - Changes the decision phrase to 'previous decision: _decision_' from
> 'Selected/Deselected'
> - Placed the decision phrase before the [choices] instead of after the [choices].
> add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------
> 1 file changed, 47 insertions(+), 37 deletions(-)
Doesn't this break t3701?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v2] add -p: show user's hunk decision when selecting hunks
2026-01-01 22:54 ` Junio C Hamano
@ 2026-01-02 7:20 ` Samuel Abraham
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Abraham @ 2026-01-02 7:20 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Patrick Steinhardt, Phillip Wood
On Thu, Jan 1, 2026 at 11:54 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
>
> > When a user is interactively deciding which hunks to use or skip for
> > staging, unstaging, stashing etc, there is no way to know the
> > decision previously chosen for a hunk when navigating through the
> > previous and next hunks using K/J respectively.
> >
> > Improve the UI to explicitly show if a user has previously decided to
> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > This will improve clarity when and aid the navigation process for the
> > user.
> >
> > Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
> > Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
> > ---
> > Changes in v2:
> > --------------
> > - Modified subject to indicate GSoC participation and user's hunk decision.
> > - Modified the code to detect the user's decision for each front-end set
> > that uses the interactive patch machinery
> > - Changes the decision phrase to 'previous decision: _decision_' from
> > 'Selected/Deselected'
> > - Placed the decision phrase before the [choices] instead of after the [choices].
> > add-patch.c | 84 ++++++++++++++++++++++++++++++-----------------------
> > 1 file changed, 47 insertions(+), 37 deletions(-)
>
> Doesn't this break t3701?
Thank you for the review Junio.
Yes it does break t3701.
I will fix the broken test cases to conform to the new code and send an updated
version.
Thanks
Abraham.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks
2026-01-01 21:04 ` [GSoC PATCH v2] add -p: show user's hunk decision " Abraham Samuel Adekunle
2026-01-01 22:54 ` Junio C Hamano
@ 2026-01-02 18:51 ` Abraham Samuel Adekunle
2026-01-04 6:03 ` Junio C Hamano
2026-01-04 11:02 ` [GSoC PATCH v4] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-02 18:51 UTC (permalink / raw)
To: git; +Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity when and aid the navigation process for the
user.
Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v2:
--------------
- Modified t3701-add-interactive.sh for conform to new changes
add-patch.c | 84 +++++++++++++++++++++-----------------
t/t3701-add-interactive.sh | 14 +++----
2 files changed, 54 insertions(+), 44 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..bc7a340d21 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,
ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
struct hunk *hunk;
char ch;
+ const char *hunk_use_decision;
struct child_process cp = CHILD_PROCESS_INIT;
int colored = !!s->colored.len, quit = 0, use_pager = 0;
enum prompt_mode_type prompt_mode_type;
@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (file_diff->hunk_nr) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (previous decision: use) ");
+ else if (hunk->use == SKIP_HUNK)
+ hunk_use_decision = _(" (previous decision: skip) ");
+ else
+ hunk_use_decision = " ";
+
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 4285314f35..e856683496 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (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 @@
10
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks
2026-01-02 18:51 ` [GSoC PATCH v3] " Abraham Samuel Adekunle
@ 2026-01-04 6:03 ` Junio C Hamano
2026-01-04 10:36 ` Samuel Abraham
2026-01-04 11:02 ` [GSoC PATCH v4] " Abraham Samuel Adekunle
1 sibling, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2026-01-04 6:03 UTC (permalink / raw)
To: Abraham Samuel Adekunle; +Cc: git, Patrick Steinhardt, Phillip Wood
Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
> When a user is interactively deciding which hunks to use or skip for
> staging, unstaging, stashing etc, there is no way to know the
> decision previously chosen for a hunk when navigating through the
> previous and next hunks using K/J respectively.
>
> Improve the UI to explicitly show if a user has previously decided to
> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> This will improve clarity when and aid the navigation process for the
> user.
>
> Reported-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
> ---
>
> Changes in v2:
> --------------
> - Modified t3701-add-interactive.sh for conform to new changes
Here is how "cd t && sh t3701-add-interactive.sh -i -v" ends for me.
expecting success of 3701.50 'print again the hunk (PAGER)':
test_when_finished "git reset" &&
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
<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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
GIT_PAGER="sed s/^/PAGER\ /" &&
export GIT_PAGER &&
test_terminal git add -p >actual
) &&
tail -n 7 <actual | test_decode_color >actual.trimmed &&
test_cmp expect actual.trimmed
--- expect 2026-01-04 06:01:25.931220332 +0000
+++ actual.trimmed 2026-01-04 06:01:26.079845771 +0000
@@ -1,7 +1,7 @@
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
-<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>
+<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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
-<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
not ok 50 - print again the hunk (PAGER)
#
# test_when_finished "git reset" &&
# cat >expect <<-EOF &&
# <GREEN>+<RESET><GREEN>15<RESET>
# 20<RESET>
# <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>
# PAGER 10<RESET>
# PAGER <GREEN>+<RESET><GREEN>15<RESET>
# PAGER 20<RESET>
# <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
# EOF
# test_write_lines s y g 1 P |
# (
# GIT_PAGER="sed s/^/PAGER\ /" &&
# export GIT_PAGER &&
# test_terminal git add -p >actual
# ) &&
# tail -n 7 <actual | test_decode_color >actual.trimmed &&
# test_cmp expect actual.trimmed
#
1..50
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v3] add -p: show user's hunk decision when selecting hunks
2026-01-04 6:03 ` Junio C Hamano
@ 2026-01-04 10:36 ` Samuel Abraham
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Abraham @ 2026-01-04 10:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Patrick Steinhardt, Phillip Wood
On Sun, Jan 4, 2026 at 7:03 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Abraham Samuel Adekunle <abrahamadekunle50@gmail.com> writes:
>
> > When a user is interactively deciding which hunks to use or skip for
> > staging, unstaging, stashing etc, there is no way to know the
> > decision previously chosen for a hunk when navigating through the
> > previous and next hunks using K/J respectively.
> >
> > Improve the UI to explicitly show if a user has previously decided to
> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > This will improve clarity when and aid the navigation process for the
> > user.
> >
> > Reported-by: Junio C Hamano <gitster@pobox.com>
> > Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
> > ---
> >
> > Changes in v2:
> > --------------
> > - Modified t3701-add-interactive.sh for conform to new changes
>
> Here is how "cd t && sh t3701-add-interactive.sh -i -v" ends for me.
>
> expecting success of 3701.50 'print again the hunk (PAGER)':
> test_when_finished "git reset" &&
> cat >expect <<-EOF &&
> <GREEN>+<RESET><GREEN>15<RESET>
> 20<RESET>
> <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>
> PAGER 10<RESET>
> PAGER <GREEN>+<RESET><GREEN>15<RESET>
> PAGER 20<RESET>
> <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> EOF
> test_write_lines s y g 1 P |
> (
> GIT_PAGER="sed s/^/PAGER\ /" &&
> export GIT_PAGER &&
> test_terminal git add -p >actual
> ) &&
> tail -n 7 <actual | test_decode_color >actual.trimmed &&
> test_cmp expect actual.trimmed
>
> --- expect 2026-01-04 06:01:25.931220332 +0000
> +++ actual.trimmed 2026-01-04 06:01:26.079845771 +0000
> @@ -1,7 +1,7 @@
> <GREEN>+<RESET><GREEN>15<RESET>
> 20<RESET>
> -<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>
> +<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>
> PAGER 10<RESET>
> PAGER <GREEN>+<RESET><GREEN>15<RESET>
> PAGER 20<RESET>
> -<BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> +<BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> not ok 50 - print again the hunk (PAGER)
> #
> # test_when_finished "git reset" &&
> # cat >expect <<-EOF &&
> # <GREEN>+<RESET><GREEN>15<RESET>
> # 20<RESET>
> # <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>
> # PAGER 10<RESET>
> # PAGER <GREEN>+<RESET><GREEN>15<RESET>
> # PAGER 20<RESET>
> # <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> # EOF
> # test_write_lines s y g 1 P |
> # (
> # GIT_PAGER="sed s/^/PAGER\ /" &&
> # export GIT_PAGER &&
> # test_terminal git add -p >actual
> # ) &&
> # tail -n 7 <actual | test_decode_color >actual.trimmed &&
> # test_cmp expect actual.trimmed
> #
> 1..50
Thank you Junio for the reviews.
I get the output when I run "cd t && ./t3701-add-interactive.sh -i -v"
[...]
ok 49 - print again the hunk
checking prerequisite: TTY
mkdir -p "$TRASH_DIRECTORY/prereq-test-dir-TTY" &&
(
cd "$TRASH_DIRECTORY/prereq-test-dir-TTY" &&
test_have_prereq PERL &&
# Reading from the pty master seems to get stuck _sometimes_
# on Mac OS X 10.5.0, using Perl 5.10.0 or 5.8.9.
#
# Reproduction recipe: run
#
# i=0
# while ./test-terminal.perl echo hi $i
# do
# : $((i = $i + 1))
# done
#
# After 2000 iterations or so it hangs.
# https://rt.cpan.org/Ticket/Display.html?id=65692
#
test "$(uname -s)" != Darwin &&
perl "$TEST_DIRECTORY"/test-terminal.perl \
sh -c "test -t 1 && test -t 2"
)
prerequisite TTY not satisfied
ok 50 # skip print again the hunk (PAGER) (missing TTY)
ok 51 # skip P handles SIGPIPE when writing to pager (missing TTY)
So that test skipped on my end because of this `test "$(uname -s)" != Darwin &&`
since I am working on a MacOS.
I will correct it and send an updated version.
Thanks
Abraham
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks
2026-01-02 18:51 ` [GSoC PATCH v3] " Abraham Samuel Adekunle
2026-01-04 6:03 ` Junio C Hamano
@ 2026-01-04 11:02 ` Abraham Samuel Adekunle
2026-01-05 19:35 ` SZEDER Gábor
2026-01-06 11:05 ` [GSoC PATCH v5] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-04 11:02 UTC (permalink / raw)
To: git; +Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity when and aid the navigation process for the
user.
Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v4:
--------------
- Modified the test case
"expecting success of 3701.50 'print again the hunk (PAGER)'"
which was skipped in v3 due to the test being run on a MacOs
add-patch.c | 84 +++++++++++++++++++++-----------------
t/t3701-add-interactive.sh | 18 ++++----
2 files changed, 56 insertions(+), 46 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..bc7a340d21 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,
ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
struct hunk *hunk;
char ch;
+ const char *hunk_use_decision;
struct child_process cp = CHILD_PROCESS_INIT;
int colored = !!s->colored.len, quit = 0, use_pager = 0;
enum prompt_mode_type prompt_mode_type;
@@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (file_diff->hunk_nr) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (previous decision: use) ");
+ else if (hunk->use == SKIP_HUNK)
+ hunk_use_decision = _(" (previous decision: skip) ");
+ else
+ hunk_use_decision = " ";
+
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 4285314f35..cc3986a9d7 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (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 @@
10
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks
2026-01-04 11:02 ` [GSoC PATCH v4] " Abraham Samuel Adekunle
@ 2026-01-05 19:35 ` SZEDER Gábor
2026-01-05 21:52 ` Samuel Abraham
2026-01-06 11:05 ` [GSoC PATCH v5] " Abraham Samuel Adekunle
1 sibling, 1 reply; 23+ messages in thread
From: SZEDER Gábor @ 2026-01-05 19:35 UTC (permalink / raw)
To: Abraham Samuel Adekunle
Cc: git, Patrick Steinhardt, Phillip Wood, Junio C Hamano
On Sun, Jan 04, 2026 at 12:02:55PM +0100, Abraham Samuel Adekunle wrote:
> diff --git a/add-patch.c b/add-patch.c
> index 173a53241e..bc7a340d21 100644
> --- a/add-patch.c
> +++ b/add-patch.c
> @@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,
> ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
> struct hunk *hunk;
> char ch;
> + const char *hunk_use_decision;
'hunk_use_decision' is defined here, but is left uninitialized.
> struct child_process cp = CHILD_PROCESS_INIT;
> int colored = !!s->colored.len, quit = 0, use_pager = 0;
> enum prompt_mode_type prompt_mode_type;
> @@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,
> (uintmax_t)(file_diff->hunk_nr
> ? file_diff->hunk_nr
> : 1));
> + if (file_diff->hunk_nr) {
> + if (hunk->use == USE_HUNK)
> + hunk_use_decision = _(" (previous decision: use) ");
> + else if (hunk->use == SKIP_HUNK)
> + hunk_use_decision = _(" (previous decision: skip) ");
> + else
> + hunk_use_decision = " ";
'hunk_use_decision' is set here, but only if 'file_diff->hunk_nr' is
non-zero.
> +`
> + }
Nit: unnecessary empty line before the closing brace.
> printf(_(s->mode->prompt_mode[prompt_mode_type]),
> - s->buf.buf);
> + hunk_use_decision, s->buf.buf);
So 'hunk_use_decision' is used uninitialized here if
'file_diff->hunk_nr' is zero.
> if (*s->s.reset_color_interactive)
> fputs(s->s.reset_color_interactive, stdout);
> fflush(stdout);
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v4] add -p: show user's hunk decision when selecting hunks
2026-01-05 19:35 ` SZEDER Gábor
@ 2026-01-05 21:52 ` Samuel Abraham
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Abraham @ 2026-01-05 21:52 UTC (permalink / raw)
To: SZEDER Gábor; +Cc: git, Patrick Steinhardt, Phillip Wood, Junio C Hamano
On Mon, Jan 5, 2026 at 8:35 PM SZEDER Gábor <szeder.dev@gmail.com> wrote:
>
> On Sun, Jan 04, 2026 at 12:02:55PM +0100, Abraham Samuel Adekunle wrote:
> > diff --git a/add-patch.c b/add-patch.c
> > index 173a53241e..bc7a340d21 100644
> > --- a/add-patch.c
> > +++ b/add-patch.c
>
> > @@ -1448,6 +1448,7 @@ static int patch_update_file(struct add_p_state *s,
> > ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
> > struct hunk *hunk;
> > char ch;
> > + const char *hunk_use_decision;
>
> 'hunk_use_decision' is defined here, but is left uninitialized.
>
> > struct child_process cp = CHILD_PROCESS_INIT;
> > int colored = !!s->colored.len, quit = 0, use_pager = 0;
> > enum prompt_mode_type prompt_mode_type;
> > @@ -1564,8 +1565,17 @@ static int patch_update_file(struct add_p_state *s,
> > (uintmax_t)(file_diff->hunk_nr
> > ? file_diff->hunk_nr
> > : 1));
> > + if (file_diff->hunk_nr) {
> > + if (hunk->use == USE_HUNK)
> > + hunk_use_decision = _(" (previous decision: use) ");
> > + else if (hunk->use == SKIP_HUNK)
> > + hunk_use_decision = _(" (previous decision: skip) ");
> > + else
> > + hunk_use_decision = " ";
>
> 'hunk_use_decision' is set here, but only if 'file_diff->hunk_nr' is
> non-zero.
>
> > +`
> > + }
>
> Nit: unnecessary empty line before the closing brace.
>
> > printf(_(s->mode->prompt_mode[prompt_mode_type]),
> > - s->buf.buf);
> > + hunk_use_decision, s->buf.buf);
>
> So 'hunk_use_decision' is used uninitialized here if
> 'file_diff->hunk_nr' is zero.
>
hello SZEDER,
Thank you very much for the review
Yes, you are right, `hunk_use_decision` is left uninitialized if
`file_diff->hunk` is zero
I will fix the patch and send an updated version.
Abraham.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks
2026-01-04 11:02 ` [GSoC PATCH v4] " Abraham Samuel Adekunle
2026-01-05 19:35 ` SZEDER Gábor
@ 2026-01-06 11:05 ` Abraham Samuel Adekunle
2026-01-06 11:08 ` Kristoffer Haugsbakk
2026-01-06 12:01 ` [GSoC PATCH v6] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-06 11:05 UTC (permalink / raw)
To: git
Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano,
SZEDER Gábor, Christian Couder
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity when and aid the navigation process for the
user.
Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v5:
===============
- Modified code to handle uninitialized variable `hunk_use_decision`
observed by SZEDER Gábor.
- Removed an unnecessary empty line
add-patch.c | 81 +++++++++++++++++++++-----------------
t/t3701-add-interactive.sh | 18 ++++-----
2 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..a383ea7f45 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,
render_diff_header(s, file_diff, colored, &s->buf);
fputs(s->buf.buf, stdout);
for (;;) {
+ const char *hunk_use_decision = " ";
enum {
ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,
ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,
@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (previous decision: use) ");
+ else
+ hunk_use_decision = _(" (previous decision: skip) ");
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 4285314f35..cc3986a9d7 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (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 @@
10
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks
2026-01-06 11:05 ` [GSoC PATCH v5] " Abraham Samuel Adekunle
@ 2026-01-06 11:08 ` Kristoffer Haugsbakk
2026-01-06 11:46 ` Samuel Abraham
2026-01-06 12:01 ` [GSoC PATCH v6] " Abraham Samuel Adekunle
1 sibling, 1 reply; 23+ messages in thread
From: Kristoffer Haugsbakk @ 2026-01-06 11:08 UTC (permalink / raw)
To: Samuel Adekunle Abraham, git
Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano,
SZEDER Gábor, Christian Couder
On Tue, Jan 6, 2026, at 12:05, Abraham Samuel Adekunle wrote:
> When a user is interactively deciding which hunks to use or skip for
> staging, unstaging, stashing etc, there is no way to know the
> decision previously chosen for a hunk when navigating through the
> previous and next hunks using K/J respectively.
>
> Improve the UI to explicitly show if a user has previously decided to
> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> This will improve clarity when and aid the navigation process for the
> user.
>
> Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
This is doubled again like it was in the first version.
> Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
>[snip]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v5] add -p: show user's hunk decision when selecting hunks
2026-01-06 11:08 ` Kristoffer Haugsbakk
@ 2026-01-06 11:46 ` Samuel Abraham
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Abraham @ 2026-01-06 11:46 UTC (permalink / raw)
To: Kristoffer Haugsbakk
Cc: git, Patrick Steinhardt, Phillip Wood, Junio C Hamano,
SZEDER Gábor, Christian Couder
On Tue, Jan 6, 2026 at 12:09 PM Kristoffer Haugsbakk
<kristofferhaugsbakk@fastmail.com> wrote:
>
> On Tue, Jan 6, 2026, at 12:05, Abraham Samuel Adekunle wrote:
> > When a user is interactively deciding which hunks to use or skip for
> > staging, unstaging, stashing etc, there is no way to know the
> > decision previously chosen for a hunk when navigating through the
> > previous and next hunks using K/J respectively.
> >
> > Improve the UI to explicitly show if a user has previously decided to
> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > This will improve clarity when and aid the navigation process for the
> > user.
> >
> > Reported-by: Reported-by: Junio C Hamano <gitster@pobox.com>
>
> This is doubled again like it was in the first version.
Ah!!
I'm sorry about this
I will fix it now.
Thanks
Abraham
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 11:05 ` [GSoC PATCH v5] " Abraham Samuel Adekunle
2026-01-06 11:08 ` Kristoffer Haugsbakk
@ 2026-01-06 12:01 ` Abraham Samuel Adekunle
2026-01-06 16:10 ` Phillip Wood
2026-01-08 15:07 ` [GSoC PATCH v7] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-06 12:01 UTC (permalink / raw)
To: git
Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano,
SZEDER Gábor, Christian Couder, Kristoffer Haugsbakk
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity and aid the navigation process for the
user.
Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v6:
==============
- Corrected duplicate Reported-by tag
add-patch.c | 81 +++++++++++++++++++++-----------------
t/t3701-add-interactive.sh | 18 ++++-----
2 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..a383ea7f45 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s[y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s[y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s[y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s[y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,
render_diff_header(s, file_diff, colored, &s->buf);
fputs(s->buf.buf, stdout);
for (;;) {
+ const char *hunk_use_decision = " ";
enum {
ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,
ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,
@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (previous decision: use) ");
+ else
+ hunk_use_decision = _(" (previous decision: skip) ");
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 4285314f35..cc3986a9d7 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (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 @@
10
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 12:01 ` [GSoC PATCH v6] " Abraham Samuel Adekunle
@ 2026-01-06 16:10 ` Phillip Wood
2026-01-06 19:01 ` Ben Knoble
2026-01-06 22:02 ` Samuel Abraham
2026-01-08 15:07 ` [GSoC PATCH v7] " Abraham Samuel Adekunle
1 sibling, 2 replies; 23+ messages in thread
From: Phillip Wood @ 2026-01-06 16:10 UTC (permalink / raw)
To: Abraham Samuel Adekunle, git
Cc: Patrick Steinhardt, Junio C Hamano, SZEDER Gábor,
Christian Couder, Kristoffer Haugsbakk
Hi Abraham
On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:
> When a user is interactively deciding which hunks to use or skip for
> staging, unstaging, stashing etc, there is no way to know the
> decision previously chosen for a hunk when navigating through the
> previous and next hunks using K/J respectively.
>
> Improve the UI to explicitly show if a user has previously decided to
> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> This will improve clarity and aid the navigation process for the
> user.
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.
> diff --git a/add-patch.c b/add-patch.c
> index 173a53241e..a383ea7f45 100644
> --- a/add-patch.c
> +++ b/add-patch.c
> @@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
> .apply_args = { "--cached", NULL },
> .apply_check_args = { "--cached", NULL },
> .prompt_mode = {
> - N_("Stage mode change [y,n,q,a,d%s,?]? "),
> - N_("Stage deletion [y,n,q,a,d%s,?]? "),
> - N_("Stage addition [y,n,q,a,d%s,?]? "),
> - N_("Stage this hunk [y,n,q,a,d%s,?]? ")
> + N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
> + N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
> + N_("Stage addition%s[y,n,q,a,d%s,?]? "),
> + N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
I'd find these strings easier to read if we kept the space and just
passed an empty string when the hunk is undecided.
> @@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,
> (uintmax_t)(file_diff->hunk_nr
> ? file_diff->hunk_nr
> : 1));
> + if (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {
Why do we need to check hunk_nr here?
Thanks
Phillip
> + if (hunk->use == USE_HUNK)
> + hunk_use_decision = _(" (previous decision: use) ");
> + else
> + hunk_use_decision = _(" (previous decision: skip) ");
> + }
> printf(_(s->mode->prompt_mode[prompt_mode_type]),
> - s->buf.buf);
> + hunk_use_decision, s->buf.buf);
> if (*s->s.reset_color_interactive)
> fputs(s->s.reset_color_interactive, stdout);
> fflush(stdout);
> diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
> index 4285314f35..cc3986a9d7 100755
> --- a/t/t3701-add-interactive.sh
> +++ b/t/t3701-add-interactive.sh
> @@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
> _10
> +15
> _20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> + (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> EOF
> test_write_lines s y g 1 | git add -p >actual &&
> tail -n 7 <actual >actual.trimmed &&
> @@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
> _10
> +15
> _20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> + (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> EOF
> test_write_lines s y g1 | git add -p >actual &&
> tail -n 4 <actual >actual.trimmed &&
> @@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
> _10
> +15
> _20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> + (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> EOF
> test_write_lines s y /1,2 | git add -p >actual &&
> tail -n 5 <actual >actual.trimmed &&
> @@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
> _10
> +15
> _20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> + (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> EOF
> test_write_lines s y / 1,2 | git add -p >actual &&
> tail -n 4 <actual >actual.trimmed &&
> @@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
> tr _ " " >expect <<-EOF &&
> +15
> 20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
> + (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 @@
> 10
> +15
> 20
> - (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> + (1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
> EOF
> test_write_lines s y g 1 p | git add -p >actual &&
> tail -n 7 <actual >actual.trimmed &&
> @@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
> cat >expect <<-EOF &&
> <GREEN>+<RESET><GREEN>15<RESET>
> 20<RESET>
> - <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
> + <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>
> PAGER 10<RESET>
> PAGER <GREEN>+<RESET><GREEN>15<RESET>
> PAGER 20<RESET>
> - <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> + <BOLD;BLUE>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> EOF
> test_write_lines s y g 1 P |
> (
> @@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
> <BOLD>-old<RESET>
> <BLUE>+new<RESET>
> <CYAN> more-context<RESET>
> - <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> + <YELLOW>(1/2) Stage this hunk (previous decision: use) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
> EOF
> test_cmp expect actual
> '
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 16:10 ` Phillip Wood
@ 2026-01-06 19:01 ` Ben Knoble
2026-01-07 0:13 ` Junio C Hamano
2026-01-06 22:02 ` Samuel Abraham
1 sibling, 1 reply; 23+ messages in thread
From: Ben Knoble @ 2026-01-06 19:01 UTC (permalink / raw)
To: phillip.wood
Cc: Abraham Samuel Adekunle, git, Patrick Steinhardt, Junio C Hamano,
SZEDER Gábor, Christian Couder, Kristoffer Haugsbakk
> Le 6 janv. 2026 à 11:13, Phillip Wood <phillip.wood123@gmail.com> a écrit :
>
> Hi Abraham
>
>> On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:
>> When a user is interactively deciding which hunks to use or skip for
>> staging, unstaging, stashing etc, there is no way to know the
>> decision previously chosen for a hunk when navigating through the
>> previous and next hunks using K/J respectively.
>> Improve the UI to explicitly show if a user has previously decided to
>> use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
>> This will improve clarity and aid the navigation process for the
>> user.
>
> 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.
I haven’t looked carefully, so apologies if this is nonsense.
What if the marker of current state were on a separate line before the prompt? That would allow more room, right?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 16:10 ` Phillip Wood
2026-01-06 19:01 ` Ben Knoble
@ 2026-01-06 22:02 ` Samuel Abraham
2026-01-06 22:19 ` Samuel Abraham
1 sibling, 1 reply; 23+ messages in thread
From: Samuel Abraham @ 2026-01-06 22:02 UTC (permalink / raw)
To: phillip.wood
Cc: git, Patrick Steinhardt, Junio C Hamano, SZEDER Gábor,
Christian Couder, Kristoffer Haugsbakk
On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:
>
> Hi Abraham
Hello Phillip,
>
> On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:
> > When a user is interactively deciding which hunks to use or skip for
> > staging, unstaging, stashing etc, there is no way to know the
> > decision previously chosen for a hunk when navigating through the
> > previous and next hunks using K/J respectively.
> >
> > Improve the UI to explicitly show if a user has previously decided to
> > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > This will improve clarity and aid the navigation process for the
> > user.
>
> 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.
Thank you for the review
So I previously used selected/deselected. But Junio was not okay with those
choice of words because they did not clearly tell If the user selected
to skip or
or selected to use the hunk.
But how about
Stage this mode change (you chose: use) [y,n,q,a,d%s,?]?
Stage this mode change (you chose: skip) [y,n,q,a,d%s,?]?
Stage this deletion (you chose: use) [y,n,q,a,d%sm,?]?
or
Stage this mode change (choice: use) [y,n,q,a,d%s,?]?
Stage this mode change (choice: skip)[y,n,q,a,d%s,?]?
Stage this deletion (choice: skip)" [y,n,q,a,d%sm,?]?
or
Stage this mode change (use: yes) [y,n,q,a,d%s,?]?
Stage this mode change (use: no) [y,n,q,a,d%s,?]?
Stage this deletion (use: no) [y,n,q,a,d%sm,?]?
Though I feel the last one does not fully tell what is happening
at a glance.
I can wait for more suggestions from other members if these do not
suffice.
>
> > diff --git a/add-patch.c b/add-patch.c
> > index 173a53241e..a383ea7f45 100644
> > --- a/add-patch.c
> > +++ b/add-patch.c
> > @@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
> > .apply_args = { "--cached", NULL },
> > .apply_check_args = { "--cached", NULL },
> > .prompt_mode = {
> > - N_("Stage mode change [y,n,q,a,d%s,?]? "),
> > - N_("Stage deletion [y,n,q,a,d%s,?]? "),
> > - N_("Stage addition [y,n,q,a,d%s,?]? "),
> > - N_("Stage this hunk [y,n,q,a,d%s,?]? ")
> > + N_("Stage mode change%s[y,n,q,a,d%s,?]? "),
> > + N_("Stage deletion%s[y,n,q,a,d%s,?]? "),
> > + N_("Stage addition%s[y,n,q,a,d%s,?]? "),
> > + N_("Stage this hunk%s[y,n,q,a,d%s,?]? ")
>
> I'd find these strings easier to read if we kept the space and just
> passed an empty string when the hunk is undecided.
Okay I understand.
Thank you. I will do that
>
> > @@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,
> > (uintmax_t)(file_diff->hunk_nr
> > ? file_diff->hunk_nr
> > : 1));
> > + if (file_diff->hunk_nr && hunk->use != UNDECIDED_HUNK) {
>
> Why do we need to check hunk_nr here?
Okay it is actually not necessary to check `hunk_nr` since
`hunk` is set to `file_diff->head` if `file_diff->hunk_nr` is zero
Thank you for the observation.
Abraham.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 22:02 ` Samuel Abraham
@ 2026-01-06 22:19 ` Samuel Abraham
2026-01-07 8:49 ` Samuel Abraham
0 siblings, 1 reply; 23+ messages in thread
From: Samuel Abraham @ 2026-01-06 22:19 UTC (permalink / raw)
To: phillip.wood
Cc: git, Patrick Steinhardt, Junio C Hamano, SZEDER Gábor,
Christian Couder, Kristoffer Haugsbakk
On Tue, Jan 6, 2026 at 11:02 PM Samuel Abraham
<abrahamadekunle50@gmail.com> wrote:
>
> On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:
> >
> > Hi Abraham
>
> Hello Phillip,
>
> >
> > On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:
> > > When a user is interactively deciding which hunks to use or skip for
> > > staging, unstaging, stashing etc, there is no way to know the
> > > decision previously chosen for a hunk when navigating through the
> > > previous and next hunks using K/J respectively.
> > >
> > > Improve the UI to explicitly show if a user has previously decided to
> > > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > > This will improve clarity and aid the navigation process for the
> > > user.
> >
> > 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.
>
> Thank you for the review
> So I previously used selected/deselected. But Junio was not okay with those
> choice of words because they did not clearly tell If the user selected
> to skip or
> or selected to use the hunk.
>
> But how about
>
> Stage this mode change (you chose: use) [y,n,q,a,d%s,?]?
> Stage this mode change (you chose: skip) [y,n,q,a,d%s,?]?
> Stage this deletion (you chose: use) [y,n,q,a,d%sm,?]?
>
> or
> Stage this mode change (choice: use) [y,n,q,a,d%s,?]?
> Stage this mode change (choice: skip)[y,n,q,a,d%s,?]?
> Stage this deletion (choice: skip)" [y,n,q,a,d%sm,?]?
>
> or
> Stage this mode change (use: yes) [y,n,q,a,d%s,?]?
> Stage this mode change (use: no) [y,n,q,a,d%s,?]?
> Stage this deletion (use: no) [y,n,q,a,d%sm,?]?
>
Also "(you chose yes)" i think is an option also.
Stage this mode change (you chose yes) [y,n,q,a,d%s,?]?
Stage this mode change (you chose no) [y,n,q,a,d%s,?]?
Stage this deletion (you chose no) [y,n,q,a,d%sm,?]?
Abraham.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 19:01 ` Ben Knoble
@ 2026-01-07 0:13 ` Junio C Hamano
0 siblings, 0 replies; 23+ messages in thread
From: Junio C Hamano @ 2026-01-07 0:13 UTC (permalink / raw)
To: Ben Knoble
Cc: phillip.wood, Abraham Samuel Adekunle, git, Patrick Steinhardt,
SZEDER Gábor, Christian Couder, Kristoffer Haugsbakk
Ben Knoble <ben.knoble@gmail.com> writes:
>> 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.
>
> I haven’t looked carefully, so apologies if this is nonsense.
>
> What if the marker of current state were on a separate line before
> the prompt? That would allow more room, right?
Vertical screen real estate is also a limited resource. Also, while
it is good if we let users know what the current selection status
is, I personally do not think the benefit outweighs the downside of
cluttering the prompt unless it is kept to the minimum. So I very
much appreciate that Phillip raised this point.
Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [GSoC PATCH v6] add -p: show user's hunk decision when selecting hunks
2026-01-06 22:19 ` Samuel Abraham
@ 2026-01-07 8:49 ` Samuel Abraham
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Abraham @ 2026-01-07 8:49 UTC (permalink / raw)
To: phillip.wood
Cc: git, Patrick Steinhardt, Junio C Hamano, SZEDER Gábor,
Christian Couder, Kristoffer Haugsbakk
On Tue, Jan 6, 2026 at 11:19 PM Samuel Abraham
<abrahamadekunle50@gmail.com> wrote:
>
> On Tue, Jan 6, 2026 at 11:02 PM Samuel Abraham
> <abrahamadekunle50@gmail.com> wrote:
> >
> > On Tue, Jan 6, 2026 at 5:10 PM Phillip Wood <phillip.wood123@gmail.com> wrote:
> > >
> > > Hi Abraham
> >
> > Hello Phillip,
> >
> > >
> > > On 06/01/2026 12:01, Abraham Samuel Adekunle wrote:
> > > > When a user is interactively deciding which hunks to use or skip for
> > > > staging, unstaging, stashing etc, there is no way to know the
> > > > decision previously chosen for a hunk when navigating through the
> > > > previous and next hunks using K/J respectively.
> > > >
> > > > Improve the UI to explicitly show if a user has previously decided to
> > > > use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
> > > > This will improve clarity and aid the navigation process for the
> > > > user.
> > >
> > > 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.
> >
> > Thank you for the review
> > So I previously used selected/deselected. But Junio was not okay with those
> > choice of words because they did not clearly tell If the user selected
> > to skip or
> > or selected to use the hunk.
> >
> > But how about
> >
> > Stage this mode change (you chose: use) [y,n,q,a,d%s,?]?
> > Stage this mode change (you chose: skip) [y,n,q,a,d%s,?]?
> > Stage this deletion (you chose: use) [y,n,q,a,d%sm,?]?
> >
> > or
> > Stage this mode change (choice: use) [y,n,q,a,d%s,?]?
> > Stage this mode change (choice: skip)[y,n,q,a,d%s,?]?
> > Stage this deletion (choice: skip)" [y,n,q,a,d%sm,?]?
> >
> > or
> > Stage this mode change (use: yes) [y,n,q,a,d%s,?]?
> > Stage this mode change (use: no) [y,n,q,a,d%s,?]?
> > Stage this deletion (use: no) [y,n,q,a,d%sm,?]?
> >
>
> Also "(you chose yes)" i think is an option also.
> Stage this mode change (you chose yes) [y,n,q,a,d%s,?]?
> Stage this mode change (you chose no) [y,n,q,a,d%s,?]?
> Stage this deletion (you chose no) [y,n,q,a,d%sm,?]?
>
> Abraham.
I also think "(was: y)" or "(was: n)" is considerably shorter
Stage this mode change (was: y) [y,n,q,a,d%s,?]?
Stage this mode change (was: n) [y,n,q,a,d%s,?]?
Stage this deletion (was: y) [y,n,q,a,d%sm,?]?
^ permalink raw reply [flat|nested] 23+ messages in thread
* [GSoC PATCH v7] add -p: show user's hunk decision when selecting hunks
2026-01-06 12:01 ` [GSoC PATCH v6] " Abraham Samuel Adekunle
2026-01-06 16:10 ` Phillip Wood
@ 2026-01-08 15:07 ` Abraham Samuel Adekunle
1 sibling, 0 replies; 23+ messages in thread
From: Abraham Samuel Adekunle @ 2026-01-08 15:07 UTC (permalink / raw)
To: git
Cc: Patrick Steinhardt, Phillip Wood, Junio C Hamano,
SZEDER Gábor, Christian Couder, Kristoffer Haugsbakk,
Ben Knoble
When a user is interactively deciding which hunks to use or skip for
staging, unstaging, stashing etc, there is no way to know the
decision previously chosen for a hunk when navigating through the
previous and next hunks using K/J respectively.
Improve the UI to explicitly show if a user has previously decided to
use a hunk (by pressing 'y') or skip the hunk (by pressing 'n').
This will improve clarity when and aid the navigation process for the
user.
Reported-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail.com>
---
Changes in v7:
==============
- changed hunk selection state message to reduce prompt width
- Removed redundant `file_diff->hunk_nr` in hunk->use check
- Made the prompt mode more readable by retaining the space before choices
- set `hunk_use_decision` to empty string if `hunk->use == UNDECIDED` to match
the prompt mode.
add-patch.c | 81 +++++++++++++++++++++-----------------
t/t3701-add-interactive.sh | 18 ++++-----
2 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/add-patch.c b/add-patch.c
index 173a53241e..df8f2e6d74 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -42,10 +42,10 @@ static struct patch_mode patch_mode_add = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stage mode change [y,n,q,a,d%s,?]? "),
- N_("Stage deletion [y,n,q,a,d%s,?]? "),
- N_("Stage addition [y,n,q,a,d%s,?]? "),
- N_("Stage this hunk [y,n,q,a,d%s,?]? ")
+ N_("Stage mode change%s [y,n,q,a,d%s,?]? "),
+ N_("Stage deletion%s [y,n,q,a,d%s,?]? "),
+ N_("Stage addition%s [y,n,q,a,d%s,?]? "),
+ N_("Stage this hunk%s [y,n,q,a,d%s,?]? ")
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for staging."),
@@ -64,10 +64,10 @@ static struct patch_mode patch_mode_stash = {
.apply_args = { "--cached", NULL },
.apply_check_args = { "--cached", NULL },
.prompt_mode = {
- N_("Stash mode change [y,n,q,a,d%s,?]? "),
- N_("Stash deletion [y,n,q,a,d%s,?]? "),
- N_("Stash addition [y,n,q,a,d%s,?]? "),
- N_("Stash this hunk [y,n,q,a,d%s,?]? "),
+ N_("Stash mode change%s [y,n,q,a,d%s,?]? "),
+ N_("Stash deletion%s [y,n,q,a,d%s,?]? "),
+ N_("Stash addition%s [y,n,q,a,d%s,?]? "),
+ N_("Stash this hunk%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for stashing."),
@@ -88,10 +88,10 @@ static struct patch_mode patch_mode_reset_head = {
.is_reverse = 1,
.index_only = 1,
.prompt_mode = {
- N_("Unstage mode change [y,n,q,a,d%s,?]? "),
- N_("Unstage deletion [y,n,q,a,d%s,?]? "),
- N_("Unstage addition [y,n,q,a,d%s,?]? "),
- N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
+ N_("Unstage mode change%s [y,n,q,a,d%s,?]? "),
+ N_("Unstage deletion%s [y,n,q,a,d%s,?]? "),
+ N_("Unstage addition%s [y,n,q,a,d%s,?]? "),
+ N_("Unstage this hunk%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for unstaging."),
@@ -111,10 +111,10 @@ static struct patch_mode patch_mode_reset_nothead = {
.apply_check_args = { "--cached", NULL },
.index_only = 1,
.prompt_mode = {
- N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index%s [y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index%s [y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index%s [y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -134,10 +134,10 @@ static struct patch_mode patch_mode_checkout_index = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -157,10 +157,10 @@ static struct patch_mode patch_mode_checkout_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from index and worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard addition from index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from index and worktree%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -179,10 +179,10 @@ static struct patch_mode patch_mode_checkout_nothead = {
.apply_for_checkout = 1,
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to index and worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply addition to index and worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to index and worktree%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -202,10 +202,10 @@ static struct patch_mode patch_mode_worktree_head = {
.apply_check_args = { "-R", NULL },
.is_reverse = 1,
.prompt_mode = {
- N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard addition from worktree [y,n,q,a,d%s,?]? "),
- N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
+ N_("Discard mode change from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard deletion from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard addition from worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Discard this hunk from worktree%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for discarding."),
@@ -224,10 +224,10 @@ static struct patch_mode patch_mode_worktree_nothead = {
.apply_args = { NULL },
.apply_check_args = { NULL },
.prompt_mode = {
- N_("Apply mode change to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply deletion to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply addition to worktree [y,n,q,a,d%s,?]? "),
- N_("Apply this hunk to worktree [y,n,q,a,d%s,?]? "),
+ N_("Apply mode change to worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply deletion to worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply addition to worktree%s [y,n,q,a,d%s,?]? "),
+ N_("Apply this hunk to worktree%s [y,n,q,a,d%s,?]? "),
},
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
"will immediately be marked for applying."),
@@ -1460,6 +1460,7 @@ static int patch_update_file(struct add_p_state *s,
render_diff_header(s, file_diff, colored, &s->buf);
fputs(s->buf.buf, stdout);
for (;;) {
+ const char *hunk_use_decision = "";
enum {
ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,
ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,
@@ -1564,8 +1565,14 @@ static int patch_update_file(struct add_p_state *s,
(uintmax_t)(file_diff->hunk_nr
? file_diff->hunk_nr
: 1));
+ if (hunk->use != UNDECIDED_HUNK) {
+ if (hunk->use == USE_HUNK)
+ hunk_use_decision = _(" (was: y)");
+ else
+ hunk_use_decision = _(" (was: n)");
+ }
printf(_(s->mode->prompt_mode[prompt_mode_type]),
- s->buf.buf);
+ hunk_use_decision, s->buf.buf);
if (*s->s.reset_color_interactive)
fputs(s->s.reset_color_interactive, stdout);
fflush(stdout);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 4285314f35..5ce9c6dd60 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -527,7 +527,7 @@ test_expect_success 'goto hunk 1 with "g 1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +540,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -554,7 +554,7 @@ test_expect_success 'navigate to hunk via regex /pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +567,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +579,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
10
+15
20
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +595,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <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>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
@@ -810,7 +810,7 @@ test_expect_success 'colors can be overridden' '
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-01-08 15:06 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-30 15:06 [PATCH] add -p: show hunk selection state when selecting hunks Abraham Samuel Adekunle
2025-11-30 18:32 ` Junio C Hamano
2025-12-01 10:01 ` Abraham Samuel Adekunle
2026-01-01 21:04 ` [GSoC PATCH v2] add -p: show user's hunk decision " Abraham Samuel Adekunle
2026-01-01 22:54 ` Junio C Hamano
2026-01-02 7:20 ` Samuel Abraham
2026-01-02 18:51 ` [GSoC PATCH v3] " Abraham Samuel Adekunle
2026-01-04 6:03 ` Junio C Hamano
2026-01-04 10:36 ` Samuel Abraham
2026-01-04 11:02 ` [GSoC PATCH v4] " Abraham Samuel Adekunle
2026-01-05 19:35 ` SZEDER Gábor
2026-01-05 21:52 ` Samuel Abraham
2026-01-06 11:05 ` [GSoC PATCH v5] " Abraham Samuel Adekunle
2026-01-06 11:08 ` Kristoffer Haugsbakk
2026-01-06 11:46 ` Samuel Abraham
2026-01-06 12:01 ` [GSoC PATCH v6] " Abraham Samuel Adekunle
2026-01-06 16:10 ` Phillip Wood
2026-01-06 19:01 ` Ben Knoble
2026-01-07 0:13 ` Junio C Hamano
2026-01-06 22:02 ` Samuel Abraham
2026-01-06 22:19 ` Samuel Abraham
2026-01-07 8:49 ` Samuel Abraham
2026-01-08 15:07 ` [GSoC PATCH v7] " Abraham Samuel Adekunle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).