зеркало из https://github.com/microsoft/git.git
Merge branch 'other-command-p-in-c'
At this stage on the journey to a fully built-in `git add`, we already have everything we need, including the `--interactive` and `--patch` options, as long as the `add.interactive.useBuiltin` setting is set to `true` (kind of a "turned off feature flag", which it will be for a while, until we get confident enough that the built-in version does the job, and retire the Perl script). However, the internal `add--interactive` helper is also used to back the `--patch` option of `git stash`, `git reset` and `git checkout`. This patch series brings them "online". Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Коммит
8af7a2842b
|
@ -846,7 +846,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.argv);
|
||||
res = run_add_p(s->r, &ps_selected);
|
||||
res = run_add_p(s->r, ADD_P_STAGE, NULL, &ps_selected);
|
||||
argv_array_clear(&args);
|
||||
clear_pathspec(&ps_selected);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,15 @@ const char *get_add_i_color(enum color_add_i ix);
|
|||
struct repository;
|
||||
struct pathspec;
|
||||
int run_add_i(struct repository *r, const struct pathspec *ps);
|
||||
int run_add_p(struct repository *r, const struct pathspec *ps);
|
||||
|
||||
enum add_p_mode {
|
||||
ADD_P_STAGE,
|
||||
ADD_P_STASH,
|
||||
ADD_P_RESET,
|
||||
ADD_P_CHECKOUT,
|
||||
};
|
||||
|
||||
int run_add_p(struct repository *r, enum add_p_mode mode,
|
||||
const char *revision, const struct pathspec *ps);
|
||||
|
||||
#endif
|
||||
|
|
286
add-patch.c
286
add-patch.c
|
@ -11,10 +11,165 @@ enum prompt_mode_type {
|
|||
PROMPT_MODE_CHANGE = 0, PROMPT_DELETION, PROMPT_HUNK
|
||||
};
|
||||
|
||||
static const char *prompt_mode[] = {
|
||||
N_("Stage mode change [y,n,a,q,d%s,?]? "),
|
||||
N_("Stage deletion [y,n,a,q,d%s,?]? "),
|
||||
N_("Stage this hunk [y,n,a,q,d%s,?]? ")
|
||||
struct patch_mode {
|
||||
const char *diff[4], *apply[4], *apply_check[4];
|
||||
unsigned is_reverse:1, apply_for_checkout:1;
|
||||
const char *prompt_mode[PROMPT_HUNK + 1];
|
||||
const char *edit_hunk_hint, *help_patch_text;
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_stage = {
|
||||
.diff = { "diff-files", NULL },
|
||||
.apply = { "--cached", NULL },
|
||||
.apply_check = { "--cached", NULL },
|
||||
.is_reverse = 0,
|
||||
.prompt_mode = {
|
||||
N_("Stage mode change [y,n,q,a,d%s,?]? "),
|
||||
N_("Stage deletion [y,n,q,a,d%s,?]? "),
|
||||
N_("Stage this hunk [y,n,q,a,d%s,?]? ")
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for staging."),
|
||||
.help_patch_text =
|
||||
N_("y - stage this hunk\n"
|
||||
"n - do not stage this hunk\n"
|
||||
"q - quit; do not stage this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - stage this hunk and all later hunks in the file\n"
|
||||
"d - do not stage this hunk or any of the later hunks in "
|
||||
"the file\n")
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_stash = {
|
||||
.diff = { "diff-index", "HEAD", NULL },
|
||||
.apply = { "--cached", NULL },
|
||||
.apply_check = { "--cached", NULL },
|
||||
.is_reverse = 0,
|
||||
.prompt_mode = {
|
||||
N_("Stash mode change [y,n,q,a,d%s,?]? "),
|
||||
N_("Stash deletion [y,n,q,a,d%s,?]? "),
|
||||
N_("Stash this hunk [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for stashing."),
|
||||
.help_patch_text =
|
||||
N_("y - stash this hunk\n"
|
||||
"n - do not stash this hunk\n"
|
||||
"q - quit; do not stash this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - stash this hunk and all later hunks in the file\n"
|
||||
"d - do not stash this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_reset_head = {
|
||||
.diff = { "diff-index", "--cached", NULL },
|
||||
.apply = { "-R", "--cached", NULL },
|
||||
.apply_check = { "-R", "--cached", NULL },
|
||||
.is_reverse = 1,
|
||||
.prompt_mode = {
|
||||
N_("Unstage mode change [y,n,q,a,d%s,?]? "),
|
||||
N_("Unstage deletion [y,n,q,a,d%s,?]? "),
|
||||
N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for unstaging."),
|
||||
.help_patch_text =
|
||||
N_("y - unstage this hunk\n"
|
||||
"n - do not unstage this hunk\n"
|
||||
"q - quit; do not unstage this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - unstage this hunk and all later hunks in the file\n"
|
||||
"d - do not unstage this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_reset_nothead = {
|
||||
.diff = { "diff-index", "-R", "--cached", NULL },
|
||||
.apply = { "--cached", NULL },
|
||||
.apply_check = { "--cached", NULL },
|
||||
.is_reverse = 0,
|
||||
.prompt_mode = {
|
||||
N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
|
||||
N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
|
||||
N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for applying."),
|
||||
.help_patch_text =
|
||||
N_("y - apply this hunk to index\n"
|
||||
"n - do not apply this hunk to index\n"
|
||||
"q - quit; do not apply this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - apply this hunk and all later hunks in the file\n"
|
||||
"d - do not apply this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_checkout_index = {
|
||||
.diff = { "diff-files", NULL },
|
||||
.apply = { "-R", NULL },
|
||||
.apply_check = { "-R", NULL },
|
||||
.is_reverse = 1,
|
||||
.prompt_mode = {
|
||||
N_("Discard mode change from worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Discard deletion from worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Discard this hunk from worktree [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for discarding."),
|
||||
.help_patch_text =
|
||||
N_("y - discard this hunk from worktree\n"
|
||||
"n - do not discard this hunk from worktree\n"
|
||||
"q - quit; do not discard this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - discard this hunk and all later hunks in the file\n"
|
||||
"d - do not discard this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_checkout_head = {
|
||||
.diff = { "diff-index", NULL },
|
||||
.apply_for_checkout = 1,
|
||||
.apply_check = { "-R", NULL },
|
||||
.is_reverse = 1,
|
||||
.prompt_mode = {
|
||||
N_("Discard mode change from index and worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Discard deletion from index and worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for discarding."),
|
||||
.help_patch_text =
|
||||
N_("y - discard this hunk from index and worktree\n"
|
||||
"n - do not discard this hunk from index and worktree\n"
|
||||
"q - quit; do not discard this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - discard this hunk and all later hunks in the file\n"
|
||||
"d - do not discard this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
static struct patch_mode patch_mode_checkout_nothead = {
|
||||
.diff = { "diff-index", "-R", NULL },
|
||||
.apply_for_checkout = 1,
|
||||
.apply_check = { NULL },
|
||||
.is_reverse = 0,
|
||||
.prompt_mode = {
|
||||
N_("Apply mode change to index and worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Apply deletion to index and worktree [y,n,q,a,d%s,?]? "),
|
||||
N_("Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "),
|
||||
},
|
||||
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be marked for applying."),
|
||||
.help_patch_text =
|
||||
N_("y - apply this hunk to index and worktree\n"
|
||||
"n - do not apply this hunk to index and worktree\n"
|
||||
"q - quit; do not apply this hunk or any of the remaining "
|
||||
"ones\n"
|
||||
"a - apply this hunk and all later hunks in the file\n"
|
||||
"d - do not apply this hunk or any of the later hunks in "
|
||||
"the file\n"),
|
||||
};
|
||||
|
||||
struct hunk_header {
|
||||
|
@ -47,6 +202,10 @@ struct add_p_state {
|
|||
unsigned deleted:1, mode_change:1,binary:1;
|
||||
} *file_diff;
|
||||
size_t file_diff_nr;
|
||||
|
||||
/* patch mode */
|
||||
struct patch_mode *mode;
|
||||
const char *revision;
|
||||
};
|
||||
|
||||
static void err(struct add_p_state *s, const char *fmt, ...)
|
||||
|
@ -159,9 +318,18 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
|
|||
struct hunk *hunk = NULL;
|
||||
int res;
|
||||
|
||||
argv_array_pushv(&args, s->mode->diff);
|
||||
if (s->revision) {
|
||||
struct object_id oid;
|
||||
argv_array_push(&args,
|
||||
/* could be on an unborn branch */
|
||||
!strcmp("HEAD", s->revision) &&
|
||||
get_oid("HEAD", &oid) ?
|
||||
empty_tree_oid_hex() : s->revision);
|
||||
}
|
||||
color_arg_index = args.argc;
|
||||
/* Use `--no-color` explicitly, just in case `diff.color = always`. */
|
||||
argv_array_pushl(&args, "diff-files", "-p", "--no-color", "--", NULL);
|
||||
color_arg_index = args.argc - 2;
|
||||
argv_array_pushl(&args, "--no-color", "-p", "--", NULL);
|
||||
for (i = 0; i < ps->nr; i++)
|
||||
argv_array_push(&args, ps->items[i].original);
|
||||
|
||||
|
@ -738,11 +906,10 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
|
|||
"(context).\n"
|
||||
"To remove '%c' lines, delete them.\n"
|
||||
"Lines starting with %c will be removed.\n"),
|
||||
'-', '+', comment_line_char);
|
||||
strbuf_commented_addf(&buf,
|
||||
_("If the patch applies cleanly, the edited hunk "
|
||||
"will immediately be\n"
|
||||
"marked for staging.\n"));
|
||||
s->mode->is_reverse ? '+' : '-',
|
||||
s->mode->is_reverse ? '-' : '+',
|
||||
comment_line_char);
|
||||
strbuf_commented_addf(&buf, "%s", _(s->mode->edit_hunk_hint));
|
||||
/*
|
||||
* TRANSLATORS: 'it' refers to the patch mentioned in the previous
|
||||
* messages.
|
||||
|
@ -838,7 +1005,8 @@ static int run_apply_check(struct add_p_state *s,
|
|||
reassemble_patch(s, file_diff, 1, &s->buf);
|
||||
|
||||
setup_child_process(&cp, s,
|
||||
"apply", "--cached", "--check", NULL);
|
||||
"apply", "--check", NULL);
|
||||
argv_array_pushv(&cp.args, s->mode->apply_check);
|
||||
if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0))
|
||||
return error(_("'git apply --cached' failed"));
|
||||
|
||||
|
@ -905,6 +1073,57 @@ static int edit_hunk_loop(struct add_p_state *s,
|
|||
}
|
||||
}
|
||||
|
||||
static int apply_for_checkout(struct add_p_state *s, struct strbuf *diff,
|
||||
int is_reverse)
|
||||
{
|
||||
const char *reverse = is_reverse ? "-R" : NULL;
|
||||
struct child_process check_index = CHILD_PROCESS_INIT;
|
||||
struct child_process check_worktree = CHILD_PROCESS_INIT;
|
||||
struct child_process apply_index = CHILD_PROCESS_INIT;
|
||||
struct child_process apply_worktree = CHILD_PROCESS_INIT;
|
||||
int applies_index, applies_worktree;
|
||||
|
||||
setup_child_process(&check_index, s,
|
||||
"apply", "--cached", "--check", reverse, NULL);
|
||||
applies_index = !pipe_command(&check_index, diff->buf, diff->len,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
setup_child_process(&check_worktree, s,
|
||||
"apply", "--check", reverse, NULL);
|
||||
applies_worktree = !pipe_command(&check_worktree, diff->buf, diff->len,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
if (applies_worktree && applies_index) {
|
||||
setup_child_process(&apply_index, s,
|
||||
"apply", "--cached", reverse, NULL);
|
||||
pipe_command(&apply_index, diff->buf, diff->len,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
setup_child_process(&apply_worktree, s,
|
||||
"apply", reverse, NULL);
|
||||
pipe_command(&apply_worktree, diff->buf, diff->len,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!applies_index) {
|
||||
err(s, _("The selected hunks do not apply to the index!"));
|
||||
if (prompt_yesno(s, _("Apply them to the worktree "
|
||||
"anyway? ")) > 0) {
|
||||
setup_child_process(&apply_worktree, s,
|
||||
"apply", reverse, NULL);
|
||||
return pipe_command(&apply_worktree, diff->buf,
|
||||
diff->len, NULL, 0, NULL, 0);
|
||||
}
|
||||
err(s, _("Nothing was applied.\n"));
|
||||
} else
|
||||
/* As a last resort, show the diff to the user */
|
||||
fwrite(diff->buf, diff->len, 1, stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SUMMARY_HEADER_WIDTH 20
|
||||
#define SUMMARY_LINE_WIDTH 80
|
||||
static void summarize_hunk(struct add_p_state *s, struct hunk *hunk,
|
||||
|
@ -953,13 +1172,6 @@ static size_t display_hunks(struct add_p_state *s,
|
|||
return end_index;
|
||||
}
|
||||
|
||||
static const char help_patch_text[] =
|
||||
N_("y - stage this hunk\n"
|
||||
"n - do not stage this hunk\n"
|
||||
"q - quit; do not stage this hunk or any of the remaining ones\n"
|
||||
"a - stage this and all the remaining hunks\n"
|
||||
"d - do not stage this hunk nor any of the remaining hunks\n");
|
||||
|
||||
static const char help_patch_remainder[] =
|
||||
N_("j - leave this hunk undecided, see next undecided hunk\n"
|
||||
"J - leave this hunk undecided, see next hunk\n"
|
||||
|
@ -1041,7 +1253,8 @@ static int patch_update_file(struct add_p_state *s,
|
|||
prompt_mode_type = PROMPT_HUNK;
|
||||
|
||||
color_fprintf(stdout, s->s.prompt_color,
|
||||
_(prompt_mode[prompt_mode_type]), s->buf.buf);
|
||||
_(s->mode->prompt_mode[prompt_mode_type]),
|
||||
s->buf.buf);
|
||||
fflush(stdout);
|
||||
if (strbuf_getline(&s->answer, stdin) == EOF)
|
||||
break;
|
||||
|
@ -1198,7 +1411,7 @@ soft_increment:
|
|||
const char *p = _(help_patch_remainder), *eol = p;
|
||||
|
||||
color_fprintf(stdout, s->s.help_color, "%s",
|
||||
_(help_patch_text));
|
||||
_(s->mode->help_patch_text));
|
||||
|
||||
/*
|
||||
* Show only those lines of the remainder that are
|
||||
|
@ -1231,10 +1444,16 @@ soft_increment:
|
|||
strbuf_reset(&s->buf);
|
||||
reassemble_patch(s, file_diff, 0, &s->buf);
|
||||
|
||||
setup_child_process(&cp, s, "apply", "--cached", NULL);
|
||||
if (s->mode->apply_for_checkout)
|
||||
apply_for_checkout(s, &s->buf,
|
||||
s->mode->is_reverse);
|
||||
else {
|
||||
setup_child_process(&cp, s, "apply", NULL);
|
||||
argv_array_pushv(&cp.args, s->mode->apply);
|
||||
if (pipe_command(&cp, s->buf.buf, s->buf.len,
|
||||
NULL, 0, NULL, 0))
|
||||
error(_("'git apply --cached' failed"));
|
||||
error(_("'git apply' failed"));
|
||||
}
|
||||
repo_refresh_and_write_index(s->s.r, REFRESH_QUIET, 0);
|
||||
}
|
||||
|
||||
|
@ -1242,7 +1461,8 @@ soft_increment:
|
|||
return quit;
|
||||
}
|
||||
|
||||
int run_add_p(struct repository *r, const struct pathspec *ps)
|
||||
int run_add_p(struct repository *r, enum add_p_mode mode,
|
||||
const char *revision, const struct pathspec *ps)
|
||||
{
|
||||
struct add_p_state s = {
|
||||
{ r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
|
||||
|
@ -1252,6 +1472,24 @@ int run_add_p(struct repository *r, const struct pathspec *ps)
|
|||
if (init_add_i_state(r, &s.s))
|
||||
return error("Could not read `add -i` config");
|
||||
|
||||
if (mode == ADD_P_STASH)
|
||||
s.mode = &patch_mode_stash;
|
||||
else if (mode == ADD_P_RESET) {
|
||||
if (!revision || !strcmp(revision, "HEAD"))
|
||||
s.mode = &patch_mode_reset_head;
|
||||
else
|
||||
s.mode = &patch_mode_reset_nothead;
|
||||
} else if (mode == ADD_P_CHECKOUT) {
|
||||
if (!revision)
|
||||
s.mode = &patch_mode_checkout_index;
|
||||
else if (!strcmp(revision, "HEAD"))
|
||||
s.mode = &patch_mode_checkout_head;
|
||||
else
|
||||
s.mode = &patch_mode_checkout_nothead;
|
||||
} else
|
||||
s.mode = &patch_mode_stage;
|
||||
s.revision = revision;
|
||||
|
||||
if (repo_refresh_and_write_index(r, REFRESH_QUIET, 0) < 0 ||
|
||||
parse_diff(&s, ps) < 0) {
|
||||
strbuf_release(&s.plain);
|
||||
|
|
|
@ -26,7 +26,8 @@ static const char * const builtin_add_usage[] = {
|
|||
N_("git add [<options>] [--] <pathspec>..."),
|
||||
NULL
|
||||
};
|
||||
static int patch_interactive, add_interactive, edit_interactive;
|
||||
static const char *patch_interactive;
|
||||
static int add_interactive, edit_interactive;
|
||||
static int take_worktree_changes;
|
||||
static int add_renormalize;
|
||||
|
||||
|
@ -181,6 +182,8 @@ static void refresh(int verbose, const struct pathspec *pathspec)
|
|||
free(seen);
|
||||
}
|
||||
|
||||
static int add_config(const char *var, const char *value, void *cb);
|
||||
|
||||
int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
|
@ -193,12 +196,23 @@ int run_add_interactive(const char *revision, const char *patch_mode,
|
|||
&use_builtin_add_i);
|
||||
|
||||
if (use_builtin_add_i == 1) {
|
||||
enum add_p_mode mode;
|
||||
|
||||
if (!patch_mode)
|
||||
return !!run_add_i(the_repository, pathspec);
|
||||
if (strcmp(patch_mode, "--patch"))
|
||||
die("'%s' not yet supported in the built-in add -p",
|
||||
patch_mode);
|
||||
return !!run_add_p(the_repository, pathspec);
|
||||
|
||||
if (!strcmp(patch_mode, "--patch"))
|
||||
mode = ADD_P_STAGE;
|
||||
else if (!strcmp(patch_mode, "--patch=stash"))
|
||||
mode = ADD_P_STASH;
|
||||
else if (!strcmp(patch_mode, "--patch=reset"))
|
||||
mode = ADD_P_RESET;
|
||||
else if (!strcmp(patch_mode, "--patch=checkout"))
|
||||
mode = ADD_P_CHECKOUT;
|
||||
else
|
||||
die("'%s' not supported", patch_mode);
|
||||
|
||||
return !!run_add_p(the_repository, mode, revision, pathspec);
|
||||
}
|
||||
|
||||
argv_array_push(&argv, "add--interactive");
|
||||
|
@ -216,9 +230,11 @@ int run_add_interactive(const char *revision, const char *patch_mode,
|
|||
return status;
|
||||
}
|
||||
|
||||
int interactive_add(int argc, const char **argv, const char *prefix, int patch)
|
||||
int interactive_add(int argc, const char **argv, const char *prefix,
|
||||
const char *patch_mode)
|
||||
{
|
||||
struct pathspec pathspec;
|
||||
char buffer[64];
|
||||
|
||||
parse_pathspec(&pathspec, 0,
|
||||
PATHSPEC_PREFER_FULL |
|
||||
|
@ -226,9 +242,13 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
|
|||
PATHSPEC_PREFIX_ORIGIN,
|
||||
prefix, argv);
|
||||
|
||||
return run_add_interactive(NULL,
|
||||
patch ? "--patch" : NULL,
|
||||
&pathspec);
|
||||
if (patch_mode) {
|
||||
xsnprintf(buffer, sizeof(buffer), "--patch%s%s",
|
||||
*patch_mode ? "=" : "", patch_mode);
|
||||
patch_mode = buffer;
|
||||
}
|
||||
|
||||
return run_add_interactive(NULL, patch_mode, &pathspec);
|
||||
}
|
||||
|
||||
static int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
|
@ -306,7 +326,9 @@ static struct option builtin_add_options[] = {
|
|||
OPT__VERBOSE(&verbose, N_("be verbose")),
|
||||
OPT_GROUP(""),
|
||||
OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
|
||||
OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
|
||||
{ OPTION_STRING, 'p', "patch", &patch_interactive, N_("patch-mode"),
|
||||
N_("select hunks interactively"), PARSE_OPT_OPTARG, NULL,
|
||||
(intptr_t) "" },
|
||||
OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
|
||||
OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
|
||||
OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
|
||||
|
|
|
@ -344,7 +344,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||
die(_("index file corrupt"));
|
||||
|
||||
if (interactive) {
|
||||
char *old_index_env = NULL;
|
||||
char *old_index_env = NULL, *old_repo_index_file;
|
||||
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||
|
||||
refresh_cache_or_die(refresh_flags);
|
||||
|
@ -352,12 +352,17 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||
if (write_locked_index(&the_index, &index_lock, 0))
|
||||
die(_("unable to create temporary index"));
|
||||
|
||||
old_repo_index_file = the_repository->index_file;
|
||||
the_repository->index_file =
|
||||
(char *)get_lock_file_path(&index_lock);
|
||||
old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
|
||||
setenv(INDEX_ENVIRONMENT, get_lock_file_path(&index_lock), 1);
|
||||
setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
|
||||
|
||||
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
|
||||
if (interactive_add(argc, argv, prefix,
|
||||
patch_interactive ? "" : NULL) != 0)
|
||||
die(_("interactive add failed"));
|
||||
|
||||
the_repository->index_file = old_repo_index_file;
|
||||
if (old_index_env && *old_index_env)
|
||||
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
|
||||
else
|
||||
|
|
|
@ -992,9 +992,9 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
|
|||
{
|
||||
int ret = 0;
|
||||
struct child_process cp_read_tree = CHILD_PROCESS_INIT;
|
||||
struct child_process cp_add_i = CHILD_PROCESS_INIT;
|
||||
struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
|
||||
struct index_state istate = { NULL };
|
||||
char *old_index_env = NULL, *old_repo_index_file;
|
||||
|
||||
remove_path(stash_index_path.buf);
|
||||
|
||||
|
@ -1008,16 +1008,19 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
|
|||
}
|
||||
|
||||
/* Find out what the user wants. */
|
||||
cp_add_i.git_cmd = 1;
|
||||
argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
|
||||
"--", NULL);
|
||||
add_pathspecs(&cp_add_i.args, ps);
|
||||
argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
|
||||
stash_index_path.buf);
|
||||
if (run_command(&cp_add_i)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
old_repo_index_file = the_repository->index_file;
|
||||
the_repository->index_file = stash_index_path.buf;
|
||||
old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
|
||||
setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
|
||||
|
||||
ret = run_add_interactive(NULL, "--patch=stash", ps);
|
||||
|
||||
the_repository->index_file = old_repo_index_file;
|
||||
if (old_index_env && *old_index_env)
|
||||
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
|
||||
else
|
||||
unsetenv(INDEX_ENVIRONMENT);
|
||||
FREE_AND_NULL(old_index_env);
|
||||
|
||||
/* State of the working tree. */
|
||||
if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
|
||||
|
|
3
commit.h
3
commit.h
|
@ -295,7 +295,8 @@ int delayed_reachability_test(struct shallow_info *si, int c);
|
|||
void prune_shallow(unsigned options);
|
||||
extern struct trace_key trace_shallow;
|
||||
|
||||
int interactive_add(int argc, const char **argv, const char *prefix, int patch);
|
||||
int interactive_add(int argc, const char **argv, const char *prefix,
|
||||
const char *patch_mode);
|
||||
int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
const struct pathspec *pathspec);
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ create_stash () {
|
|||
|
||||
# find out what the user wants
|
||||
GIT_INDEX_FILE="$TMP-index" \
|
||||
git add--interactive --patch=stash -- "$@" &&
|
||||
git add --patch=stash -- "$@" &&
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
|
||||
|
|
Загрузка…
Ссылка в новой задаче