@matheusbsbs / matheus-bagliano / commits / 36bae1dc0e
Fork 0

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>

Johannes Schindelin committed Dec 21, 2019 at 21:57 UTC 36bae1dc0ee777aa529dd955f2e619281265f262
3 files changed +85 -4
add-interactive.h
+2
@@ -25,6 +25,8 @@ int run_add_i(struct repository *r, const struct pathspec *ps);
25
26 enum add_p_mode {
27 ADD_P_ADD,
28 + ADD_P_STASH,
29 + ADD_P_RESET,
30 };
31
32 int run_add_p(struct repository *r, enum add_p_mode mode,
add-patch.c
+79 -4
@@ -19,7 +19,7 @@ struct patch_mode {
19 * trailing `NULL`.
20 */
21 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;
23 const char *prompt_mode[PROMPT_MODE_MAX];
24 const char *edit_hunk_hint, *help_patch_text;
25 };
@@ -45,6 +45,72 @@ static struct patch_mode patch_mode_add = {
45 "the file\n")
46 };
47
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 +
114 struct hunk_header {
115 unsigned long old_offset, old_count, new_offset, new_count;
116 /*
@@ -1350,12 +1416,21 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
1416
1417 init_add_i_state(&s.s, r);
1418
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;
1428 s.revision = revision;
1429
1430 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) ||
1434 parse_diff(&s, ps) < 0) {
1435 strbuf_release(&s.plain);
1436 strbuf_release(&s.colored);
builtin/add.c
+4
@@ -201,6 +201,10 @@ int run_add_interactive(const char *revision, const char *patch_mode,
201
202 if (!strcmp(patch_mode, "--patch"))
203 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;
208 else
209 die("'%s' not yet supported in the built-in add -p",
210 patch_mode);