]> asedeno.scripts.mit.edu Git - git.git/blobdiff - resolve-undo.c
Merge branch 'aw/git-p4-deletion' into maint
[git.git] / resolve-undo.c
index 86e8547ca25c72f0cce5a4ca2780a3f93dac33ae..72b46125b719861641a55ee8fd534e0d1f47a94f 100644 (file)
@@ -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;
@@ -27,32 +28,28 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
        ui->mode[stage - 1] = ce->ce_mode;
 }
 
-static int write_one(struct string_list_item *item, void *cbdata)
+void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
 {
-       struct strbuf *sb = cbdata;
-       struct resolve_undo_info *ui = item->util;
-       int i;
+       struct string_list_item *item;
+       for_each_string_list_item(item, resolve_undo) {
+               struct resolve_undo_info *ui = item->util;
+               int i;
 
-       if (!ui)
-               return 0;
-       strbuf_addstr(sb, item->string);
-       strbuf_addch(sb, 0);
-       for (i = 0; i < 3; i++)
-               strbuf_addf(sb, "%o%c", ui->mode[i], 0);
-       for (i = 0; i < 3; i++) {
-               if (!ui->mode[i])
+               if (!ui)
                        continue;
-               strbuf_add(sb, ui->sha1[i], 20);
+               strbuf_addstr(sb, item->string);
+               strbuf_addch(sb, 0);
+               for (i = 0; i < 3; i++)
+                       strbuf_addf(sb, "%o%c", ui->mode[i], 0);
+               for (i = 0; i < 3; i++) {
+                       if (!ui->mode[i])
+                               continue;
+                       strbuf_add(sb, ui->sha1[i], 20);
+               }
        }
-       return 0;
 }
 
-void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
-{
-       for_each_string_list(write_one, resolve_undo, 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 +66,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 +89,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 +112,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);
+       }
+}