Documentation: reset: describe new "--keep" option
[gitweb.git] / builtin-reset.c
index 2c880a7e7acf05f3d1ed162ffc503ca2adbd5298..da61f20e87655583ffb995989cefb19b577e8da6 100644 (file)
 #include "cache-tree.h"
 
 static const char * const git_reset_usage[] = {
-       "git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
+       "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]",
        "git reset [--mixed] <commit> [--] <paths>...",
        NULL
 };
 
-enum reset_type { MIXED, SOFT, HARD, MERGE, NONE };
-static const char *reset_type_names[] = { "mixed", "soft", "hard", "merge", NULL };
+enum reset_type { MIXED, SOFT, HARD, MERGE, KEEP, NONE };
+static const char *reset_type_names[] = {
+       "mixed", "soft", "hard", "merge", "keep", NULL
+};
 
 static char *args_to_str(const char **argv)
 {
@@ -71,6 +73,7 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
        if (!quiet)
                opts.verbose_update = 1;
        switch (reset_type) {
+       case KEEP:
        case MERGE:
                opts.update = 1;
                break;
@@ -85,6 +88,16 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
 
        read_cache_unmerged();
 
+       if (reset_type == KEEP) {
+               unsigned char head_sha1[20];
+               if (get_sha1("HEAD", head_sha1))
+                       return error("You do not have a valid HEAD.");
+               if (!fill_tree_descriptor(desc, head_sha1))
+                       return error("Failed to find tree of HEAD.");
+               nr++;
+               opts.fn = twoway_merge;
+       }
+
        if (!fill_tree_descriptor(desc + nr - 1, sha1))
                return error("Failed to find tree of %s.", sha1_to_hex(sha1));
        if (unpack_trees(nr, desc, &opts))
@@ -221,6 +234,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        struct commit *commit;
        char *reflog_action, msg[1024];
        const struct option options[] = {
+               OPT__QUIET(&quiet),
                OPT_SET_INT(0, "mixed", &reset_type,
                                                "reset HEAD and index", MIXED),
                OPT_SET_INT(0, "soft", &reset_type, "reset only HEAD", SOFT),
@@ -228,8 +242,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
                                "reset HEAD, index and working tree", HARD),
                OPT_SET_INT(0, "merge", &reset_type,
                                "reset HEAD, index and working tree", MERGE),
-               OPT_BOOLEAN('q', NULL, &quiet,
-                               "disable showing new HEAD in hard reset and progress message"),
+               OPT_SET_INT(0, "keep", &reset_type,
+                               "reset HEAD but keep local changes", KEEP),
                OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
                OPT_END()
        };
@@ -305,10 +319,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        if (reset_type == NONE)
                reset_type = MIXED; /* by default */
 
-       if ((reset_type == HARD || reset_type == MERGE)
-           && !is_inside_work_tree())
-               die("%s reset requires a work tree",
-                   reset_type_names[reset_type]);
+       if (reset_type == HARD || reset_type == MERGE)
+               setup_work_tree();
 
        if (reset_type == MIXED && is_bare_repository())
                die("%s reset is not allowed in a bare repository",
@@ -320,9 +332,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        if (reset_type == SOFT) {
                if (is_merge() || read_cache() < 0 || unmerged_cache())
                        die("Cannot do a soft reset in the middle of a merge.");
+       } else {
+               int err = reset_index_file(sha1, reset_type, quiet);
+               if (reset_type == KEEP)
+                       err = err || reset_index_file(sha1, MIXED, quiet);
+               if (err)
+                       die("Could not reset index file to revision '%s'.", rev);
        }
-       else if (reset_index_file(sha1, reset_type, quiet))
-               die("Could not reset index file to revision '%s'.", rev);
 
        /* Any resets update HEAD to the head being switched to,
         * saving the previous head in ORIG_HEAD before. */