public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Abraham Samuel Adekunle <abrahamadekunle50@gmail•com>
To: git@vger•kernel.org
Cc: "Patrick Steinhardt" <ps@pks•im>,
	"Phillip Wood" <phillip.wood123@gmail•com>,
	"SZEDER Gábor" <szeder.dev@gmail•com>,
	"Christian Couder" <christian.couder@gmail•com>,
	"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail•com>,
	"Ben Knoble" <ben.knoble@gmail•com>,
	"Junio C Hamano" <gitster@pobox•com>,
	"Karthik Nayak" <karthik.188@gmail•com>
Subject: [PATCH v3 2/3] add-patch: Allow interfile navigation when selecting hunks
Date: Fri, 6 Feb 2026 16:56:14 +0100	[thread overview]
Message-ID: <24692afa3f0a67d3f3eba776cc745287c5d71e94.1770390576.git.abrahamadekunle50@gmail.com> (raw)
In-Reply-To: <cover.1770390576.git.abrahamadekunle50@gmail.com>

After deciding on all hunks in a file, the interactive session
advances automatically to the next file if there is another,
or the process ends.

Now using the `--rework-with-file` flag with `--patch` the process does not
advance automatically. A user can choose to go to the next file by pressing
'>' or the previous file by pressing '<', before or after deciding on all
hunks in the current file.

After all hunks have been decided in a file, a prompt appears,
which allow the user to still rework with the file by applying
the options available in the permit set for that hunk, and
after all the decisions, the user presses 'q' to submit.

This feature is enabled by passing the `--rework-with-file` flag
to `--patch` option of the subcommands add, stash, reset,
and checkout

Signed-off-by: Abraham Samuel Adekunle <abrahamadekunle50@gmail•com>
---
 add-patch.c | 95 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 80 insertions(+), 15 deletions(-)

diff --git a/add-patch.c b/add-patch.c
index 173a53241e..2bd839f17e 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -1418,6 +1418,8 @@ N_("j - go to the next undecided hunk, roll over at the bottom\n"
    "e - manually edit the current hunk\n"
    "p - print the current hunk\n"
    "P - print the current hunk using the pager\n"
+   "> - go to the next file\n"
+   "< - go to the previous file\n"
    "? - print help\n");
 
 static size_t dec_mod(size_t a, size_t m)
@@ -1430,6 +1432,12 @@ static size_t inc_mod(size_t a, size_t m)
 	return a < m - 1 ? a + 1 : 0;
 }
 
