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
);
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
);
27 lost
->util
= xcalloc(1, sizeof(*ui
));
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
;
42 strbuf_addstr(sb
, item
->string
);
44 for (i
= 0; i
< 3; i
++)
45 strbuf_addf(sb
, "%o%c", ui
->mode
[i
], 0);
46 for (i
= 0; i
< 3; i
++) {
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
;
60 const unsigned rawsz
= the_hash_algo
->rawsz
;
62 CALLOC_ARRAY(resolve_undo
, 1);
63 resolve_undo
->strdup_strings
= 1;
66 struct string_list_item
*lost
;
67 struct resolve_undo_info
*ui
;
69 len
= strlen(data
) + 1;
72 lost
= string_list_insert(resolve_undo
, data
);
74 lost
->util
= xcalloc(1, sizeof(*ui
));
79 for (i
= 0; i
< 3; i
++) {
80 ui
->mode
[i
] = strtoul(data
, &endptr
, 8);
81 if (!endptr
|| endptr
== data
|| *endptr
)
83 len
= (endptr
+ 1) - (char*)data
;
90 for (i
= 0; i
< 3; i
++) {
95 oidread(&ui
->oid
[i
], (const unsigned char *)data
);
103 string_list_clear(resolve_undo
, 1);
104 error("Index records invalid resolve-undo information");
108 void resolve_undo_clear_index(struct index_state
*istate
)
110 struct string_list
*resolve_undo
= istate
->resolve_undo
;
113 string_list_clear(resolve_undo
, 1);
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
;
127 if (!istate
->resolve_undo
)
130 ce
= istate
->cache
[pos
];
132 /* already unmerged */
133 while ((pos
< istate
->cache_nr
) &&
134 ! strcmp(istate
->cache
[pos
]->name
, ce
->name
))
136 return pos
- 1; /* return the last entry processed */
138 item
= string_list_lookup(istate
->resolve_undo
, ce
->name
);
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
;
151 nce
= make_cache_entry(istate
,
156 nce
->ce_flags
|= CE_MATCHED
;
157 if (add_index_entry(istate
, nce
, ADD_CACHE_OK_TO_ADD
)) {
159 error("cannot unmerge '%s'", name
);
167 return unmerge_index_entry_at(istate
, pos
);
170 void unmerge_marked_index(struct index_state
*istate
)
174 if (!istate
->resolve_undo
)
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
)
190 if (!istate
->resolve_undo
)
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
))
199 i
= unmerge_index_entry_at(istate
, i
);