sparse-index.h: move declarations for sparse-index.c from cache.h
[git/debian.git] / resolve-undo.c
blob7ec09e89d4f8662f29a12350df6be517750ad8f5
1 #include "cache.h"
2 #include "dir.h"
3 #include "hash.h"
4 #include "resolve-undo.h"
5 #include "sparse-index.h"
6 #include "string-list.h"
8 /* The only error case is to run out of memory in string-list */
9 void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
11 struct string_list_item *lost;
12 struct resolve_undo_info *ui;
13 struct string_list *resolve_undo;
14 int stage = ce_stage(ce);
16 if (!stage)
17 return;
19 if (!istate->resolve_undo) {
20 CALLOC_ARRAY(resolve_undo, 1);
21 resolve_undo->strdup_strings = 1;
22 istate->resolve_undo = resolve_undo;
24 resolve_undo = istate->resolve_undo;
25 lost = string_list_insert(resolve_undo, ce->name);
26 if (!lost->util)
27 lost->util = xcalloc(1, sizeof(*ui));
28 ui = lost->util;
29 oidcpy(&ui->oid[stage - 1], &ce->oid);
30 ui->mode[stage - 1] = ce->ce_mode;
33 void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
35 struct string_list_item *item;
36 for_each_string_list_item(item, resolve_undo) {
37 struct resolve_undo_info *ui = item->util;
38 int i;
40 if (!ui)
41 continue;
42 strbuf_addstr(sb, item->string);
43 strbuf_addch(sb, 0);
44 for (i = 0; i < 3; i++)
45 strbuf_addf(sb, "%o%c", ui->mode[i], 0);
46 for (i = 0; i < 3; i++) {
47 if (!ui->mode[i])
48 continue;
49 strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
54 struct string_list *resolve_undo_read(const char *data, unsigned long size)
56 struct string_list *resolve_undo;
57 size_t len;
58 char *endptr;
59 int i;
60 const unsigned rawsz = the_hash_algo->rawsz;
62 CALLOC_ARRAY(resolve_undo, 1);
63 resolve_undo->strdup_strings = 1;
65 while (size) {
66 struct string_list_item *lost;
67 struct resolve_undo_info *ui;
69 len = strlen(data) + 1;
70 if (size <= len)
71 goto error;
72 lost = string_list_insert(resolve_undo, data);
73 if (!lost->util)
74 lost->util = xcalloc(1, sizeof(*ui));
75 ui = lost->util;
76 size -= len;
77 data += len;
79 for (i = 0; i < 3; i++) {
80 ui->mode[i] = strtoul(data, &endptr, 8);
81 if (!endptr || endptr == data || *endptr)
82 goto error;
83 len = (endptr + 1) - (char*)data;
84 if (size <= len)
85 goto error;
86 size -= len;
87 data += len;
90 for (i = 0; i < 3; i++) {
91 if (!ui->mode[i])
92 continue;
93 if (size < rawsz)
94 goto error;
95 oidread(&ui->oid[i], (const unsigned char *)data);
96 size -= rawsz;
97 data += rawsz;
100 return resolve_undo;
102 error:
103 string_list_clear(resolve_undo, 1);
104 error("Index records invalid resolve-undo information");
105 return NULL;
108 void resolve_undo_clear_index(struct index_state *istate)
110 struct string_list *resolve_undo = istate->resolve_undo;
111 if (!resolve_undo)
112 return;
113 string_list_clear(resolve_undo, 1);
114 free(resolve_undo);
115 istate->resolve_undo = NULL;
116 istate->cache_changed |= RESOLVE_UNDO_CHANGED;
119 int unmerge_index_entry_at(struct index_state *istate, int pos)
121 const struct cache_entry *ce;
122 struct string_list_item *item;
123 struct resolve_undo_info *ru;
124 int i, err = 0, matched;
125 char *name;
127 if (!istate->resolve_undo)
128 return pos;
130 ce = istate->cache[pos];
131 if (ce_stage(ce)) {
132 /* already unmerged */
133 while ((pos < istate->cache_nr) &&
134 ! strcmp(istate->cache[pos]->name, ce->name))
135 pos++;
136 return pos - 1; /* return the last entry processed */
138 item = string_list_lookup(istate->resolve_undo, ce->name);
139 if (!item)
140 return pos;
141 ru = item->util;
142 if (!ru)
143 return pos;
144 matched = ce->ce_flags & CE_MATCHED;
145 name = xstrdup(ce->name);
146 remove_index_entry_at(istate, pos);
147 for (i = 0; i < 3; i++) {
148 struct cache_entry *nce;
149 if (!ru->mode[i])
150 continue;
151 nce = make_cache_entry(istate,
152 ru->mode[i],
153 &ru->oid[i],
154 name, i + 1, 0);
155 if (matched)
156 nce->ce_flags |= CE_MATCHED;
157 if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
158 err = 1;
159 error("cannot unmerge '%s'", name);
162 free(name);
163 if (err)
164 return pos;
165 free(ru);
166 item->util = NULL;
167 return unmerge_index_entry_at(istate, pos);
170 void unmerge_marked_index(struct index_state *istate)
172 int i;
174 if (!istate->resolve_undo)
175 return;
177 /* TODO: audit for interaction with sparse-index. */
178 ensure_full_index(istate);
179 for (i = 0; i < istate->cache_nr; i++) {
180 const struct cache_entry *ce = istate->cache[i];
181 if (ce->ce_flags & CE_MATCHED)
182 i = unmerge_index_entry_at(istate, i);
186 void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
188 int i;
190 if (!istate->resolve_undo)
191 return;
193 /* TODO: audit for interaction with sparse-index. */
194 ensure_full_index(istate);
195 for (i = 0; i < istate->cache_nr; i++) {
196 const struct cache_entry *ce = istate->cache[i];
197 if (!ce_path_match(istate, ce, pathspec, NULL))
198 continue;
199 i = unmerge_index_entry_at(istate, i);