add-patch: allow disabling editing of hunks

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Patrick Steinhardt 2026-03-02 13:13:09 +01:00 committed by Junio C Hamano
parent 0c5583a57d
commit 48f6d92328
7 changed files with 28 additions and 15 deletions

View File

@ -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);
}

View File

@ -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 @@ soft_increment:
}

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;


View File

@ -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

View File

@ -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);


View File

@ -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);

View File

@ -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)

View File

@ -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)