]> git.ipfire.org Git - thirdparty/git.git/blame - resolve-undo.c
setup: adopt shared init-db & clone code
[thirdparty/git.git] / resolve-undo.c
CommitLineData
cfc5789a 1#include "cache.h"
4421a823 2#include "dir.h"
d1cbe1e6 3#include "hash.h"
cfc5789a
JH
4#include "resolve-undo.h"
5#include "string-list.h"
6
7/* The only error case is to run out of memory in string-list */
8void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
9{
10 struct string_list_item *lost;
11 struct resolve_undo_info *ui;
12 struct string_list *resolve_undo;
13 int stage = ce_stage(ce);
14
15 if (!stage)
16 return;
17
18 if (!istate->resolve_undo) {
ca56dadb 19 CALLOC_ARRAY(resolve_undo, 1);
cfc5789a
JH
20 resolve_undo->strdup_strings = 1;
21 istate->resolve_undo = resolve_undo;
22 }
23 resolve_undo = istate->resolve_undo;
78a395d3 24 lost = string_list_insert(resolve_undo, ce->name);
cfc5789a
JH
25 if (!lost->util)
26 lost->util = xcalloc(1, sizeof(*ui));
27 ui = lost->util;
5ac913c6 28 oidcpy(&ui->oid[stage - 1], &ce->oid);
cfc5789a
JH
29 ui->mode[stage - 1] = ce->ce_mode;
30}
31
8a57c6e9 32void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
cfc5789a 33{
8a57c6e9
AR
34 struct string_list_item *item;
35 for_each_string_list_item(item, resolve_undo) {
36 struct resolve_undo_info *ui = item->util;
37 int i;
cfc5789a 38
8a57c6e9 39 if (!ui)
cfc5789a 40 continue;
8a57c6e9
AR
41 strbuf_addstr(sb, item->string);
42 strbuf_addch(sb, 0);
43 for (i = 0; i < 3; i++)
44 strbuf_addf(sb, "%o%c", ui->mode[i], 0);
45 for (i = 0; i < 3; i++) {
46 if (!ui->mode[i])
47 continue;
5ac913c6 48 strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
8a57c6e9 49 }
cfc5789a 50 }
cfc5789a
JH
51}
52
b8bba419 53struct string_list *resolve_undo_read(const char *data, unsigned long size)
cfc5789a
JH
54{
55 struct string_list *resolve_undo;
56 size_t len;
57 char *endptr;
58 int i;
5ac913c6 59 const unsigned rawsz = the_hash_algo->rawsz;
cfc5789a 60
ca56dadb 61 CALLOC_ARRAY(resolve_undo, 1);
cfc5789a
JH
62 resolve_undo->strdup_strings = 1;
63
64 while (size) {
65 struct string_list_item *lost;
66 struct resolve_undo_info *ui;
67
68 len = strlen(data) + 1;
69 if (size <= len)
70 goto error;
78a395d3 71 lost = string_list_insert(resolve_undo, data);
cfc5789a
JH
72 if (!lost->util)
73 lost->util = xcalloc(1, sizeof(*ui));
74 ui = lost->util;
75 size -= len;
76 data += len;
77
78 for (i = 0; i < 3; i++) {
79 ui->mode[i] = strtoul(data, &endptr, 8);
80 if (!endptr || endptr == data || *endptr)
81 goto error;
82 len = (endptr + 1) - (char*)data;
83 if (size <= len)
84 goto error;
85 size -= len;
86 data += len;
87 }
88
89 for (i = 0; i < 3; i++) {
90 if (!ui->mode[i])
91 continue;
5ac913c6 92 if (size < rawsz)
cfc5789a 93 goto error;
69d12425 94 oidread(&ui->oid[i], (const unsigned char *)data);
5ac913c6 95 size -= rawsz;
96 data += rawsz;
cfc5789a
JH
97 }
98 }
99 return resolve_undo;
100
101error:
102 string_list_clear(resolve_undo, 1);
103 error("Index records invalid resolve-undo information");
104 return NULL;
105}
106
107void resolve_undo_clear_index(struct index_state *istate)
108{
109 struct string_list *resolve_undo = istate->resolve_undo;
110 if (!resolve_undo)
111 return;
112 string_list_clear(resolve_undo, 1);
113 free(resolve_undo);
114 istate->resolve_undo = NULL;
6c306a34 115 istate->cache_changed |= RESOLVE_UNDO_CHANGED;
cfc5789a 116}
4421a823
JH
117
118int unmerge_index_entry_at(struct index_state *istate, int pos)
119{
9c5e6c80 120 const struct cache_entry *ce;
4421a823
JH
121 struct string_list_item *item;
122 struct resolve_undo_info *ru;
e721c154 123 int i, err = 0, matched;
5699d17e 124 char *name;
4421a823
JH
125
126 if (!istate->resolve_undo)
127 return pos;
128
129 ce = istate->cache[pos];
130 if (ce_stage(ce)) {
131 /* already unmerged */
132 while ((pos < istate->cache_nr) &&
133 ! strcmp(istate->cache[pos]->name, ce->name))
134 pos++;
135 return pos - 1; /* return the last entry processed */
136 }
e8c8b713 137 item = string_list_lookup(istate->resolve_undo, ce->name);
4421a823
JH
138 if (!item)
139 return pos;
140 ru = item->util;
141 if (!ru)
142 return pos;
e721c154 143 matched = ce->ce_flags & CE_MATCHED;
5699d17e 144 name = xstrdup(ce->name);
4421a823
JH
145 remove_index_entry_at(istate, pos);
146 for (i = 0; i < 3; i++) {
147 struct cache_entry *nce;
148 if (!ru->mode[i])
149 continue;
a849735b
JM
150 nce = make_cache_entry(istate,
151 ru->mode[i],
152 &ru->oid[i],
5699d17e 153 name, i + 1, 0);
e721c154
NTND
154 if (matched)
155 nce->ce_flags |= CE_MATCHED;
4421a823
JH
156 if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
157 err = 1;
5699d17e 158 error("cannot unmerge '%s'", name);
4421a823
JH
159 }
160 }
5699d17e 161 free(name);
4421a823
JH
162 if (err)
163 return pos;
164 free(ru);
165 item->util = NULL;
166 return unmerge_index_entry_at(istate, pos);
167}
168
e721c154
NTND
169void unmerge_marked_index(struct index_state *istate)
170{
171 int i;
172
173 if (!istate->resolve_undo)
174 return;
175
dc26b23e
DS
176 /* TODO: audit for interaction with sparse-index. */
177 ensure_full_index(istate);
e721c154 178 for (i = 0; i < istate->cache_nr; i++) {
9c5e6c80 179 const struct cache_entry *ce = istate->cache[i];
e721c154
NTND
180 if (ce->ce_flags & CE_MATCHED)
181 i = unmerge_index_entry_at(istate, i);
182 }
183}
184
5ab06518 185void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
4421a823
JH
186{
187 int i;
188
189 if (!istate->resolve_undo)
190 return;
191
dc26b23e
DS
192 /* TODO: audit for interaction with sparse-index. */
193 ensure_full_index(istate);
4421a823 194 for (i = 0; i < istate->cache_nr; i++) {
9c5e6c80 195 const struct cache_entry *ce = istate->cache[i];
ff82d126 196 if (!ce_path_match(istate, ce, pathspec, NULL))
4421a823
JH
197 continue;
198 i = unmerge_index_entry_at(istate, i);
199 }
200}