1 #define DISABLE_SIGN_COMPARE_WARNINGS
3 #include "git-compat-util.h"
6 #include "read-cache.h"
7 #include "resolve-undo.h"
8 #include "sparse-index.h"
9 #include "string-list.h"
11 /* The only error case is to run out of memory in string-list */
12 void record_resolve_undo(struct index_state
*istate
, struct cache_entry
*ce
)
14 struct string_list_item
*lost
;
15 struct resolve_undo_info
*ui
;
16 struct string_list
*resolve_undo
;
17 int stage
= ce_stage(ce
);
22 if (!istate
->resolve_undo
) {
23 CALLOC_ARRAY(resolve_undo
, 1);
24 resolve_undo
->strdup_strings
= 1;
25 istate
->resolve_undo
= resolve_undo
;
27 resolve_undo
= istate
->resolve_undo
;
28 lost
= string_list_insert(resolve_undo
, ce
->name
);
30 lost
->util
= xcalloc(1, sizeof(*ui
));
32 oidcpy(&ui
->oid
[stage
- 1], &ce
->oid
);
33 ui
->mode
[stage
- 1] = ce
->ce_mode
;
36 void resolve_undo_write(struct strbuf
*sb
, struct string_list
*resolve_undo
,
37 const struct git_hash_algo
*algop
)
39 struct string_list_item
*item
;
40 for_each_string_list_item(item
, resolve_undo
) {
41 struct resolve_undo_info
*ui
= item
->util
;
46 strbuf_addstr(sb
, item
->string
);
48 for (i
= 0; i
< 3; i
++)
49 strbuf_addf(sb
, "%o%c", ui
->mode
[i
], 0);
50 for (i
= 0; i
< 3; i
++) {
53 strbuf_add(sb
, ui
->oid
[i
].hash
, algop
->rawsz
);
58 struct string_list
*resolve_undo_read(const char *data
, unsigned long size
,
59 const struct git_hash_algo
*algop
)
61 struct string_list
*resolve_undo
;
65 const unsigned rawsz
= algop
->rawsz
;
67 CALLOC_ARRAY(resolve_undo
, 1);
68 resolve_undo
->strdup_strings
= 1;
71 struct string_list_item
*lost
;
72 struct resolve_undo_info
*ui
;
74 len
= strlen(data
) + 1;
77 lost
= string_list_insert(resolve_undo
, data
);
79 lost
->util
= xcalloc(1, sizeof(*ui
));
84 for (i
= 0; i
< 3; i
++) {
85 ui
->mode
[i
] = strtoul(data
, &endptr
, 8);
86 if (!endptr
|| endptr
== data
|| *endptr
)
88 len
= (endptr
+ 1) - (char*)data
;
95 for (i
= 0; i
< 3; i
++) {
100 oidread(&ui
->oid
[i
], (const unsigned char *)data
, algop
);
108 string_list_clear(resolve_undo
, 1);
109 error("Index records invalid resolve-undo information");
113 void resolve_undo_clear_index(struct index_state
*istate
)
115 struct string_list
*resolve_undo
= istate
->resolve_undo
;
118 string_list_clear(resolve_undo
, 1);
120 istate
->resolve_undo
= NULL
;
121 istate
->cache_changed
|= RESOLVE_UNDO_CHANGED
;
124 int unmerge_index_entry(struct index_state
*istate
, const char *path
,
125 struct resolve_undo_info
*ru
, unsigned ce_flags
)
127 int i
= index_name_pos(istate
, path
, strlen(path
));
132 if (i
< istate
->cache_nr
&&
133 !strcmp(istate
->cache
[i
]->name
, path
))
134 /* yes, it is already unmerged */
136 /* fallthru: resolved to removal */
138 /* merged - remove it to replace it with unmerged entries */
139 remove_index_entry_at(istate
, i
);
142 for (i
= 0; i
< 3; i
++) {
143 struct cache_entry
*ce
;
146 ce
= make_cache_entry(istate
, ru
->mode
[i
], &ru
->oid
[i
],
148 ce
->ce_flags
|= ce_flags
;
149 if (add_index_entry(istate
, ce
, ADD_CACHE_OK_TO_ADD
))
150 return error("cannot unmerge '%s'", path
);
155 void unmerge_index(struct index_state
*istate
, const struct pathspec
*pathspec
,
158 struct string_list_item
*item
;
160 if (!istate
->resolve_undo
)
163 /* TODO: audit for interaction with sparse-index. */
164 ensure_full_index(istate
);
166 for_each_string_list_item(item
, istate
->resolve_undo
) {
167 const char *path
= item
->string
;
168 struct resolve_undo_info
*ru
= item
->util
;
171 if (!match_pathspec(istate
, pathspec
,
172 item
->string
, strlen(item
->string
),
175 unmerge_index_entry(istate
, path
, ru
, ce_flags
);