git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 17:28 UTC

[PATCH 5/8] add-patch: allow disabling editing of hunks

From
Patrick Steinhardt <ps@pks.im>
Date
Mar 2, 2026, 12:13 UTC
Message-ID
<20260302-pks-history-split-v1-5-444fc987a324@pks.im>
In-Reply-To
<20260302-pks-history-split-v1-0-444fc987a324@pks.im>

The "add-patch" mode allows the user to edit hunks to apply custom changes. This is incompatible with a new `git history split` command that we're about to introduce in a subsequent commit, so we need a way to disable this mode.

Add a new flag to disable editing hunks.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 add-interactive.c  |  2 +-
 add-patch.c        | 22 ++++++++++++++--------
 add-patch.h        | 11 +++++++++--
 builtin/add.c      |  2 +-
 builtin/checkout.c |  2 +-
 builtin/reset.c    |  2 +-
 builtin/stash.c    |  2 +-
 7 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/add-interactive.c b/add-interactive.c
index 152e2a0297..3cf8a1dbf8 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -927,7 +927,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
 		parse_pathspec(&ps_selected,
 			       PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
 			       PATHSPEC_LITERAL_PATH, "", args.v);
-		res = run_add_p(s->r, ADD_P_ADD, &opts, NULL, &ps_selected);
+		res = run_add_p(s->r, ADD_P_ADD, &opts, NULL, &ps_selected, 0);
 		strvec_clear(&args);
 		clear_pathspec(&ps_selected);
 	}
diff --git a/add-patch.c b/add-patch.c
index b4dc7d2293..4e28e5c187 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -1604,7 +1604,9 @@ static bool get_first_undecided(const struct file_diff *file_diff, size_t *idx)
 	return false;
 }
 
-static size_t patch_update_file(struct add_p_state *s, size_t idx)
+static size_t patch_update_file(struct add_p_state *s,
+				size_t idx,
+				unsigned flags)
 {
 	size_t hunk_index = 0;
 	ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
@@ -1715,7 +1717,8 @@ static size_t patch_update_file(struct add_p_state *s, size_t idx)
 				permitted |= ALLOW_SPLIT;
 				strbuf_addstr(&s->buf, ",s");
 			}
-			if (hunk_index + 1 > file_diff->mode_change &&
+			if (!(flags & ADD_P_DISALLOW_EDIT) &&
+			    hunk_index + 1 > file_diff->mode_change &&
 			    !file_diff->deleted) {
 				permitted |= ALLOW_EDIT;
 				strbuf_addstr(&s->buf, ",e");
@@ -2003,7 +2006,8 @@ static size_t patch_update_file(struct add_p_state *s, size_t idx)
 }
 
 static int run_add_p_common(struct add_p_state *state,
-			    const struct pathspec *ps)
+			    const struct pathspec *ps,
+			    unsigned flags)
 {
 	size_t binary_count = 0;
 	size_t i;
@@ -2017,7 +2021,7 @@ static int run_add_p_common(struct add_p_state *state,
 			i++;
 			continue;
 		}
-		if ((i = patch_update_file(state, i)) == state->file_diff_nr)
+		if ((i = patch_update_file(state, i, flags)) == state->file_diff_nr)
 			break;
 	}
 
