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>
Patrick Steinhardt committed
Mar 2, 2026 at 13:13 UTC
48f6d9232834be661f0d1dc4f187b324124ccbe0
7 files changed
+28
-15
add-interactive.c
+1
-1
@@ -927,7 +927,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
927
parse_pathspec(&ps_selected,
928
PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
929
PATHSPEC_LITERAL_PATH, "", args.v);
930
- res = run_add_p(s->r, ADD_P_ADD, &opts, NULL, &ps_selected);
930
+ res = run_add_p(s->r, ADD_P_ADD, &opts, NULL, &ps_selected, 0);
931
strvec_clear(&args);
932
clear_pathspec(&ps_selected);
933
}
add-patch.c
+14
-8
@@ -1604,7 +1604,9 @@ static bool get_first_undecided(const struct file_diff *file_diff, size_t *idx)
1604
return false;
1605
}
1606
1607
-static size_t patch_update_file(struct add_p_state *s, size_t idx)
1607
+static size_t patch_update_file(struct add_p_state *s,
1608
+ size_t idx,
1609
+ unsigned flags)
1610
{
1611
size_t hunk_index = 0;
1612
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)
1717
permitted |= ALLOW_SPLIT;
1718
strbuf_addstr(&s->buf, ",s");
1719
}
1718
- if (hunk_index + 1 > file_diff->mode_change &&
1720
+ if (!(flags & ADD_P_DISALLOW_EDIT) &&
1721
+ hunk_index + 1 > file_diff->mode_change &&
1722
!file_diff->deleted) {
1723
permitted |= ALLOW_EDIT;
1724
strbuf_addstr(&s->buf, ",e");
@@ -2003,7 +2006,8 @@ soft_increment:
2006
}
2007
2008
static int run_add_p_common(struct add_p_state *state,
2006
- const struct pathspec *ps)
2009
+ const struct pathspec *ps,
2010
+ unsigned flags)
2011
{
2012
size_t binary_count = 0;
2013
size_t i;
@@ -2017,7 +2021,7 @@ static int run_add_p_common(struct add_p_state *state,
2021
i++;
2022
continue;
2023
}
2020
- if ((i = patch_update_file(state, i)) == state->file_diff_nr)
2024
+ if ((i = patch_update_file(state, i, flags)) == state->file_diff_nr)
2025
break;
2026
}
2027
@@ -2035,7 +2039,8 @@ static int run_add_p_common(struct add_p_state *state,
2039
2040
int run_add_p(struct repository *r, enum add_p_mode mode,
2041
struct interactive_options *opts, const char *revision,
2038
- const struct pathspec *ps)
2042
+ const struct pathspec *ps,
2043
+ unsigned flags)
2044
{
2045
struct add_p_state s = {
2046
.r = r,
@@ -2084,7 +2089,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
2089
goto out;
2090
}
2091
2087
- ret = run_add_p_common(&s, ps);
2092
+ ret = run_add_p_common(&s, ps, flags);
2093
if (ret < 0)
2094
goto out;
2095
@@ -2100,7 +2105,8 @@ int run_add_p_index(struct repository *r,
2105
const char *index_file,
2106
struct interactive_options *opts,
2107
const char *revision,
2103
- const struct pathspec *ps)
2108
+ const struct pathspec *ps,
2109
+ unsigned flags)
2110
{
2111
struct patch_mode mode = {
2112
.apply_args = { "--cached", NULL },
@@ -2156,7 +2162,7 @@ int run_add_p_index(struct repository *r,
2162
mode.diff_cmd[1] = "-r";
2163
mode.diff_cmd[2] = parent_tree_oid;
2164
2159
- ret = run_add_p_common(&s, ps);
2165
+ ret = run_add_p_common(&s, ps, flags);
2166
if (ret < 0)
2167
goto out;
2168
add-patch.h
+9
-2
@@ -53,15 +53,22 @@ enum add_p_mode {
53
ADD_P_WORKTREE,
54
};
55
56
+enum add_p_flags {
57
+ /* Disallow "editing" hunks. */
58
+ ADD_P_DISALLOW_EDIT = (1 << 0),
59
+};
60
+
61
int run_add_p(struct repository *r, enum add_p_mode mode,
62
struct interactive_options *opts, const char *revision,
58
- const struct pathspec *ps);
63
+ const struct pathspec *ps,
64
+ unsigned flags);
65
66
int run_add_p_index(struct repository *r,
67
struct index_state *index,
68
const char *index_file,
69
struct interactive_options *opts,
70
const char *revision,
65
- const struct pathspec *ps);
71
+ const struct pathspec *ps,
72
+ unsigned flags);
73
74
#endif
builtin/add.c
+1
-1
@@ -172,7 +172,7 @@ int interactive_add(struct repository *repo,
172
prefix, argv);
173
174
if (patch)
175
- ret = !!run_add_p(repo, ADD_P_ADD, interactive_opts, NULL, &pathspec);
175
+ ret = !!run_add_p(repo, ADD_P_ADD, interactive_opts, NULL, &pathspec, 0);
176
else
177
ret = !!run_add_i(repo, &pathspec, interactive_opts);
178
builtin/checkout.c
+1
-1
@@ -563,7 +563,7 @@ static int checkout_paths(const struct checkout_opts *opts,
563
BUG("either flag must have been set, worktree=%d, index=%d",
564
opts->checkout_worktree, opts->checkout_index);
565
return !!run_add_p(the_repository, patch_mode, &interactive_opts,
566
- rev, &opts->pathspec);
566
+ rev, &opts->pathspec, 0);
567
}
568
569
repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
builtin/reset.c
+1
-1
@@ -438,7 +438,7 @@ int cmd_reset(int argc,
438
die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}");
439
trace2_cmd_mode("patch-interactive");
440
update_ref_status = !!run_add_p(the_repository, ADD_P_RESET,
441
- &interactive_opts, rev, &pathspec);
441
+ &interactive_opts, rev, &pathspec, 0);
442
goto cleanup;
443
} else {
444
if (interactive_opts.context != -1)
builtin/stash.c
+1
-1
@@ -1331,7 +1331,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
1331
old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
1332
setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
1333
1334
- ret = !!run_add_p(the_repository, ADD_P_STASH, interactive_opts, NULL, ps);
1334
+ ret = !!run_add_p(the_repository, ADD_P_STASH, interactive_opts, NULL, ps, 0);
1335
1336
the_repository->index_file = old_repo_index_file;
1337
if (old_index_env && *old_index_env)