};
static const char *prompt_mode[] = {
- N_("Stage mode change [y,n,a,d%s,?]? "),
- N_("Stage deletion [y,n,a,d%s,?]? "),
- N_("Stage this hunk [y,n,a,d%s,?]? ")
+ 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 hunk_header {
struct hunk head;
struct hunk *hunk;
size_t hunk_nr, hunk_alloc;
- unsigned deleted:1, mode_change:1;
+ unsigned deleted:1, mode_change:1,binary:1;
} *file_diff;
size_t file_diff_nr;
};
BUG("'new mode' does not immediately follow "
"'old mode'?\n\n%.*s",
(int)(eol - plain->buf), plain->buf);
- }
+ } else if (hunk == &file_diff->head &&
+ 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",
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"
- "j - leave this hunk undecided, see next undecided hunk\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"
"k - leave this hunk undecided, see previous undecided hunk\n"
"K - leave this hunk undecided, see previous hunk\n"
struct hunk *hunk;
char ch;
struct child_process cp = CHILD_PROCESS_INIT;
- int colored = !!s->colored.len;
+ int colored = !!s->colored.len, quit = 0;
enum prompt_mode_type prompt_mode_type;
if (!file_diff->hunk_nr)
if (hunk->use == UNDECIDED_HUNK)
hunk->use = USE_HUNK;
}
- } else if (ch == 'd') {
+ } else if (ch == 'd' || ch == 'q') {
for (; hunk_index < file_diff->hunk_nr; hunk_index++) {
hunk = file_diff->hunk + hunk_index;
if (hunk->use == UNDECIDED_HUNK)
hunk->use = SKIP_HUNK;
}
+ if (ch == 'q') {
+ quit = 1;
+ break;
+ }
} else if (s->answer.buf[0] == 'K') {
if (hunk_index)
hunk_index--;
hunk->use = USE_HUNK;
goto soft_increment;
}
- } else
- color_fprintf(stdout, s->s.help_color,
+ } else {
+ const char *p = _(help_patch_remainder), *eol = p;
+
+ color_fprintf(stdout, s->s.help_color, "%s",
_(help_patch_text));
+
+ /*
+ * Show only those lines of the remainder that are
+ * actually applicable with the current hunk.
+ */
+ for (; *p; p = eol + (*eol == '\n')) {
+ eol = strchrnul(p, '\n');
+
+ /*
+ * `s->buf` still contains the part of the
+ * commands shown in the prompt that are not
+ * always available.
+ */
+ if (*p != '?' && !strchr(s->buf.buf, *p))
+ continue;
+
+ color_fprintf_ln(stdout, s->s.help_color,
+ "%.*s", (int)(eol - p), p);
+ }
+ }
}
/* Any hunk to be used? */
}
putchar('\n');
- return 0;
+ return quit;
}
int run_add_p(struct repository *r, const struct pathspec *ps)
struct add_p_state s = {
{ r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
};
- size_t i;
+ size_t i, binary_count = 0;
init_add_i_state(&s.s, r);
}
for (i = 0; i < s.file_diff_nr; i++)
- if (patch_update_file(&s, s.file_diff + i))
+ if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr)
+ binary_count++;
+ else if (patch_update_file(&s, s.file_diff + i))
break;
+ if (s.file_diff_nr == 0)
+ fprintf(stderr, _("No changes.\n"));
+ else if (binary_count == s.file_diff_nr)
+ fprintf(stderr, _("Only binary files changed.\n"));
+
strbuf_release(&s.answer);
strbuf_release(&s.buf);
strbuf_release(&s.plain);