+enum patch_update_response {
+	NEXT_FILE = 0,
+	QUIT,
+	PREVIOUS_FILE,
+};
+
 static bool get_first_undecided(const struct file_diff *file_diff, size_t *idx)
 {
 	for (size_t i = 0; i < file_diff->hunk_nr; i++) {
@@ -1441,7 +1449,7 @@ static bool get_first_undecided(const struct file_diff *file_diff, size_t *idx)
 	return false;
 }
 
-static int patch_update_file(struct add_p_state *s,
+static enum patch_update_response patch_update_file(struct add_p_state *s,
 			     struct file_diff *file_diff)
 {
 	size_t hunk_index = 0;
@@ -1449,12 +1457,14 @@ static int patch_update_file(struct add_p_state *s,
 	struct hunk *hunk;
 	char ch;
 	struct child_process cp = CHILD_PROCESS_INIT;
-	int colored = !!s->colored.len, quit = 0, use_pager = 0;
+	int colored = !!s->colored.len, use_pager = 0;
 	enum prompt_mode_type prompt_mode_type;
+	int all_decided = 0;
+	enum patch_update_response ret = NEXT_FILE;
 
 	/* Empty added files have no hunks */
 	if (!file_diff->hunk_nr && !file_diff->added)
-		return 0;
+		return NEXT_FILE;
 
 	strbuf_reset(&s->buf);
 	render_diff_header(s, file_diff, colored, &s->buf);
@@ -1467,7 +1477,9 @@ static int patch_update_file(struct add_p_state *s,
 			ALLOW_GOTO_NEXT_UNDECIDED_HUNK = 1 << 3,
 			ALLOW_SEARCH_AND_GOTO = 1 << 4,
 			ALLOW_SPLIT = 1 << 5,
-			ALLOW_EDIT = 1 << 6
+			ALLOW_EDIT = 1 << 6,
+			ALLOW_GOTO_PREVIOUS_FILE = 1 << 7,
+			ALLOW_GOTO_NEXT_FILE = 1 << 8
 		} permitted = 0;
 
 		if (hunk_index >= file_diff->hunk_nr)
@@ -1498,9 +1510,12 @@ static int patch_update_file(struct add_p_state *s,
 
 		/* Everything decided? */
 		if (undecided_previous < 0 && undecided_next < 0 &&
-		    hunk->use != UNDECIDED_HUNK)
-			break;
-
+		    hunk->use != UNDECIDED_HUNK) {
+				if (s->s.no_auto_advance)
+					all_decided = 1;
+				else
+					break;
+			}
 		strbuf_reset(&s->buf);
 		if (file_diff->hunk_nr) {
 			if (rendered_hunk_index != hunk_index) {
@@ -1548,6 +1563,14 @@ static int patch_update_file(struct add_p_state *s,
 				permitted |= ALLOW_EDIT;
 				strbuf_addstr(&s->buf, ",e");
 			}
+			if (s->s.no_auto_advance && s->file_diff_nr > 1) {
+				permitted |= ALLOW_GOTO_NEXT_FILE;
+				strbuf_addstr(&s->buf, ",>");
+			}
+			if (s->s.no_auto_advance && s->file_diff_nr > 1) {
+				permitted |= ALLOW_GOTO_PREVIOUS_FILE;
+				strbuf_addstr(&s->buf, ",<");
+			}
 			strbuf_addstr(&s->buf, ",p,P");
 		}
 		if (file_diff->deleted)
@@ -1566,11 +1589,14 @@ static int patch_update_file(struct add_p_state *s,
 						: 1));
 		printf(_(s->mode->prompt_mode[prompt_mode_type]),
 		       s->buf.buf);
+		if (s->s.no_auto_advance && all_decided)
+			printf(_("\n%s All hunks decided. What now? "),
+				s->s.prompt_color);
 		if (*s->s.reset_color_interactive)
 			fputs(s->s.reset_color_interactive, stdout);
 		fflush(stdout);
 		if (read_single_character(s) == EOF) {
-			quit = 1;
+			ret = QUIT;
 			break;
 		}
 
@@ -1616,9 +1642,26 @@ static int patch_update_file(struct add_p_state *s,
 				hunk->use = SKIP_HUNK;
 			}
 		} else if (ch == 'q') {
-			quit = 1;
+			ret = QUIT;
 			break;
-		} else if (s->answer.buf[0] == 'K') {
+		} else if (s->s.no_auto_advance && s->answer.buf[0] == '>') {
+			if (permitted & ALLOW_GOTO_NEXT_FILE) {
+				ret = NEXT_FILE;
+				break;
+			} else {
+				err(s, _("No next file"));
+				continue;
+			}
+		} else if (s->s.no_auto_advance && s->answer.buf[0] == '<') {
+			if (permitted & ALLOW_GOTO_PREVIOUS_FILE) {
+				ret = PREVIOUS_FILE;
+				break;
+			} else {
+				err(s, _("No previous file"));
+				continue;
+			}
+		}
+		else if (s->answer.buf[0] == 'K') {
 			if (permitted & ALLOW_GOTO_PREVIOUS_HUNK)
 				hunk_index = dec_mod(hunk_index,
 						     file_diff->hunk_nr);
@@ -1803,7 +1846,7 @@ static int patch_update_file(struct add_p_state *s,
 	}
 
 	putchar('\n');
-	return quit;
+	return ret;
 }
 
 int run_add_p(struct repository *r, enum add_p_mode mode,
@@ -1814,6 +1857,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 		{ r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
 	};
 	size_t i, binary_count = 0;
+	enum patch_update_response ret;
 
 	init_add_i_state(&s.s, r, o);
 
@@ -1852,11 +1896,32 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 		return -1;
 	}
 
-	for (i = 0; i < s.file_diff_nr; i++)
-		if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr)
+	for (i = 0; i < s.file_diff_nr;) {
+		if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr) {
 			binary_count++;
-		else if (patch_update_file(&s, s.file_diff + i))
-			break;
+			i++;
+			continue;
+		}
+		else {
+			ret = patch_update_file(&s, s.file_diff + i);
+			if (ret == NEXT_FILE) {
+				if (s.s.no_auto_advance && i == s.file_diff_nr - 1)
+					i = 0;
+				else
+					i++;
+				continue;
+			}
+			if (ret == QUIT)
+				break;
+			if (s.s.no_auto_advance && ret == PREVIOUS_FILE) {
+				if (i == 0)
+					i = s.file_diff_nr - 1;
+				else
+					i--;
+				continue;
+			}
+		}
+    }
 
 	if (s.file_diff_nr == 0)
 		err(&s, _("No changes."));
-- 
2.39.5 (Apple Git-154)


  parent reply	other threads:[~2026-02-06 15:56 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-23 11:56 [RFC PATCH 0/1] add-patch: Allow reworking with a file after deciding on its hunks Abraham Samuel Adekunle
2026-01-23 11:58 ` [RFC PATCH 1/1] add-patch: Allow reworking with a file after deciding on all " Abraham Samuel Adekunle
2026-01-23 16:38   ` Junio C Hamano
2026-01-23 21:43     ` Samuel Abraham
2026-01-27 15:43 ` [PATCH v2 0/1] Allow reworking with a file when making hunk decisions Abraham Samuel Adekunle
2026-01-27 15:45   ` [PATCH v2 1/1] Allow reworking with a file after deciding on all its hunks Abraham Samuel Adekunle
2026-01-27 20:48     ` Junio C Hamano
2026-01-28 11:26       ` Samuel Abraham
2026-01-30  9:22         ` Samuel Abraham
2026-01-30 16:29           ` Junio C Hamano
2026-01-30 17:36             ` Samuel Abraham
2026-01-31 19:25           ` Junio C Hamano
2026-02-02 11:14             ` Samuel Abraham
2026-02-02 17:26               ` Junio C Hamano
2026-02-03  9:55                 ` Samuel Abraham
2026-01-27 17:04   ` [PATCH v2 0/1] Allow reworking with a file when making hunk decisions Junio C Hamano
2026-01-28  9:49     ` Samuel Abraham
2026-02-06 15:52   ` [PATCH v3 0/3] introduce new option `rework-with-file` Abraham Samuel Adekunle
2026-02-06 15:54     ` [PATCH v3 1/3] interactive -p: add new `--rework-with-file` flag to interactive machinery Abraham Samuel Adekunle
2026-02-06 18:25       ` Junio C Hamano
2026-02-06 20:21         ` Samuel Abraham
2026-02-06 15:56     ` Abraham Samuel Adekunle [this message]
2026-02-06 18:35       ` [PATCH v3 2/3] add-patch: Allow interfile navigation when selecting hunks Junio C Hamano
2026-02-06 20:22         ` Samuel Abraham
2026-02-06 18:54       ` Junio C Hamano
2026-02-06 20:32         ` Samuel Abraham
2026-02-06 19:21       ` Junio C Hamano
2026-02-06 20:37         ` Samuel Abraham
2026-02-12 10:32         ` Samuel Abraham
2026-02-12 17:25           ` Junio C Hamano
2026-02-12 21:13             ` Samuel Abraham
2026-02-12 21:31               ` Junio C Hamano
2026-02-12 22:20                 ` Samuel Abraham
2026-02-06 15:57     ` [PATCH v3 3/3] add-patch: Allow proper 'git apply' when using the --rework-with-file flag Abraham Samuel Adekunle
2026-02-06 19:02       ` Junio C Hamano
2026-02-06 20:39         ` Samuel Abraham
2026-02-06 19:19     ` [PATCH v3 0/3] introduce new option `rework-with-file` Junio C Hamano
2026-02-06 20:40       ` Samuel Abraham
2026-02-13 22:08     ` [PATCH v4 0/4] introduce new option `--auto-advance` Abraham Samuel Adekunle
2026-02-13 22:09       ` [PATCH v4 1/4] interactive -p: add new `--auto-advance` flag Abraham Samuel Adekunle
2026-02-13 23:04         ` Junio C Hamano
2026-02-14  9:16           ` Samuel Abraham
2026-02-13 22:10       ` [PATCH v4 2/4] add-patch: modify patch_update_file() signature Abraham Samuel Adekunle
2026-02-13 23:33         ` Junio C Hamano
2026-02-14 10:14           ` Samuel Abraham
2026-02-13 22:11       ` [PATCH v4 3/4] add-patch: allow all-or-none application of patches Abraham Samuel Adekunle
2026-02-13 22:12       ` [PATCH v4 4/4] add-patch: allow interfile navigation when selecting hunks Abraham Samuel Adekunle
2026-02-14 11:01       ` [PATCH v5 0/4] introduce new option `--auto-advance` Abraham Samuel Adekunle
2026-02-14 11:03         ` [PATCH v5 1/4] interactive -p: add new `--auto-advance` flag Abraham Samuel Adekunle
2026-02-14 11:04         ` [PATCH v5 2/4] add-patch: modify patch_update_file() signature Abraham Samuel Adekunle
2026-02-14 11:06         ` [PATCH v5 3/4] add-patch: allow all-or-none application of patches Abraham Samuel Adekunle
2026-02-14 11:06         ` [PATCH v5 4/4] add-patch: allow interfile navigation when selecting hunks Abraham Samuel Adekunle
2026-02-20 22:32         ` [PATCH v5 0/4] introduce new option `--auto-advance` Junio C Hamano
2026-02-21  9:06           ` Samuel Abraham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=24692afa3f0a67d3f3eba776cc745287c5d71e94.1770390576.git.abrahamadekunle50@gmail.com \
    --to=abrahamadekunle50@gmail$(echo .)com \
    --cc=ben.knoble@gmail$(echo .)com \
    --cc=christian.couder@gmail$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=gitster@pobox$(echo .)com \
    --cc=karthik.188@gmail$(echo .)com \
    --cc=kristofferhaugsbakk@fastmail$(echo .)com \
    --cc=phillip.wood123@gmail$(echo .)com \
    --cc=ps@pks$(echo .)im \
    --cc=szeder.dev@gmail$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox