summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-10-24 16:10:11 -0700
committerJunio C Hamano <gitster@pobox.com>2016-10-24 16:10:32 -0700
commit95da20413a0392dafe06d352403efa86381252a4 (patch)
tree02182b2c4e905e81a878f4115ec97373a3937bce
parent23415c26fef155f2fa9aebf8a48a6ae457b68c7b (diff)
downloadgit-jc/reset-unmerge.tar.gz
reset: --unmergejc/reset-unmerge
The procedure to resolve a merge conflict typically goes like this: - first open the file in the editor, and with the help of conflict markers come up with a resolution. - save the file. - look at the output from "git diff" to see the combined diff to double check if the resolution makes sense. - perform other tests, like trying to build the result with "make". - finally "git add file" to mark that you are done. and repeating the above until you are done with all the conflicted paths. If you, for whatever reason, accidentally "git add file" by mistake until you are convinced that you resolved it correctly (e.g. doing "git add file" immediately after saving, without a chance to peruse the output from "git diff"), there is no good way to recover. There is "git checkout -m file" but that overwrites the working tree file to reproduce the conflicted state, which is not exactly what you want. You only want to reproduce the conflicted state in the index, so that you can inspect the (proposed) merge resolution you already have in your working tree. Add "git reset --unmerge <paths>" command that does just that. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/reset.c8
-rwxr-xr-xt/t7107-reset-unmerged.sh36
2 files changed, 43 insertions, 1 deletions
diff --git a/builtin/reset.c b/builtin/reset.c
index 9020ec66c8..3aa9e0b34a 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -21,6 +21,7 @@
#include "parse-options.h"
#include "unpack-trees.h"
#include "cache-tree.h"
+#include "resolve-undo.h"
static const char * const git_reset_usage[] = {
N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
@@ -272,6 +273,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
struct object_id oid;
struct pathspec pathspec;
int intent_to_add = 0;
+ int unmerge = 0;
const struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
OPT_SET_INT(0, "mixed", &reset_type,
@@ -286,6 +288,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
OPT_BOOL('N', "intent-to-add", &intent_to_add,
N_("record only the fact that removed paths will be added later")),
+ OPT_BOOL(0, "unmerge", &unmerge,
+ N_("recover conflicted stages from an earlier 'git add'")),
OPT_END()
};
@@ -357,7 +361,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
hold_locked_index(lock, 1);
if (reset_type == MIXED) {
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
- if (read_from_tree(&pathspec, oid.hash, intent_to_add))
+ if (unmerge)
+ unmerge_cache(&pathspec);
+ else if (read_from_tree(&pathspec, oid.hash, intent_to_add))
return 1;
if (get_git_work_tree())
refresh_index(&the_index, flags, NULL, NULL,
diff --git a/t/t7107-reset-unmerged.sh b/t/t7107-reset-unmerged.sh
new file mode 100755
index 0000000000..57b2e27150
--- /dev/null
+++ b/t/t7107-reset-unmerged.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+test_description='git reset with paths'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo one >file &&
+ git add file &&
+ git commit -m "one" &&
+ git tag initial &&
+
+ echo two >file &&
+ git commit -a -m "two" &&
+
+ git checkout -b side initial &&
+ echo three >file &&
+ git commit -a -m "three"
+'
+
+test_expect_success "cause conflict, resolve, and unresolve" '
+ git reset --hard &&
+ git checkout master &&
+ test_must_fail git merge side &&
+
+ git ls-files -u >expect &&
+
+ echo four >file &&
+ git add file &&
+
+ git reset --unmerge -- file &&
+ git ls-files -u >actual &&
+ test_cmp expect actual
+'
+
+test_done