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 */
6
+void 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
+
30
+static 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
+
50
+void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
51
+{
52
+ for_each_string_list(write_one, resolve_undo, sb);
53
+}
54
+
55
+struct 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
+
102
+error:
103
+ string_list_clear(resolve_undo, 1);
104
+ error("Index records invalid resolve-undo information");
105
+ return NULL;
106
+}
107
+
108
+void 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
+}