resolve-undo: allow plumbing to clear the information
[git/git.git] / resolve-undo.c
CommitLineData
cfc5789a
JH
1#include "cache.h"
2#include "resolve-undo.h"
3#include "string-list.h"
4
5/* The only error case is to run out of memory in string-list */
6void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
7{
8 struct string_list_item *lost;
9 struct resolve_undo_info *ui;
10 struct string_list *resolve_undo;
11 int stage = ce_stage(ce);
12
13 if (!stage)
14 return;
15
16 if (!istate->resolve_undo) {
17 resolve_undo = xcalloc(1, sizeof(*resolve_undo));
18 resolve_undo->strdup_strings = 1;
19 istate->resolve_undo = resolve_undo;
20 }
21 resolve_undo = istate->resolve_undo;
22 lost = string_list_insert(ce->name, resolve_undo);
23 if (!lost->util)
24 lost->util = xcalloc(1, sizeof(*ui));
25 ui = lost->util;
26 hashcpy(ui->sha1[stage - 1], ce->sha1);
27 ui->mode[stage - 1] = ce->ce_mode;
28}
29
30static int write_one(struct string_list_item *item, void *cbdata)
31{
32 struct strbuf *sb = cbdata;
33 struct resolve_undo_info *ui = item->util;
34 int i;
35
36 if (!ui)
37 return 0;
38 strbuf_addstr(sb, item->string);
39 strbuf_addch(sb, 0);
40 for (i = 0; i < 3; i++)
41 strbuf_addf(sb, "%o%c", ui->mode[i], 0);
42 for (i = 0; i < 3; i++) {
43 if (!ui->mode[i])
44 continue;
45 strbuf_add(sb, ui->sha1[i], 20);
46 }
47 return 0;
48}
49
50void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
51{
52 for_each_string_list(write_one, resolve_undo, sb);
53}
54
55struct string_list *resolve_undo_read(void *data, unsigned long size)
56{
57 struct string_list *resolve_undo;
58 size_t len;
59 char *endptr;
60 int i;
61
62 resolve_undo = xcalloc(1, sizeof(*resolve_undo));
63 resolve_undo->strdup_strings = 1;
64
65 while (size) {
66 struct string_list_item *lost;
67 struct resolve_undo_info *ui;
68
69 len = strlen(data) + 1;
70 if (size <= len)
71 goto error;
72 lost = string_list_insert(data, resolve_undo);
73 if (!lost->util)
74 lost->util = xcalloc(1, sizeof(*ui));
75 ui = lost->util;
76 size -= len;
77 data += len;
78
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;
88 }
89
90 for (i = 0; i < 3; i++) {
91 if (!ui->mode[i])
92 continue;
93 if (size < 20)
94 goto error;
95 hashcpy(ui->sha1[i], data);
96 size -= 20;
97 data += 20;
98 }
99 }
100 return resolve_undo;
101
102error:
103 string_list_clear(resolve_undo, 1);
104 error("Index records invalid resolve-undo information");
105 return NULL;
106}
107
108void resolve_undo_clear_index(struct index_state *istate)
109{
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 = 1;
117}