Skip to content

Commit 36bae1d

Browse files
dschogitster
authored andcommitted
built-in add -p: implement the "stash" and "reset" patch modes
The `git stash` and `git reset` commands support a `--patch` option, and both simply hand off to `git add -p` to perform that work. Let's teach the built-in version of that command to be able to perform that work, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent d2a233c commit 36bae1d

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

add-interactive.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ int run_add_i(struct repository *r, const struct pathspec *ps);
2525

2626
enum add_p_mode {
2727
ADD_P_ADD,
28+
ADD_P_STASH,
29+
ADD_P_RESET,
2830
};
2931

3032
int run_add_p(struct repository *r, enum add_p_mode mode,

add-patch.c

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct patch_mode {
1919
* trailing `NULL`.
2020
*/
2121
const char *diff_cmd[4], *apply_args[4], *apply_check_args[4];
22-
unsigned is_reverse:1, apply_for_checkout:1;
22+
unsigned is_reverse:1, index_only:1, apply_for_checkout:1;
2323
const char *prompt_mode[PROMPT_MODE_MAX];
2424
const char *edit_hunk_hint, *help_patch_text;
2525
};
@@ -45,6 +45,72 @@ static struct patch_mode patch_mode_add = {
4545
"the file\n")
4646
};
4747

48+
static struct patch_mode patch_mode_stash = {
49+
.diff_cmd = { "diff-index", "HEAD", NULL },
50+
.apply_args = { "--cached", NULL },
51+
.apply_check_args = { "--cached", NULL },
52+
.prompt_mode = {
53+
N_("Stash mode change [y,n,q,a,d%s,?]? "),
54+
N_("Stash deletion [y,n,q,a,d%s,?]? "),
55+
N_("Stash this hunk [y,n,q,a,d%s,?]? "),
56+
},
57+
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
58+
"will immediately be marked for stashing."),
59+
.help_patch_text =
60+
N_("y - stash this hunk\n"
61+
"n - do not stash this hunk\n"
62+
"q - quit; do not stash this hunk or any of the remaining "
63+
"ones\n"
64+
"a - stash this hunk and all later hunks in the file\n"
65+
"d - do not stash this hunk or any of the later hunks in "
66+
"the file\n"),
67+
};
68+
69+
static struct patch_mode patch_mode_reset_head = {
70+
.diff_cmd = { "diff-index", "--cached", NULL },
71+
.apply_args = { "-R", "--cached", NULL },
72+
.apply_check_args = { "-R", "--cached", NULL },
73+
.is_reverse = 1,
74+
.index_only = 1,
75+
.prompt_mode = {
76+
N_("Unstage mode change [y,n,q,a,d%s,?]? "),
77+
N_("Unstage deletion [y,n,q,a,d%s,?]? "),
78+
N_("Unstage this hunk [y,n,q,a,d%s,?]? "),
79+
},
80+
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
81+
"will immediately be marked for unstaging."),
82+
.help_patch_text =
83+
N_("y - unstage this hunk\n"
84+
"n - do not unstage this hunk\n"
85+
"q - quit; do not unstage this hunk or any of the remaining "
86+
"ones\n"
87+
"a - unstage this hunk and all later hunks in the file\n"
88+
"d - do not unstage this hunk or any of the later hunks in "
89+
"the file\n"),
90+
};
91+
92+
static struct patch_mode patch_mode_reset_nothead = {
93+
.diff_cmd = { "diff-index", "-R", "--cached", NULL },
94+
.apply_args = { "--cached", NULL },
95+
.apply_check_args = { "--cached", NULL },
96+
.index_only = 1,
97+
.prompt_mode = {
98+
N_("Apply mode change to index [y,n,q,a,d%s,?]? "),
99+
N_("Apply deletion to index [y,n,q,a,d%s,?]? "),
100+
N_("Apply this hunk to index [y,n,q,a,d%s,?]? "),
101+
},
102+
.edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
103+
"will immediately be marked for applying."),
104+
.help_patch_text =
105+
N_("y - apply this hunk to index\n"
106+
"n - do not apply this hunk to index\n"
107+
"q - quit; do not apply this hunk or any of the remaining "
108+
"ones\n"
109+
"a - apply this hunk and all later hunks in the file\n"
110+
"d - do not apply this hunk or any of the later hunks in "
111+
"the file\n"),
112+
};
113+
48114
struct hunk_header {
49115
unsigned long old_offset, old_count, new_offset, new_count;
50116
/*
@@ -1350,12 +1416,21 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
13501416

13511417
init_add_i_state(&s.s, r);
13521418

1353-
s.mode = &patch_mode_add;
1419+
if (mode == ADD_P_STASH)
1420+
s.mode = &patch_mode_stash;
1421+
else if (mode == ADD_P_RESET) {
1422+
if (!revision || !strcmp(revision, "HEAD"))
1423+
s.mode = &patch_mode_reset_head;
1424+
else
1425+
s.mode = &patch_mode_reset_nothead;
1426+
} else
1427+
s.mode = &patch_mode_add;
13541428
s.revision = revision;
13551429

13561430
if (discard_index(r->index) < 0 || repo_read_index(r) < 0 ||
1357-
repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,
1358-
NULL, NULL, NULL) < 0 ||
1431+
(!s.mode->index_only &&
1432+
repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,
1433+
NULL, NULL, NULL) < 0) ||
13591434
parse_diff(&s, ps) < 0) {
13601435
strbuf_release(&s.plain);
13611436
strbuf_release(&s.colored);

builtin/add.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ int run_add_interactive(const char *revision, const char *patch_mode,
201201

202202
if (!strcmp(patch_mode, "--patch"))
203203
mode = ADD_P_ADD;
204+
else if (!strcmp(patch_mode, "--patch=stash"))
205+
mode = ADD_P_STASH;
206+
else if (!strcmp(patch_mode, "--patch=reset"))
207+
mode = ADD_P_RESET;
204208
else
205209
die("'%s' not yet supported in the built-in add -p",
206210
patch_mode);

0 commit comments

Comments
 (0)