git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] reset: --unmerge

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 24, 2016, 23:10 UTC
Message-ID
<xmqqa8dttkbw.fsf@gitster.mtv.corp.google.com>
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>
---
 * Not thought through thoroughly yet about details, such as "should
   it always require at least one pathspec?".
 builtin/reset.c           |  8 +++++++-
 t/t7107-reset-unmerged.sh | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
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
Next: Duy Nguyen
Message 1 of 9 in “reset: --unmerge”
  1. reset: --unmergeJunio C Hamano, Oct 24, 2016
  2. Duy NguyenOct 25, 2016
  3. Duy NguyenOct 25, 2016
  4. Junio C HamanoOct 25, 2016
  5. Duy NguyenOct 26, 2016
  6. Junio C HamanoOct 26, 2016
  7. Andreas SchwabOct 27, 2016
  8. Junio C HamanoOct 27, 2016
  9. Sergey OrganovOct 25, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.