]> git.ipfire.org Git - thirdparty/git.git/commitdiff
built-in add -p: implement the "stash" and "reset" patch modes
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Sat, 21 Dec 2019 21:57:11 +0000 (21:57 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 22 Dec 2019 00:06:21 +0000 (16:06 -0800)
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>
add-interactive.h
add-patch.c
builtin/add.c

index e29a769aba2c6212cb359cdfdef43fc0ea6bbe17..1f6a61326e9d4f13769edad5eed491e1c8c615fa 100644 (file)
@@ -25,6 +25,8 @@ int run_add_i(struct repository *r, const struct pathspec *ps);
 
 enum add_p_mode {
        ADD_P_ADD,
+       ADD_P_STASH,
+       ADD_P_RESET,
 };
 
 int run_add_p(struct repository *r, enum add_p_mode mode,
index 71356fbd9a56866b71a4d59e3cf2e4395b756f25..af0a86f0f7bd89fdd318035b4e0cc651d2c4982a 100644 (file)
@@ -19,7 +19,7 @@ struct patch_mode {
         * trailing `NULL`.
         */
        const char *diff_cmd[4], *apply_args[4], *apply_check_args[4];
-       unsigned is_reverse:1, apply_for_checkout:1;
+       unsigned is_reverse:1, index_only:1, apply_for_checkout:1;
        const char *prompt_mode[PROMPT_MODE_MAX];
        const char *edit_hunk_hint, *help_patch_text;
 };
@@ -45,6 +45,72 @@ static struct patch_mode patch_mode_add = {
                        "the file\n")
 };
 
+static struct patch_mode patch_mode_stash = {
+       .diff_cmd = { "diff-index", "HEAD", NULL },
+       .apply_args = { "--cached", NULL },
+       .apply_check_args = { "--cached", NULL },
+       .prompt_mode = {
+               N_("Stash mode change [y,n,q,a,d%s,?]? "),
+               N_("Stash deletion [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 "
+                            "will immediately be marked for stashing."),
+       .help_patch_text =
+               N_("y - stash this hunk\n"
+                  "n - do not stash this hunk\n"
+                  "q - quit; do not stash this hunk or any of the remaining "
+                       "ones\n"
+                  "a - stash this hunk and all later hunks in the file\n"
+                  "d - do not stash this hunk or any of the later hunks in "
+                       "the file\n"),
+};
+
+static struct patch_mode patch_mode_reset_head = {
+       .diff_cmd = { "diff-index", "--cached", NULL },
+       .apply_args = { "-R", "--cached", NULL },
+       .apply_check_args = { "-R", "--cached", NULL },
+       .is_reverse = 1,
+       .index_only = 1,
+       .prompt_mode = {
+               N_("Unstage mode change [y,n,q,a,d%s,?]? "),
+               N_("Unstage deletion [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 "
+                            "will immediately be marked for unstaging."),
+       .help_patch_text =
+               N_("y - unstage this hunk\n"
+                  "n - do not unstage this hunk\n"
+                  "q - quit; do not unstage this hunk or any of the remaining "
+                       "ones\n"
+                  "a - unstage this hunk and all later hunks in the file\n"
+                  "d - do not unstage this hunk or any of the later hunks in "
+                       "the file\n"),
+};
+
+static struct patch_mode patch_mode_reset_nothead = {
+       .diff_cmd = { "diff-index", "-R", "--cached", NULL },
+       .apply_args = { "--cached", NULL },
+       .apply_check_args = { "--cached", NULL },
+       .index_only = 1,
+       .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 this hunk to index [y,n,q,a,d%s,?]? "),
+       },
+       .edit_hunk_hint = N_("If the patch applies cleanly, the edited hunk "
+                            "will immediately be marked for applying."),
+       .help_patch_text =
+               N_("y - apply this hunk to index\n"
+                  "n - do not apply this hunk to index\n"
+                  "q - quit; do not apply this hunk or any of the remaining "
+                       "ones\n"
+                  "a - apply this hunk and all later hunks in the file\n"
+                  "d - do not apply this hunk or any of the later hunks in "
+                       "the file\n"),
+};
+
 struct hunk_header {
        unsigned long old_offset, old_count, new_offset, new_count;
        /*
@@ -1350,12 +1416,21 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 
        init_add_i_state(&s.s, r);
 
-       s.mode = &patch_mode_add;
+       if (mode == ADD_P_STASH)
+               s.mode = &patch_mode_stash;
+       else if (mode == ADD_P_RESET) {
+               if (!revision || !strcmp(revision, "HEAD"))
+                       s.mode = &patch_mode_reset_head;
+               else
+                       s.mode = &patch_mode_reset_nothead;
+       } else
+               s.mode = &patch_mode_add;
        s.revision = revision;
 
        if (discard_index(r->index) < 0 || repo_read_index(r) < 0 ||
-           repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,
-                                        NULL, NULL, NULL) < 0 ||
+           (!s.mode->index_only &&
+            repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,
+                                         NULL, NULL, NULL) < 0) ||
            parse_diff(&s, ps) < 0) {
                strbuf_release(&s.plain);
                strbuf_release(&s.colored);
index 006016267e2cca3302770be3c923ef996254da01..b0d6891479438c5830f026badf6058289fd775b1 100644 (file)
@@ -201,6 +201,10 @@ int run_add_interactive(const char *revision, const char *patch_mode,
 
                if (!strcmp(patch_mode, "--patch"))
                        mode = ADD_P_ADD;
+               else if (!strcmp(patch_mode, "--patch=stash"))
+                       mode = ADD_P_STASH;
+               else if (!strcmp(patch_mode, "--patch=reset"))
+                       mode = ADD_P_RESET;
                else
                        die("'%s' not yet supported in the built-in add -p",
                            patch_mode);