mirror of
https://github.com/git/git.git
synced 2026-02-26 01:43:43 +00:00
Merge branch 'aa/add-p-no-auto-advance' into jch
"git add -p" learned a new mode that allows the user to revisit a file that was already dealt with. * aa/add-p-no-auto-advance: add-patch: allow interfile navigation when selecting hunks add-patch: allow all-or-none application of patches add-patch: modify patch_update_file() signature interactive -p: add new `--auto-advance` flag
This commit is contained in:
@@ -64,6 +64,7 @@ void init_add_i_state(struct add_i_state *s, struct repository *r,
|
||||
s->r = r;
|
||||
s->context = -1;
|
||||
s->interhunkcontext = -1;
|
||||
s->auto_advance = add_p_opt->auto_advance;
|
||||
|
||||
s->use_color_interactive = check_color_config(r, "color.interactive");
|
||||
|
||||
@@ -1017,6 +1018,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
|
||||
struct add_p_opt add_p_opt = {
|
||||
.context = s->context,
|
||||
.interhunkcontext = s->interhunkcontext,
|
||||
.auto_advance = s->auto_advance
|
||||
};
|
||||
struct strvec args = STRVEC_INIT;
|
||||
struct pathspec ps_selected = { 0 };
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
struct add_p_opt {
|
||||
int context;
|
||||
int interhunkcontext;
|
||||
int auto_advance;
|
||||
};
|
||||
|
||||
#define ADD_P_OPT_INIT { .context = -1, .interhunkcontext = -1 }
|
||||
#define ADD_P_OPT_INIT { .context = -1, .interhunkcontext = -1, .auto_advance = 1 }
|
||||
|
||||
struct add_i_state {
|
||||
struct repository *r;
|
||||
@@ -29,6 +30,7 @@ struct add_i_state {
|
||||
int use_single_key;
|
||||
char *interactive_diff_filter, *interactive_diff_algorithm;
|
||||
int context, interhunkcontext;
|
||||
int auto_advance;
|
||||
};
|
||||
|
||||
void init_add_i_state(struct add_i_state *s, struct repository *r,
|
||||
|
||||
154
add-patch.c
154
add-patch.c
@@ -1418,7 +1418,44 @@ N_("j - go to the next undecided hunk, roll over at the bottom\n"
|
||||
"e - manually edit the current hunk\n"
|
||||
"p - print the current hunk\n"
|
||||
"P - print the current hunk using the pager\n"
|
||||
"? - print help\n");
|
||||
"> - go to the next file, roll over at the bottom\n"
|
||||
"< - go to the previous file, roll over at the top\n"
|
||||
"? - print help\n"
|
||||
"HUNKS SUMMARY - Hunks: %d, USE: %d, SKIP: %d\n");
|
||||
|
||||
static void apply_patch(struct add_p_state *s, struct file_diff *file_diff)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
size_t j;
|
||||
|
||||
/* Any hunk to be used? */
|
||||
for (j = 0; j < file_diff->hunk_nr; j++)
|
||||
if (file_diff->hunk[j].use == USE_HUNK)
|
||||
break;
|
||||
|
||||
if (j < file_diff->hunk_nr ||
|
||||
(!file_diff->hunk_nr && file_diff->head.use == USE_HUNK)) {
|
||||
/* At least one hunk selected: apply */
|
||||
strbuf_reset(&s->buf);
|
||||
reassemble_patch(s, file_diff, 0, &s->buf);
|
||||
|
||||
discard_index(s->s.r->index);
|
||||
if (s->mode->apply_for_checkout)
|
||||
apply_for_checkout(s, &s->buf,
|
||||
s->mode->is_reverse);
|
||||
else {
|
||||
setup_child_process(s, &cp, "apply", NULL);
|
||||
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"));
|
||||
}
|
||||
if (repo_read_index(s->s.r) >= 0)
|
||||
repo_refresh_and_write_index(s->s.r, REFRESH_QUIET, 0,
|
||||
1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static size_t dec_mod(size_t a, size_t m)
|
||||
{
|
||||
@@ -1441,20 +1478,21 @@ static bool get_first_undecided(const struct file_diff *file_diff, size_t *idx)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int patch_update_file(struct add_p_state *s,
|
||||
struct file_diff *file_diff)
|
||||
static size_t patch_update_file(struct add_p_state *s, size_t idx)
|
||||
{
|
||||
size_t hunk_index = 0;
|
||||
ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
|
||||
struct hunk *hunk;
|
||||
char ch;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
int colored = !!s->colored.len, quit = 0, use_pager = 0;
|
||||
int colored = !!s->colored.len, use_pager = 0;
|
||||
enum prompt_mode_type prompt_mode_type;
|
||||
int all_decided = 0;
|
||||
struct file_diff *file_diff = s->file_diff + idx;
|
||||
size_t patch_update_resp = idx;
|
||||
|
||||
/* Empty added files have no hunks */
|
||||
if (!file_diff->hunk_nr && !file_diff->added)
|
||||
return 0;
|
||||
return patch_update_resp + 1;
|
||||
|
||||
strbuf_reset(&s->buf);
|
||||
render_diff_header(s, file_diff, colored, &s->buf);
|
||||
@@ -1468,7 +1506,9 @@ static int patch_update_file(struct add_p_state *s,
|
||||
ALLOW_GOTO_NEXT_UNDECIDED_HUNK = 1 << 3,
|
||||
ALLOW_SEARCH_AND_GOTO = 1 << 4,
|
||||
ALLOW_SPLIT = 1 << 5,
|
||||
ALLOW_EDIT = 1 << 6
|
||||
ALLOW_EDIT = 1 << 6,
|
||||
ALLOW_GOTO_PREVIOUS_FILE = 1 << 7,
|
||||
ALLOW_GOTO_NEXT_FILE = 1 << 8
|
||||
} permitted = 0;
|
||||
|
||||
if (hunk_index >= file_diff->hunk_nr)
|
||||
@@ -1499,9 +1539,14 @@ static int patch_update_file(struct add_p_state *s,
|
||||
|
||||
/* Everything decided? */
|
||||
if (undecided_previous < 0 && undecided_next < 0 &&
|
||||
hunk->use != UNDECIDED_HUNK)
|
||||
break;
|
||||
|
||||
hunk->use != UNDECIDED_HUNK) {
|
||||
if (!s->s.auto_advance)
|
||||
all_decided = 1;
|
||||
else {
|
||||
patch_update_resp++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
strbuf_reset(&s->buf);
|
||||
if (file_diff->hunk_nr) {
|
||||
if (rendered_hunk_index != hunk_index) {
|
||||
@@ -1549,6 +1594,14 @@ static int patch_update_file(struct add_p_state *s,
|
||||
permitted |= ALLOW_EDIT;
|
||||
strbuf_addstr(&s->buf, ",e");
|
||||
}
|
||||
if (!s->s.auto_advance && s->file_diff_nr > 1) {
|
||||
permitted |= ALLOW_GOTO_NEXT_FILE;
|
||||
strbuf_addstr(&s->buf, ",>");
|
||||
}
|
||||
if (!s->s.auto_advance && s->file_diff_nr > 1) {
|
||||
permitted |= ALLOW_GOTO_PREVIOUS_FILE;
|
||||
strbuf_addstr(&s->buf, ",<");
|
||||
}
|
||||
strbuf_addstr(&s->buf, ",p,P");
|
||||
}
|
||||
if (file_diff->deleted)
|
||||
@@ -1577,7 +1630,7 @@ static int patch_update_file(struct add_p_state *s,
|
||||
fputs(s->s.reset_color_interactive, stdout);
|
||||
fflush(stdout);
|
||||
if (read_single_character(s) == EOF) {
|
||||
quit = 1;
|
||||
patch_update_resp = s->file_diff_nr;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1623,8 +1676,30 @@ soft_increment:
|
||||
hunk->use = SKIP_HUNK;
|
||||
}
|
||||
} else if (ch == 'q') {
|
||||
quit = 1;
|
||||
patch_update_resp = s->file_diff_nr;
|
||||
break;
|
||||
} else if (!s->s.auto_advance && s->answer.buf[0] == '>') {
|
||||
if (permitted & ALLOW_GOTO_NEXT_FILE) {
|
||||
if (patch_update_resp == s->file_diff_nr - 1)
|
||||
patch_update_resp = 0;
|
||||
else
|
||||
patch_update_resp++;
|
||||
break;
|
||||
} else {
|
||||
err(s, _("No next file"));
|
||||
continue;
|
||||
}
|
||||
} else if (!s->s.auto_advance && s->answer.buf[0] == '<') {
|
||||
if (permitted & ALLOW_GOTO_PREVIOUS_FILE) {
|
||||
if (patch_update_resp == 0)
|
||||
patch_update_resp = s->file_diff_nr - 1;
|
||||
else
|
||||
patch_update_resp--;
|
||||
break;
|
||||
} else {
|
||||
err(s, _("No previous file"));
|
||||
continue;
|
||||
}
|
||||
} else if (s->answer.buf[0] == 'K') {
|
||||
if (permitted & ALLOW_GOTO_PREVIOUS_HUNK)
|
||||
hunk_index = dec_mod(hunk_index,
|
||||
@@ -1770,6 +1845,18 @@ soft_increment:
|
||||
* commands shown in the prompt that are not
|
||||
* always available.
|
||||
*/
|
||||
if (all_decided && !strncmp(p, "HUNKS SUMMARY", 13)) {
|
||||
int total = file_diff->hunk_nr, used = 0, skipped = 0;
|
||||
|
||||
for (i = 0; i < file_diff->hunk_nr; i++) {
|
||||
if (file_diff->hunk[i].use == USE_HUNK)
|
||||
used += 1;
|
||||
if (file_diff->hunk[i].use == SKIP_HUNK)
|
||||
skipped += 1;
|
||||
}
|
||||
color_fprintf_ln(stdout, s->s.help_color, _(p),
|
||||
total, used, skipped);
|
||||
}
|
||||
if (*p != '?' && !strchr(s->buf.buf, *p))
|
||||
continue;
|
||||
|
||||
@@ -1782,35 +1869,11 @@ soft_increment:
|
||||
}
|
||||
}
|
||||
|
||||
/* Any hunk to be used? */
|
||||
for (i = 0; i < file_diff->hunk_nr; i++)
|
||||
if (file_diff->hunk[i].use == USE_HUNK)
|
||||
break;
|
||||
|
||||
if (i < file_diff->hunk_nr ||
|
||||
(!file_diff->hunk_nr && file_diff->head.use == USE_HUNK)) {
|
||||
/* At least one hunk selected: apply */
|
||||
strbuf_reset(&s->buf);
|
||||
reassemble_patch(s, file_diff, 0, &s->buf);
|
||||
|
||||
discard_index(s->s.r->index);
|
||||
if (s->mode->apply_for_checkout)
|
||||
apply_for_checkout(s, &s->buf,
|
||||
s->mode->is_reverse);
|
||||
else {
|
||||
setup_child_process(s, &cp, "apply", NULL);
|
||||
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"));
|
||||
}
|
||||
if (repo_read_index(s->s.r) >= 0)
|
||||
repo_refresh_and_write_index(s->s.r, REFRESH_QUIET, 0,
|
||||
1, NULL, NULL, NULL);
|
||||
}
|
||||
if (s->s.auto_advance)
|
||||
apply_patch(s, file_diff);
|
||||
|
||||
putchar('\n');
|
||||
return quit;
|
||||
return patch_update_resp;
|
||||
}
|
||||
|
||||
int run_add_p(struct repository *r, enum add_p_mode mode,
|
||||
@@ -1859,11 +1922,18 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < s.file_diff_nr; i++)
|
||||
if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr)
|
||||
for (i = 0; i < s.file_diff_nr;) {
|
||||
if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr) {
|
||||
binary_count++;
|
||||
else if (patch_update_file(&s, s.file_diff + i))
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ((i = patch_update_file(&s, i)) == s.file_diff_nr)
|
||||
break;
|
||||
}
|
||||
if (!s.s.auto_advance)
|
||||
for (i = 0; i < s.file_diff_nr; i++)
|
||||
apply_patch(&s, s.file_diff + i);
|
||||
|
||||
if (s.file_diff_nr == 0)
|
||||
err(&s, _("No changes."));
|
||||
|
||||
@@ -256,6 +256,8 @@ static struct option builtin_add_options[] = {
|
||||
OPT_GROUP(""),
|
||||
OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
|
||||
OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
|
||||
OPT_BOOL(0, "auto-advance", &add_p_opt.auto_advance,
|
||||
N_("auto advance to the next file when selecting hunks interactively")),
|
||||
OPT_DIFF_UNIFIED(&add_p_opt.context),
|
||||
OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext),
|
||||
OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
|
||||
@@ -418,6 +420,8 @@ int cmd_add(int argc,
|
||||
die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch");
|
||||
if (add_p_opt.interhunkcontext != -1)
|
||||
die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch");
|
||||
if (!add_p_opt.auto_advance)
|
||||
die(_("the option '%s' requires '%s'"), "--no-auto-advance", "--interactive/--patch");
|
||||
}
|
||||
|
||||
if (edit_interactive) {
|
||||
|
||||
@@ -47,6 +47,7 @@ struct checkout_opts {
|
||||
int patch_mode;
|
||||
int patch_context;
|
||||
int patch_interhunk_context;
|
||||
int auto_advance;
|
||||
int quiet;
|
||||
int merge;
|
||||
int force;
|
||||
@@ -95,6 +96,7 @@ struct checkout_opts {
|
||||
.merge = -1, \
|
||||
.patch_context = -1, \
|
||||
.patch_interhunk_context = -1, \
|
||||
.auto_advance = 1, \
|
||||
}
|
||||
|
||||
struct branch_info {
|
||||
@@ -533,6 +535,7 @@ static int checkout_paths(const struct checkout_opts *opts,
|
||||
struct add_p_opt add_p_opt = {
|
||||
.context = opts->patch_context,
|
||||
.interhunkcontext = opts->patch_interhunk_context,
|
||||
.auto_advance = opts->auto_advance
|
||||
};
|
||||
const char *rev = new_branch_info->name;
|
||||
char rev_oid[GIT_MAX_HEXSZ + 1];
|
||||
@@ -1845,6 +1848,8 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
||||
die(_("the option '%s' requires '%s'"), "--unified", "--patch");
|
||||
if (opts->patch_interhunk_context != -1)
|
||||
die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch");
|
||||
if (!opts->auto_advance)
|
||||
die(_("the option '%s' requires '%s'"), "--no-auto-advance", "--patch");
|
||||
}
|
||||
|
||||
if (opts->show_progress < 0) {
|
||||
@@ -2043,6 +2048,8 @@ int cmd_checkout(int argc,
|
||||
OPT_BOOL(0, "guess", &opts.dwim_new_local_branch,
|
||||
N_("second guess 'git checkout <no-such-branch>' (default)")),
|
||||
OPT_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode (default)")),
|
||||
OPT_BOOL(0, "auto-advance", &opts.auto_advance,
|
||||
N_("auto advance to the next file when selecting hunks interactively")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
||||
@@ -371,6 +371,8 @@ int cmd_reset(int argc,
|
||||
PARSE_OPT_OPTARG,
|
||||
option_parse_recurse_submodules_worktree_updater),
|
||||
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
|
||||
OPT_BOOL(0, "auto-advance", &add_p_opt.auto_advance,
|
||||
N_("auto advance to the next file when selecting hunks interactively")),
|
||||
OPT_DIFF_UNIFIED(&add_p_opt.context),
|
||||
OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext),
|
||||
OPT_BOOL('N', "intent-to-add", &intent_to_add,
|
||||
@@ -443,6 +445,8 @@ int cmd_reset(int argc,
|
||||
die(_("the option '%s' requires '%s'"), "--unified", "--patch");
|
||||
if (add_p_opt.interhunkcontext != -1)
|
||||
die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch");
|
||||
if (!add_p_opt.auto_advance)
|
||||
die(_("the option '%s' requires '%s'"), "--no-auto-advance", "--patch");
|
||||
}
|
||||
|
||||
/* git reset tree [--] paths... can be used to
|
||||
|
||||
@@ -1849,6 +1849,8 @@ static int push_stash(int argc, const char **argv, const char *prefix,
|
||||
N_("stash staged changes only")),
|
||||
OPT_BOOL('p', "patch", &patch_mode,
|
||||
N_("stash in patch mode")),
|
||||
OPT_BOOL(0, "auto-advance", &add_p_opt.auto_advance,
|
||||
N_("auto advance to the next file when selecting hunks interactively")),
|
||||
OPT_DIFF_UNIFIED(&add_p_opt.context),
|
||||
OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext),
|
||||
OPT__QUIET(&quiet, N_("quiet mode")),
|
||||
@@ -1911,6 +1913,8 @@ static int push_stash(int argc, const char **argv, const char *prefix,
|
||||
die(_("the option '%s' requires '%s'"), "--unified", "--patch");
|
||||
if (add_p_opt.interhunkcontext != -1)
|
||||
die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch");
|
||||
if (!add_p_opt.auto_advance)
|
||||
die(_("the option '%s' requires '%s'"), "--no-auto-advance", "--patch");
|
||||
}
|
||||
|
||||
if (add_p_opt.context < -1)
|
||||
@@ -1952,6 +1956,8 @@ static int save_stash(int argc, const char **argv, const char *prefix,
|
||||
N_("stash staged changes only")),
|
||||
OPT_BOOL('p', "patch", &patch_mode,
|
||||
N_("stash in patch mode")),
|
||||
OPT_BOOL(0, "auto-advance", &add_p_opt.auto_advance,
|
||||
N_("auto advance to the next file when selecting hunks interactively")),
|
||||
OPT_DIFF_UNIFIED(&add_p_opt.context),
|
||||
OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext),
|
||||
OPT__QUIET(&quiet, N_("quiet mode")),
|
||||
@@ -1983,6 +1989,8 @@ static int save_stash(int argc, const char **argv, const char *prefix,
|
||||
die(_("the option '%s' requires '%s'"), "--unified", "--patch");
|
||||
if (add_p_opt.interhunkcontext != -1)
|
||||
die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch");
|
||||
if (!add_p_opt.auto_advance)
|
||||
die(_("the option '%s' requires '%s'"), "--no-auto-advance", "--patch");
|
||||
}
|
||||
|
||||
ret = do_push_stash(&ps, stash_msg, quiet, keep_index,
|
||||
|
||||
@@ -1441,5 +1441,105 @@ test_expect_success 'EOF quits' '
|
||||
test_grep file out &&
|
||||
test_grep ! file2 out
|
||||
'
|
||||
for cmd in add checkout reset "stash save" "stash push"
|
||||
do
|
||||
test_expect_success "$cmd rejects invalid --no-auto-advance options" '
|
||||
test_must_fail git $cmd --no-auto-advance 2>actual &&
|
||||
test_grep -E "requires .*--(interactive|patch)" actual
|
||||
'
|
||||
done
|
||||
|
||||
test_expect_success 'manual advance (">") moves to next file with --no-auto-advance' '
|
||||
git reset --hard &&
|
||||
echo line1 >first-file &&
|
||||
echo line2 >second-file &&
|
||||
git add -A &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
echo change_first >>first-file &&
|
||||
echo change_second >>second-file &&
|
||||
|
||||
printf ">\nq\n" | git add -p --no-auto-advance >output.test 2>&1 &&
|
||||
test_grep -E "(a|b)/second-file" output.test
|
||||
'
|
||||
|
||||
test_expect_success 'select n on a hunk, go to another file, come back and change to y stages' '
|
||||
git reset --hard &&
|
||||
echo one >f1 &&
|
||||
echo one >f2 &&
|
||||
git add -A &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
echo change1 >>f1 &&
|
||||
echo change2 >>f2 &&
|
||||
|
||||
printf "n\n>\n<\ny\nq\n" | git add -p --no-auto-advance >output.staged 2>&1 &&
|
||||
git diff --cached --name-only >staged &&
|
||||
test_grep -E "(a/f1)" output.staged
|
||||
'
|
||||
|
||||
test_expect_success 'select y on a hunk, go to another file, come back and change to n does not stage' '
|
||||
git reset --hard &&
|
||||
echo one >f1 &&
|
||||
echo one >f2 &&
|
||||
git add -A &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
echo change1 >>f1 &&
|
||||
echo change2 >>f2 &&
|
||||
|
||||
printf "y\n>\n<\nn\nq\n" | git add -p --no-auto-advance >output.unstaged 2>&1 &&
|
||||
git diff --cached --name-only >staged &&
|
||||
test_must_be_empty staged
|
||||
'
|
||||
|
||||
test_expect_success 'deciding all hunks in a file does not auto advance' '
|
||||
git reset --hard &&
|
||||
echo line >stay &&
|
||||
echo line >other &&
|
||||
git add -A &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
echo change >>stay &&
|
||||
echo change >>other &&
|
||||
test_write_lines y | git add -p --no-auto-advance >raw-output 2>&1 &&
|
||||
test_grep "(1/1) Stage this hunk (was: y)" raw-output &&
|
||||
test_grep ! "diff --git a/stay b/stay" raw-output
|
||||
'
|
||||
test_expect_success 'HUNKS SUMMARY does not show in help text when there are undecided hunks' '
|
||||
git reset --hard &&
|
||||
test_write_lines 1 2 3 4 5 6 7 8 9 >f &&
|
||||
git add f &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
test_write_lines 1 X 3 4 Y 6 7 Z 9 >f &&
|
||||
test_write_lines s y n | git add -p --no-auto-advance >raw-nostat 2>&1 &&
|
||||
test_grep ! "HUNKS SUMMARY - Hunks: " raw-nostat
|
||||
'
|
||||
|
||||
test_expect_success 'help text shows HUNK SUMMARY when all hunks have been decided' '
|
||||
git reset --hard &&
|
||||
test_write_lines 1 2 3 4 5 6 7 8 9 >f2 &&
|
||||
git add f2 &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
test_write_lines 1 X 3 4 Y 6 7 Z 9 >f2 &&
|
||||
printf "s\ny\nn\ny\n?\n" | git add -p --no-auto-advance >raw-stat 2>&1 &&
|
||||
test_grep "HUNKS SUMMARY - Hunks: 3, USE: 2, SKIP: 1" raw-stat
|
||||
'
|
||||
|
||||
test_expect_success 'selective staging across multiple files with --no-advance' '
|
||||
git reset --hard &&
|
||||
test_write_lines 1 2 3 4 5 6 7 8 9 >a.file &&
|
||||
test_write_lines 1 2 3 4 5 6 7 8 9 >b.file &&
|
||||
test_write_lines 1 2 3 4 5 6 7 8 9 >c.file &&
|
||||
git add -A &&
|
||||
git commit -m initial >/dev/null 2>&1 &&
|
||||
test_write_lines 1 A2 3 4 A5 6 7 8 9 >a.file &&
|
||||
test_write_lines 1 2 B3 4 5 6 7 B8 9 >b.file &&
|
||||
test_write_lines C1 2 3 4 5 C6 7 8 9 >c.file &&
|
||||
printf "s\ny\nn\n>\ns\nn\ny\n>\ns\ny\ny\nq\n" | git add -p --no-auto-advance >output.index 2>&1 &&
|
||||
git diff --cached >staged.diff &&
|
||||
test_grep "+A2" staged.diff &&
|
||||
test_grep ! "+A5" staged.diff &&
|
||||
test_grep "+B8" staged.diff &&
|
||||
test_grep ! "+B3" staged.diff &&
|
||||
test_grep "+C1" staged.diff &&
|
||||
test_grep "+C6" staged.diff
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -2601,6 +2601,7 @@ test_expect_success 'double dash "git checkout"' '
|
||||
--ignore-skip-worktree-bits Z
|
||||
--ignore-other-worktrees Z
|
||||
--recurse-submodules Z
|
||||
--auto-advance Z
|
||||
--progress Z
|
||||
--guess Z
|
||||
--no-guess Z
|
||||
|
||||
Reference in New Issue
Block a user