@@ -2035,7 +2039,8 @@ static int run_add_p_common(struct add_p_state *state,
 
 int run_add_p(struct repository *r, enum add_p_mode mode,
 	      struct interactive_options *opts, const char *revision,
-	      const struct pathspec *ps)
+	      const struct pathspec *ps,
+	      unsigned flags)
 {
 	struct add_p_state s = {
 		.r = r,
@@ -2084,7 +2089,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 		goto out;
 	}
 
-	ret = run_add_p_common(&s, ps);
+	ret = run_add_p_common(&s, ps, flags);
 	if (ret < 0)
 		goto out;
 
@@ -2100,7 +2105,8 @@ int run_add_p_index(struct repository *r,
 		    const char *index_file,
 		    struct interactive_options *opts,
 		    const char *revision,
-		    const struct pathspec *ps)
+		    const struct pathspec *ps,
+		    unsigned flags)
 {
 	struct patch_mode mode = {
 		.apply_args = { "--cached", NULL },
@@ -2156,7 +2162,7 @@ int run_add_p_index(struct repository *r,
 	mode.diff_cmd[1] = "-r";
 	mode.diff_cmd[2] = parent_tree_oid;
 
-	ret = run_add_p_common(&s, ps);
+	ret = run_add_p_common(&s, ps, flags);
 	if (ret < 0)
 		goto out;
 
diff --git a/add-patch.h b/add-patch.h
index cf2a31a40f..fb6d975b68 100644
--- a/add-patch.h
+++ b/add-patch.h
@@ -53,15 +53,22 @@ enum add_p_mode {
 	ADD_P_WORKTREE,
 };
 
+enum add_p_flags {
+	/* Disallow "editing" hunks. */
+	ADD_P_DISALLOW_EDIT = (1 << 0),
+};
+
 int run_add_p(struct repository *r, enum add_p_mode mode,
 	      struct interactive_options *opts, const char *revision,
-	      const struct pathspec *ps);
+	      const struct pathspec *ps,
+	      unsigned flags);
 
 int run_add_p_index(struct repository *r,
 		    struct index_state *index,
 		    const char *index_file,
 		    struct interactive_options *opts,
 		    const char *revision,
-		    const struct pathspec *ps);
+		    const struct pathspec *ps,
+		    unsigned flags);
 
 #endif
diff --git a/builtin/add.c b/builtin/add.c
index 84f9bcb789..eeab779328 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -172,7 +172,7 @@ int interactive_add(struct repository *repo,
 		       prefix, argv);
 
 	if (patch)
-		ret = !!run_add_p(repo, ADD_P_ADD, interactive_opts, NULL, &pathspec);
+		ret = !!run_add_p(repo, ADD_P_ADD, interactive_opts, NULL, &pathspec, 0);
 	else
 		ret = !!run_add_i(repo, &pathspec, interactive_opts);
 
diff --git a/builtin/checkout.c b/builtin/checkout.c
index bebe18c1d9..a8863277f2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -563,7 +563,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 			BUG("either flag must have been set, worktree=%d, index=%d",
 			    opts->checkout_worktree, opts->checkout_index);
 		return !!run_add_p(the_repository, patch_mode, &interactive_opts,
-				   rev, &opts->pathspec);
+				   rev, &opts->pathspec, 0);
 	}
 
 	repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
diff --git a/builtin/reset.c b/builtin/reset.c
index 4a74a82c0a..3590be57a5 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -438,7 +438,7 @@ int cmd_reset(int argc,
 			die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}");
 		trace2_cmd_mode("patch-interactive");
 		update_ref_status = !!run_add_p(the_repository, ADD_P_RESET,
-						&interactive_opts, rev, &pathspec);
+						&interactive_opts, rev, &pathspec, 0);
 		goto cleanup;
 	} else {
 		if (interactive_opts.context != -1)
diff --git a/builtin/stash.c b/builtin/stash.c
index c467c02c7f..7c68a1d7f9 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1331,7 +1331,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
 	old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
 	setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
 
-	ret = !!run_add_p(the_repository, ADD_P_STASH, interactive_opts, NULL, ps);
+	ret = !!run_add_p(the_repository, ADD_P_STASH, interactive_opts, NULL, ps, 0);
 
 	the_repository->index_file = old_repo_index_file;
 	if (old_index_env && *old_index_env)
-- 
2.53.0.697.g625c4fb2da.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 6 of 16 in “history: introduce "split" subcommand”
  1. 0/8 history: introduce "split" subcommandPatrick Steinhardt, Mar 2, 2026
  2. 1/8 add-patch: split out header from "add-interactive.h"Patrick Steinhardt, Mar 2, 2026
  3. 2/8 add-patch: split out `struct interactive_options`Patrick Steinhardt, Mar 2, 2026
  4. 3/8 add-patch: remove dependency on "add-interactive" subsystemPatrick Steinhardt, Mar 2, 2026
  5. 4/8 add-patch: add support for in-memory index patchingPatrick Steinhardt, Mar 2, 2026
  6. 5/8 add-patch: allow disabling editing of hunksPatrick Steinhardt, Mar 2, 2026
  7. 6/8 cache-tree: allow writing in-memory index as treePatrick Steinhardt, Mar 2, 2026
  8. 7/8 builtin/history: split out extended function to create commitsPatrick Steinhardt, Mar 2, 2026
  9. 8/8 builtin/history: implement "split" subcommandPatrick Steinhardt, Mar 2, 2026
  10. D. Ben KnobleMar 3, 2026
  11. D. Ben KnobleMar 3, 2026
  12. D. Ben KnobleMar 3, 2026
  13. Patrick SteinhardtMar 11, 2026
  14. Patrick SteinhardtMar 11, 2026
  15. Junio C HamanoMar 13, 2026
  16. Patrick SteinhardtMar 16, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.