X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=resolve-undo.c;h=174ebec9e573b1942e379942037f38500bd19b97;hb=fc051572a3fe171286f10761bd33946c48de3f7f;hp=86e8547ca25c72f0cce5a4ca2780a3f93dac33ae;hpb=cfc5789ada444423232fa1533f401b5972eb3f6c;p=git.git diff --git a/resolve-undo.c b/resolve-undo.c index 86e8547ca..174ebec9e 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "dir.h" #include "resolve-undo.h" #include "string-list.h" @@ -19,7 +20,7 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce) istate->resolve_undo = resolve_undo; } resolve_undo = istate->resolve_undo; - lost = string_list_insert(ce->name, resolve_undo); + lost = string_list_insert(resolve_undo, ce->name); if (!lost->util) lost->util = xcalloc(1, sizeof(*ui)); ui = lost->util; @@ -49,10 +50,10 @@ static int write_one(struct string_list_item *item, void *cbdata) void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo) { - for_each_string_list(write_one, resolve_undo, sb); + for_each_string_list(resolve_undo, write_one, sb); } -struct string_list *resolve_undo_read(void *data, unsigned long size) +struct string_list *resolve_undo_read(const char *data, unsigned long size) { struct string_list *resolve_undo; size_t len; @@ -69,7 +70,7 @@ struct string_list *resolve_undo_read(void *data, unsigned long size) len = strlen(data) + 1; if (size <= len) goto error; - lost = string_list_insert(data, resolve_undo); + lost = string_list_insert(resolve_undo, data); if (!lost->util) lost->util = xcalloc(1, sizeof(*ui)); ui = lost->util; @@ -92,7 +93,7 @@ struct string_list *resolve_undo_read(void *data, unsigned long size) continue; if (size < 20) goto error; - hashcpy(ui->sha1[i], data); + hashcpy(ui->sha1[i], (const unsigned char *)data); size -= 20; data += 20; } @@ -115,3 +116,61 @@ void resolve_undo_clear_index(struct index_state *istate) 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(istate->resolve_undo, ce->name); + 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); + } +}