summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4a39f79)
raw | patch | inline | side by side (parent: 4a39f79)
author | Junio C Hamano <gitster@pobox.com> | |
Fri, 25 Dec 2009 19:57:11 +0000 (11:57 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 26 Dec 2009 01:10:10 +0000 (17:10 -0800) |
Once you resolved conflicts by "git add path", you cannot recreate the
conflicted state with "git checkout -m path", because you lost information
from higher stages in the index when you resolved them.
Since we record the necessary information in the resolve-undo index
extension these days, we can reproduce the unmerged state in the index and
check it out.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
conflicted state with "git checkout -m path", because you lost information
from higher stages in the index when you resolved them.
Since we record the necessary information in the resolve-undo index
extension these days, we can reproduce the unmerged state in the index and
check it out.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-checkout.c | patch | blob | history | |
cache.h | patch | blob | history | |
resolve-undo.c | patch | blob | history | |
resolve-undo.h | patch | blob | history | |
t/t2030-unresolve-info.sh | patch | blob | history |
diff --git a/builtin-checkout.c b/builtin-checkout.c
index a0fe7a4e6d300e347a6c5251f41596a95ee72323..bdef1aa38699e6c74ca30b313406ef093890e902 100644 (file)
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
if (report_path_error(ps_matched, pathspec, 0))
return 1;
+ /* "checkout -m path" to recreate conflicted state */
+ if (opts->merge)
+ unmerge_cache(pathspec);
+
/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
index 310d9e672c8b1a66d5dfaf057db3af9eac028423..f479f091900e684455de122c2b146c174d447ca1 100644 (file)
--- a/cache.h
+++ b/cache.h
#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
#define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))
#define resolve_undo_clear() resolve_undo_clear_index(&the_index)
+#define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)
#endif
enum object_type {
diff --git a/resolve-undo.c b/resolve-undo.c
index 86e8547ca25c72f0cce5a4ca2780a3f93dac33ae..37d73cd949bd884397615d0f6399bd64a88e20a1 100644 (file)
--- a/resolve-undo.c
+++ b/resolve-undo.c
#include "cache.h"
+#include "dir.h"
#include "resolve-undo.h"
#include "string-list.h"
istate->resolve_undo = NULL;
istate->cache_changed = 1;
}
+
+int unmerge_index_entry_at(struct index_state *istate, int pos)
+{
+ struct cache_entry *ce;
+ struct string_list_item *item;
+ struct resolve_undo_info *ru;
+ int i, err = 0;
+
+ if (!istate->resolve_undo)
+ return pos;
+
+ ce = istate->cache[pos];
+ if (ce_stage(ce)) {
+ /* already unmerged */
+ while ((pos < istate->cache_nr) &&
+ ! strcmp(istate->cache[pos]->name, ce->name))
+ pos++;
+ return pos - 1; /* return the last entry processed */
+ }
+ item = string_list_lookup(ce->name, istate->resolve_undo);
+ if (!item)
+ return pos;
+ ru = item->util;
+ if (!ru)
+ return pos;
+ remove_index_entry_at(istate, pos);
+ for (i = 0; i < 3; i++) {
+ struct cache_entry *nce;
+ if (!ru->mode[i])
+ continue;
+ nce = make_cache_entry(ru->mode[i], ru->sha1[i],
+ ce->name, i + 1, 0);
+ if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
+ err = 1;
+ error("cannot unmerge '%s'", ce->name);
+ }
+ }
+ if (err)
+ return pos;
+ free(ru);
+ item->util = NULL;
+ return unmerge_index_entry_at(istate, pos);
+}
+
+void unmerge_index(struct index_state *istate, const char **pathspec)
+{
+ int i;
+
+ if (!istate->resolve_undo)
+ return;
+
+ for (i = 0; i < istate->cache_nr; i++) {
+ struct cache_entry *ce = istate->cache[i];
+ if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+ continue;
+ i = unmerge_index_entry_at(istate, i);
+ }
+}
diff --git a/resolve-undo.h b/resolve-undo.h
index 74194d0eba7d6dca49fefff11ed8089b49363650..e4e5c1b1ad5b3fc7d5a2d516ab3ccccb3e88b993 100644 (file)
--- a/resolve-undo.h
+++ b/resolve-undo.h
extern void resolve_undo_write(struct strbuf *, struct string_list *);
extern struct string_list *resolve_undo_read(void *, unsigned long);
extern void resolve_undo_clear_index(struct index_state *);
+extern int unmerge_index_entry_at(struct index_state *, int);
+extern void unmerge_index(struct index_state *, const char **);
#endif
index 984480271c0deef50dddae215a59aa62471c0e47..ea65f391c1671b141d2d071aad0f7df7ca4ea4ac 100755 (executable)
check_resolve_undo cleared
'
+test_expect_success 'add records checkout -m undoes' '
+ prime_resolve_undo &&
+ git diff HEAD &&
+ git checkout --conflict=merge file &&
+ echo checkout used the record and removed it &&
+ check_resolve_undo removed &&
+ echo the index and the work tree is unmerged again &&
+ git diff >actual &&
+ grep "^++<<<<<<<" actual
+'
+
test_done