diff options
Diffstat (limited to 'add-patch.c')
-rw-r--r-- | add-patch.c | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/add-patch.c b/add-patch.c index d8dafa8168..f67b304a55 100644 --- a/add-patch.c +++ b/add-patch.c @@ -2,14 +2,15 @@ #include "add-interactive.h" #include "strbuf.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "pathspec.h" #include "color.h" #include "diff.h" #include "compat/terminal.h" +#include "prompt.h" enum prompt_mode_type { - PROMPT_MODE_CHANGE = 0, PROMPT_DELETION, PROMPT_HUNK, + PROMPT_MODE_CHANGE = 0, PROMPT_DELETION, PROMPT_ADDITION, PROMPT_HUNK, PROMPT_MODE_MAX, /* must be last */ }; @@ -32,6 +33,7 @@ static struct patch_mode patch_mode_add = { .prompt_mode = { N_("Stage mode change [y,n,q,a,d%s,?]? "), N_("Stage deletion [y,n,q,a,d%s,?]? "), + N_("Stage addition [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 " @@ -53,6 +55,7 @@ static struct patch_mode patch_mode_stash = { .prompt_mode = { N_("Stash mode change [y,n,q,a,d%s,?]? "), N_("Stash deletion [y,n,q,a,d%s,?]? "), + N_("Stash addition [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 " @@ -76,6 +79,7 @@ static struct patch_mode patch_mode_reset_head = { .prompt_mode = { N_("Unstage mode change [y,n,q,a,d%s,?]? "), N_("Unstage deletion [y,n,q,a,d%s,?]? "), + N_("Unstage addition [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 " @@ -98,6 +102,7 @@ static struct patch_mode patch_mode_reset_nothead = { .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 addition 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 " @@ -120,6 +125,7 @@ static struct patch_mode patch_mode_checkout_index = { .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 addition 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 " @@ -142,6 +148,7 @@ static struct patch_mode patch_mode_checkout_head = { .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 addition 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 " @@ -163,6 +170,7 @@ static struct patch_mode patch_mode_checkout_nothead = { .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 addition 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 " @@ -185,6 +193,7 @@ static struct patch_mode patch_mode_worktree_head = { .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 addition 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 " @@ -206,6 +215,7 @@ static struct patch_mode patch_mode_worktree_nothead = { .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 addition 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 " @@ -247,7 +257,7 @@ struct add_p_state { struct hunk head; struct hunk *hunk; size_t hunk_nr, hunk_alloc; - unsigned deleted:1, mode_change:1,binary:1; + unsigned deleted:1, added:1, mode_change:1,binary:1; } *file_diff; size_t file_diff_nr; @@ -276,12 +286,12 @@ static void setup_child_process(struct add_p_state *s, va_start(ap, cp); while ((arg = va_arg(ap, const char *))) - argv_array_push(&cp->args, arg); + strvec_push(&cp->args, arg); va_end(ap); cp->git_cmd = 1; - argv_array_pushf(&cp->env_array, - INDEX_ENVIRONMENT "=%s", s->s.r->index_file); + strvec_pushf(&cp->env_array, + INDEX_ENVIRONMENT "=%s", s->s.r->index_file); } static int parse_range(const char **p, @@ -360,7 +370,7 @@ static int is_octal(const char *p, size_t len) static int parse_diff(struct add_p_state *s, const struct pathspec *ps) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; const char *diff_algorithm = s->s.interactive_diff_algorithm; struct strbuf *plain = &s->plain, *colored = NULL; struct child_process cp = CHILD_PROCESS_INIT; @@ -370,32 +380,32 @@ 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_cmd); + strvec_pushv(&args, s->mode->diff_cmd); if (diff_algorithm) - argv_array_pushf(&args, "--diff-algorithm=%s", diff_algorithm); + strvec_pushf(&args, "--diff-algorithm=%s", diff_algorithm); 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); + strvec_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; + color_arg_index = args.nr; /* Use `--no-color` explicitly, just in case `diff.color = always`. */ - argv_array_pushl(&args, "--no-color", "-p", "--", NULL); + strvec_pushl(&args, "--no-color", "-p", "--", NULL); for (i = 0; i < ps->nr; i++) - argv_array_push(&args, ps->items[i].original); + strvec_push(&args, ps->items[i].original); setup_child_process(s, &cp, NULL); - cp.argv = args.argv; + cp.argv = args.v; res = capture_command(&cp, plain, 0); if (res) { - argv_array_clear(&args); + strvec_clear(&args); return error(_("could not parse diff")); } if (!plain->len) { - argv_array_clear(&args); + strvec_clear(&args); return 0; } strbuf_complete_line(plain); @@ -405,11 +415,11 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) const char *diff_filter = s->s.interactive_diff_filter; setup_child_process(s, &colored_cp, NULL); - xsnprintf((char *)args.argv[color_arg_index], 8, "--color"); - colored_cp.argv = args.argv; + xsnprintf((char *)args.v[color_arg_index], 8, "--color"); + colored_cp.argv = args.v; colored = &s->colored; res = capture_command(&colored_cp, colored, 0); - argv_array_clear(&args); + strvec_clear(&args); if (res) return error(_("could not parse colored diff")); @@ -434,14 +444,14 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) colored_p = colored->buf; colored_pend = colored_p + colored->len; } - argv_array_clear(&args); + strvec_clear(&args); /* parse files and hunks */ p = plain->buf; pend = p + plain->len; while (p != pend) { char *eol = memchr(p, '\n', pend - p); - const char *deleted = NULL, *mode_change = NULL; + const char *deleted = NULL, *added = NULL, *mode_change = NULL; if (!eol) eol = pend; @@ -460,11 +470,12 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) } else if (p == plain->buf) BUG("diff starts with unexpected line:\n" "%.*s\n", (int)(eol - p), p); - else if (file_diff->deleted) + else if (file_diff->deleted || file_diff->added) ; /* keep the rest of the file in a single "hunk" */ else if (starts_with(p, "@@ ") || (hunk == &file_diff->head && - skip_prefix(p, "deleted file", &deleted))) { + (skip_prefix(p, "deleted file", &deleted) || + skip_prefix(p, "new file", &added)))) { if (marker == '-' || marker == '+') /* * Should not happen; previous hunk did not end @@ -484,6 +495,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) if (deleted) file_diff->deleted = 1; + else if (added) + file_diff->added = 1; else if (parse_hunk_header(s, hunk) < 0) return -1; @@ -536,8 +549,10 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) starts_with(p, "Binary files ")) file_diff->binary = 1; - if (file_diff->deleted && file_diff->mode_change) - BUG("diff contains delete *and* a mode change?!?\n%.*s", + if (!!file_diff->deleted + !!file_diff->added + + !!file_diff->mode_change > 1) + BUG("diff can only contain delete *or* add *or* a " + "mode change?!?\n%.*s", (int)(eol - (plain->buf + file_diff->head.start)), plain->buf + file_diff->head.start); @@ -1143,7 +1158,7 @@ static int run_apply_check(struct add_p_state *s, setup_child_process(s, &cp, "apply", "--check", NULL); - argv_array_pushv(&cp.args, s->mode->apply_check_args); + strvec_pushv(&cp.args, s->mode->apply_check_args); if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) return error(_("'git apply --cached' failed")); @@ -1158,9 +1173,8 @@ static int read_single_character(struct add_p_state *s) return res; } - if (strbuf_getline(&s->answer, stdin) == EOF) + if (git_read_line_interactively(&s->answer) == EOF) return EOF; - strbuf_trim_trailing_newline(&s->answer); return 0; } @@ -1189,7 +1203,7 @@ static int edit_hunk_loop(struct add_p_state *s, for (;;) { int res = edit_hunk_manually(s, hunk); if (res == 0) { - /* abandonded */ + /* abandoned */ *hunk = backup; return -1; } @@ -1397,6 +1411,8 @@ static int patch_update_file(struct add_p_state *s, if (file_diff->deleted) prompt_mode_type = PROMPT_DELETION; + else if (file_diff->added) + prompt_mode_type = PROMPT_ADDITION; else if (file_diff->mode_change && !hunk_index) prompt_mode_type = PROMPT_MODE_CHANGE; else @@ -1603,7 +1619,7 @@ soft_increment: s->mode->is_reverse); else { setup_child_process(s, &cp, "apply", NULL); - argv_array_pushv(&cp.args, s->mode->apply_args); + strvec_pushv(&cp.args, s->mode->apply_args); if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) error(_("'git apply' failed")); |