From 66c14ab592f0226168a7411184c2e3ffc05e30b8 Mon Sep 17 00:00:00 2001 From: Rubén Justo Date: Fri, 29 Mar 2024 04:58:28 +0100 Subject: add-patch: introduce 'p' in interactive-patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shortly we're going make interactive-patch stop printing automatically the hunk under certain circumstances. Let's introduce a new option to allow the user to explicitly request the printing. Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- Documentation/git-add.txt | 1 + add-patch.c | 4 ++++ t/t3701-add-interactive.sh | 22 +++++++++++----------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 14a371fff3..aceaa025e3 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -348,6 +348,7 @@ patch:: K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk + p - print the current hunk ? - print help + After deciding the fate for all hunks, if there is any hunk diff --git a/add-patch.c b/add-patch.c index 68f525b35c..b5d3a3f0cc 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1388,6 +1388,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" + "p - print the current hunk\n" "? - print help\n"); static int patch_update_file(struct add_p_state *s, @@ -1480,6 +1481,7 @@ static int patch_update_file(struct add_p_state *s, permitted |= ALLOW_EDIT; strbuf_addstr(&s->buf, ",e"); } + strbuf_addstr(&s->buf, ",p"); } if (file_diff->deleted) prompt_mode_type = PROMPT_DELETION; @@ -1658,6 +1660,8 @@ soft_increment: hunk->use = USE_HUNK; goto soft_increment; } + } else if (s->answer.buf[0] == 'p') { + /* nothing special is needed */ } else { const char *p = _(help_patch_remainder), *eol = p; diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 0b5339ac6c..bc55255b0a 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -325,9 +325,9 @@ test_expect_success 'different prompts for mode change/deleted' ' git -c core.filemode=true add -p >actual && sed -n "s/^\(([0-9/]*) Stage .*?\).*/\1/p" actual >actual.filtered && cat >expect <<-\EOF && - (1/1) Stage deletion [y,n,q,a,d,?]? - (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,?]? - (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + (1/1) Stage deletion [y,n,q,a,d,p,?]? + (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,p,?]? + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? EOF test_cmp expect actual.filtered ' @@ -514,13 +514,13 @@ test_expect_success 'split hunk setup' ' test_expect_success 'goto hunk' ' test_when_finished "git reset" && tr _ " " >expect <<-EOF && - (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + 1: -1,2 +1,3 +15 + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? + 1: -1,2 +1,3 +15 _ 2: -2,4 +3,8 +21 go to which hunk? @@ -1,2 +1,3 @@ _10 +15 _20 - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_ + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_ EOF test_write_lines s y g 1 | git add -p >actual && tail -n 7 actual.trimmed && @@ -530,11 +530,11 @@ test_expect_success 'goto hunk' ' test_expect_success 'navigate to hunk via regex' ' test_when_finished "git reset" && tr _ " " >expect <<-EOF && - (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,2 +1,3 @@ + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? @@ -1,2 +1,3 @@ _10 +15 _20 - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_ + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]?_ EOF test_write_lines s y /1,2 | git add -p >actual && tail -n 5 actual.trimmed && @@ -715,21 +715,21 @@ test_expect_success 'colors can be overridden' ' +new more-context +another-one - (1/1) Stage this hunk [y,n,q,a,d,s,e,?]? Split into 2 hunks. + (1/1) Stage this hunk [y,n,q,a,d,s,e,p,?]? Split into 2 hunks. @@ -1,3 +1,3 @@ context -old +new more-context - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? @@ -3 +3,2 @@ + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? @@ -3 +3,2 @@ more-context +another-one - (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,3 +1,3 @@ + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,p,?]? @@ -1,3 +1,3 @@ context -old +new more-context - (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? EOF test_cmp expect actual ' -- cgit 1.2.3-korg From bab1f1c3948bddc4bc35d9ce1cb33d9ce84446cb Mon Sep 17 00:00:00 2001 From: Rubén Justo Date: Fri, 29 Mar 2024 04:58:52 +0100 Subject: add-patch: do not print hunks repeatedly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The interactive-patch is a sequential process where, on each step, we print one hunk from a patch and then ask the user how to proceed. There is a possibility of repeating a step, for example if the user enters a non-applicable option, i.e: "s" $ git add -p diff --git a/add-patch.c b/add-patch.c index 52be1ddb15..8fb75e82e2 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1394,7 +1394,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n" static int patch_update_file(struct add_p_state *s, struct file_diff *file_diff) { - size_t hunk_index = 0; + size_t hunk_index = 0, prev_hunk_index = -1; ssize_t i, undecided_previous, undecided_next; struct hunk *hunk; char ch; (1/4) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? s Sorry, cannot split this hunk @@ -1394,7 +1394,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n" static int patch_update_file(struct add_p_state *s, struct file_diff *file_diff) { - size_t hunk_index = 0; + size_t hunk_index = 0, prev_hunk_index = -1; ssize_t i, undecided_previous, undecided_next; struct hunk *hunk; char ch; (1/4) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? ... or an invalid option, i.e: "U" $ git add -p diff --git a/add-patch.c b/add-patch.c index 52be1ddb15..8fb75e82e2 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1394,7 +1394,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n" static int patch_update_file(struct add_p_state *s, struct file_diff *file_diff) { - size_t hunk_index = 0; + size_t hunk_index = 0, prev_hunk_index = -1; ssize_t i, undecided_previous, undecided_next; struct hunk *hunk; char ch; (1/4) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? U y - stage this hunk n - do not stage this hunk q - quit; do not stage this hunk or any of the remaining ones a - stage this hunk and all later hunks in the file d - do not stage this hunk or any of the later hunks in the file j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk g - select a hunk to go to / - search for a hunk matching the given regex e - manually edit the current hunk p - print again the current hunk ? - print help @@ -1394,7 +1394,7 @@ N_("j - leave this hunk undecided, see next undecided hunk\n" static int patch_update_file(struct add_p_state *s, struct file_diff *file_diff) { - size_t hunk_index = 0; + size_t hunk_index = 0, prev_hunk_index = -1; ssize_t i, undecided_previous, undecided_next; struct hunk *hunk; char ch; (1/4) Stage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? Printing the chunk again followed by the question can be confusing as the user has to pay special attention to notice that the same chunk is being reconsidered. It can also be problematic if the chunk is longer than one screen height because the result of the previous iteration is lost off the screen (the help guide in the previous example). To avoid such problems, stop printing the chunk if the iteration does not advance to a different chunk. Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- add-patch.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/add-patch.c b/add-patch.c index b5d3a3f0cc..778f168298 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1395,7 +1395,7 @@ static int patch_update_file(struct add_p_state *s, struct file_diff *file_diff) { size_t hunk_index = 0; - ssize_t i, undecided_previous, undecided_next; + ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1; struct hunk *hunk; char ch; struct child_process cp = CHILD_PROCESS_INIT; @@ -1448,8 +1448,11 @@ static int patch_update_file(struct add_p_state *s, strbuf_reset(&s->buf); if (file_diff->hunk_nr) { - render_hunk(s, hunk, 0, colored, &s->buf); - fputs(s->buf.buf, stdout); + if (rendered_hunk_index != hunk_index) { + render_hunk(s, hunk, 0, colored, &s->buf); + fputs(s->buf.buf, stdout); + rendered_hunk_index = hunk_index; + } strbuf_reset(&s->buf); if (undecided_previous >= 0) { @@ -1646,13 +1649,15 @@ soft_increment: hunk_index = i; } else if (s->answer.buf[0] == 's') { size_t splittable_into = hunk->splittable_into; - if (!(permitted & ALLOW_SPLIT)) + if (!(permitted & ALLOW_SPLIT)) { err(s, _("Sorry, cannot split this hunk")); - else if (!split_hunk(s, file_diff, - hunk - file_diff->hunk)) + } else if (!split_hunk(s, file_diff, + hunk - file_diff->hunk)) { color_fprintf_ln(stdout, s->s.header_color, _("Split into %d hunks."), (int)splittable_into); + rendered_hunk_index = -1; + } } else if (s->answer.buf[0] == 'e') { if (!(permitted & ALLOW_EDIT)) err(s, _("Sorry, cannot edit this hunk")); @@ -1661,7 +1666,7 @@ soft_increment: goto soft_increment; } } else if (s->answer.buf[0] == 'p') { - /* nothing special is needed */ + rendered_hunk_index = -1; } else { const char *p = _(help_patch_remainder), *eol = p; -- cgit 1.2.3-korg