]> git.ipfire.org Git - thirdparty/git.git/blame - rerere.c
treewide: be explicit about dependence on gettext.h
[thirdparty/git.git] / rerere.c
CommitLineData
36bf1958
EN
1#include "git-compat-util.h"
2#include "alloc.h"
b2141fc1 3#include "config.h"
f394e093 4#include "gettext.h"
41771fa4 5#include "hex.h"
697cc8ef 6#include "lockfile.h"
c455c87c 7#include "string-list.h"
5b2fd956 8#include "rerere.h"
5b2fd956 9#include "xdiff-interface.h"
dea4562b
JH
10#include "dir.h"
11#include "resolve-undo.h"
12#include "ll-merge.h"
8588567c 13#include "attr.h"
01a10b0a 14#include "pathspec.h"
cbd53a21 15#include "object-store.h"
bc626927 16#include "hash-lookup.h"
680ff910 17#include "strmap.h"
5b2fd956 18
ac49f5ca
MZ
19#define RESOLVED 0
20#define PUNTED 1
21#define THREE_STAGED 2
22void *RERERE_RESOLVED = &RERERE_RESOLVED;
23
5b2fd956
SB
24/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
25static int rerere_enabled = -1;
26
27/* automatically update cleanly resolved paths to the index */
28static int rerere_autoupdate;
29
2c7929b1
JH
30#define RR_HAS_POSTIMAGE 1
31#define RR_HAS_PREIMAGE 2
680ff910 32struct rerere_dir {
a13d1370
JH
33 int status_alloc, status_nr;
34 unsigned char *status;
680ff910
JK
35 char name[FLEX_ARRAY];
36};
37
38static struct strmap rerere_dirs = STRMAP_INIT;
1869bbe1
JH
39
40static void free_rerere_dirs(void)
41{
680ff910
JK
42 struct hashmap_iter iter;
43 struct strmap_entry *ent;
44
45 strmap_for_each_entry(&rerere_dirs, &iter, ent) {
46 struct rerere_dir *rr_dir = ent->value;
47 free(rr_dir->status);
48 free(rr_dir);
a13d1370 49 }
680ff910 50 strmap_clear(&rerere_dirs, 0);
1869bbe1
JH
51}
52
1d51eced 53static void free_rerere_id(struct string_list_item *item)
5b2fd956 54{
1d51eced 55 free(item->util);
5b2fd956
SB
56}
57
1d51eced
JH
58static const char *rerere_id_hex(const struct rerere_id *id)
59{
680ff910 60 return id->collection->name;
1d51eced
JH
61}
62
a13d1370
JH
63static void fit_variant(struct rerere_dir *rr_dir, int variant)
64{
65 variant++;
66 ALLOC_GROW(rr_dir->status, variant, rr_dir->status_alloc);
67 if (rr_dir->status_nr < variant) {
68 memset(rr_dir->status + rr_dir->status_nr,
69 '\0', variant - rr_dir->status_nr);
70 rr_dir->status_nr = variant;
71 }
72}
73
74static void assign_variant(struct rerere_id *id)
75{
76 int variant;
77 struct rerere_dir *rr_dir = id->collection;
78
79 variant = id->variant;
80 if (variant < 0) {
629716d2
JH
81 for (variant = 0; variant < rr_dir->status_nr; variant++)
82 if (!rr_dir->status[variant])
83 break;
a13d1370
JH
84 }
85 fit_variant(rr_dir, variant);
86 id->variant = variant;
1d51eced
JH
87}
88
89const char *rerere_path(const struct rerere_id *id, const char *file)
90{
91 if (!file)
92 return git_path("rr-cache/%s", rerere_id_hex(id));
93
a13d1370
JH
94 if (id->variant <= 0)
95 return git_path("rr-cache/%s/%s", rerere_id_hex(id), file);
96
97 return git_path("rr-cache/%s/%s.%d",
98 rerere_id_hex(id), file, id->variant);
5b2fd956
SB
99}
100
a13d1370 101static int is_rr_file(const char *name, const char *filename, int *variant)
2c7929b1 102{
a13d1370
JH
103 const char *suffix;
104 char *ep;
105
106 if (!strcmp(name, filename)) {
107 *variant = 0;
108 return 1;
109 }
110 if (!skip_prefix(name, filename, &suffix) || *suffix != '.')
111 return 0;
112
113 errno = 0;
114 *variant = strtol(suffix + 1, &ep, 10);
115 if (errno || *ep)
116 return 0;
117 return 1;
2c7929b1
JH
118}
119
120static void scan_rerere_dir(struct rerere_dir *rr_dir)
121{
122 struct dirent *de;
680ff910 123 DIR *dir = opendir(git_path("rr-cache/%s", rr_dir->name));
2c7929b1
JH
124
125 if (!dir)
126 return;
127 while ((de = readdir(dir)) != NULL) {
a13d1370
JH
128 int variant;
129
130 if (is_rr_file(de->d_name, "postimage", &variant)) {
131 fit_variant(rr_dir, variant);
132 rr_dir->status[variant] |= RR_HAS_POSTIMAGE;
133 } else if (is_rr_file(de->d_name, "preimage", &variant)) {
134 fit_variant(rr_dir, variant);
135 rr_dir->status[variant] |= RR_HAS_PREIMAGE;
136 }
2c7929b1
JH
137 }
138 closedir(dir);
139}
140
1869bbe1
JH
141static struct rerere_dir *find_rerere_dir(const char *hex)
142{
1869bbe1 143 struct rerere_dir *rr_dir;
680ff910
JK
144
145 rr_dir = strmap_get(&rerere_dirs, hex);
146 if (!rr_dir) {
147 FLEX_ALLOC_STR(rr_dir, name, hex);
a13d1370
JH
148 rr_dir->status = NULL;
149 rr_dir->status_nr = 0;
150 rr_dir->status_alloc = 0;
680ff910
JK
151 strmap_put(&rerere_dirs, hex, rr_dir);
152
2c7929b1 153 scan_rerere_dir(rr_dir);
1869bbe1 154 }
680ff910 155 return rr_dir;
5b2fd956
SB
156}
157
1d51eced 158static int has_rerere_resolution(const struct rerere_id *id)
5b2fd956 159{
05dd9f13 160 const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE;
a13d1370 161 int variant = id->variant;
1d51eced 162
a13d1370
JH
163 if (variant < 0)
164 return 0;
165 return ((id->collection->status[variant] & both) == both);
5b2fd956
SB
166}
167
1d51eced
JH
168static struct rerere_id *new_rerere_id_hex(char *hex)
169{
170 struct rerere_id *id = xmalloc(sizeof(*id));
1869bbe1 171 id->collection = find_rerere_dir(hex);
a13d1370 172 id->variant = -1; /* not known yet */
1d51eced
JH
173 return id;
174}
175
3f34d70d 176static struct rerere_id *new_rerere_id(unsigned char *hash)
1d51eced 177{
3f34d70d 178 return new_rerere_id_hex(hash_to_hex(hash));
5b2fd956
SB
179}
180
4b68c2a0
JH
181/*
182 * $GIT_DIR/MERGE_RR file is a collection of records, each of which is
183 * "conflict ID", a HT and pathname, terminated with a NUL, and is
184 * used to keep track of the set of paths that "rerere" may need to
185 * work on (i.e. what is left by the previous invocation of "git
186 * rerere" during the current conflict resolution session).
187 */
55e6b354 188static void read_rr(struct repository *r, struct string_list *rr)
5b2fd956 189{
f5800f6a 190 struct strbuf buf = STRBUF_INIT;
55e6b354 191 FILE *in = fopen_or_warn(git_path_merge_rr(r), "r");
f5800f6a 192
5b2fd956
SB
193 if (!in)
194 return;
f5800f6a
JH
195 while (!strbuf_getwholeline(&buf, in, '\0')) {
196 char *path;
0d7c419a 197 unsigned char hash[GIT_MAX_RAWSZ];
1d51eced 198 struct rerere_id *id;
a13d1370 199 int variant;
0d7c419a 200 const unsigned hexsz = the_hash_algo->hexsz;
f5800f6a
JH
201
202 /* There has to be the hash, tab, path and then NUL */
0d7c419a 203 if (buf.len < hexsz + 2 || get_sha1_hex(buf.buf, hash))
2373b650 204 die(_("corrupt MERGE_RR"));
f5800f6a 205
0d7c419a 206 if (buf.buf[hexsz] != '.') {
a13d1370 207 variant = 0;
0d7c419a 208 path = buf.buf + hexsz;
a13d1370
JH
209 } else {
210 errno = 0;
0d7c419a 211 variant = strtol(buf.buf + hexsz + 1, &path, 10);
a13d1370 212 if (errno)
2373b650 213 die(_("corrupt MERGE_RR"));
a13d1370
JH
214 }
215 if (*(path++) != '\t')
2373b650 216 die(_("corrupt MERGE_RR"));
0d7c419a 217 buf.buf[hexsz] = '\0';
1d51eced 218 id = new_rerere_id_hex(buf.buf);
a13d1370 219 id->variant = variant;
1d51eced 220 string_list_insert(rr, path)->util = id;
5b2fd956 221 }
f5800f6a 222 strbuf_release(&buf);
5b2fd956
SB
223 fclose(in);
224}
225
226static struct lock_file write_lock;
227
c455c87c 228static int write_rr(struct string_list *rr, int out_fd)
5b2fd956
SB
229{
230 int i;
231 for (i = 0; i < rr->nr; i++) {
e2cb6a95 232 struct strbuf buf = STRBUF_INIT;
1d51eced 233 struct rerere_id *id;
e2cb6a95
JH
234
235 assert(rr->items[i].util != RERERE_RESOLVED);
1d51eced
JH
236
237 id = rr->items[i].util;
238 if (!id)
5b2fd956 239 continue;
a13d1370
JH
240 assert(id->variant >= 0);
241 if (0 < id->variant)
242 strbuf_addf(&buf, "%s.%d\t%s%c",
243 rerere_id_hex(id), id->variant,
244 rr->items[i].string, 0);
245 else
246 strbuf_addf(&buf, "%s\t%s%c",
247 rerere_id_hex(id),
248 rr->items[i].string, 0);
249
06f46f23 250 if (write_in_full(out_fd, buf.buf, buf.len) < 0)
2373b650 251 die(_("unable to write rerere record"));
e2cb6a95
JH
252
253 strbuf_release(&buf);
5b2fd956
SB
254 }
255 if (commit_lock_file(&write_lock) != 0)
2373b650 256 die(_("unable to write rerere record"));
5b2fd956
SB
257 return 0;
258}
259
a96847cc
JH
260/*
261 * "rerere" interacts with conflicted file contents using this I/O
262 * abstraction. It reads a conflicted contents from one place via
263 * "getline()" method, and optionally can write it out after
264 * normalizing the conflicted hunks to the "output". Subclasses of
265 * rerere_io embed this structure at the beginning of their own
266 * rerere_io object.
267 */
268struct rerere_io {
269 int (*getline)(struct strbuf *, struct rerere_io *);
270 FILE *output;
271 int wrerror;
272 /* some more stuff */
273};
274
47d32af2
AR
275static void ferr_write(const void *p, size_t count, FILE *fp, int *err)
276{
277 if (!count || *err)
278 return;
279 if (fwrite(p, count, 1, fp) != 1)
280 *err = errno;
281}
282
283static inline void ferr_puts(const char *s, FILE *fp, int *err)
284{
285 ferr_write(s, strlen(s), fp, err);
286}
287
27d6b085
JH
288static void rerere_io_putstr(const char *str, struct rerere_io *io)
289{
290 if (io->output)
291 ferr_puts(str, io->output, &io->wrerror);
292}
293
294static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io)
295{
296 if (io->output)
297 ferr_write(mem, sz, io->output, &io->wrerror);
298}
299
a96847cc
JH
300/*
301 * Subclass of rerere_io that reads from an on-disk file
302 */
27d6b085
JH
303struct rerere_io_file {
304 struct rerere_io io;
305 FILE *input;
306};
307
a96847cc
JH
308/*
309 * ... and its getline() method implementation
310 */
27d6b085
JH
311static int rerere_file_getline(struct strbuf *sb, struct rerere_io *io_)
312{
313 struct rerere_io_file *io = (struct rerere_io_file *)io_;
314 return strbuf_getwholeline(sb, io->input, '\n');
315}
316
67711cdc
JH
317/*
318 * Require the exact number of conflict marker letters, no more, no
319 * less, followed by SP or any whitespace
320 * (including LF).
321 */
322static int is_cmarker(char *buf, int marker_char, int marker_size)
191f2417 323{
67711cdc
JH
324 int want_sp;
325
326 /*
327 * The beginning of our version and the end of their version
328 * always are labeled like "<<<<< ours" or ">>>>> theirs",
329 * hence we set want_sp for them. Note that the version from
330 * the common ancestor in diff3-style output is not always
331 * labelled (e.g. "||||| common" is often seen but "|||||"
332 * alone is also valid), so we do not set want_sp.
333 */
334 want_sp = (marker_char == '<') || (marker_char == '>');
335
191f2417
JH
336 while (marker_size--)
337 if (*buf++ != marker_char)
338 return 0;
339 if (want_sp && *buf != ' ')
340 return 0;
341 return isspace(*buf);
342}
343
5ebbdad3
TG
344static void rerere_strbuf_putconflict(struct strbuf *buf, int ch, size_t size)
345{
346 strbuf_addchars(buf, ch, size);
347 strbuf_addch(buf, '\n');
348}
349
350static int handle_conflict(struct strbuf *out, struct rerere_io *io,
0d7c419a 351 int marker_size, git_hash_ctx *ctx)
5b2fd956 352{
cc58d7df 353 enum {
c0f16f8e
TG
354 RR_SIDE_1 = 0, RR_SIDE_2, RR_ORIGINAL
355 } hunk = RR_SIDE_1;
f285a2d7 356 struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
4af32207 357 struct strbuf buf = STRBUF_INIT, conflict = STRBUF_INIT;
c0f16f8e 358 int has_conflicts = -1;
5b2fd956 359
27d6b085 360 while (!io->getline(&buf, io)) {
67711cdc 361 if (is_cmarker(buf.buf, '<', marker_size)) {
4af32207
TG
362 if (handle_conflict(&conflict, io, marker_size, NULL) < 0)
363 break;
364 if (hunk == RR_SIDE_1)
365 strbuf_addbuf(&one, &conflict);
366 else
367 strbuf_addbuf(&two, &conflict);
368 strbuf_release(&conflict);
67711cdc 369 } else if (is_cmarker(buf.buf, '|', marker_size)) {
cc58d7df 370 if (hunk != RR_SIDE_1)
c0f16f8e 371 break;
387c9d49 372 hunk = RR_ORIGINAL;
67711cdc 373 } else if (is_cmarker(buf.buf, '=', marker_size)) {
387c9d49 374 if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
c0f16f8e 375 break;
cc58d7df 376 hunk = RR_SIDE_2;
67711cdc 377 } else if (is_cmarker(buf.buf, '>', marker_size)) {
cc58d7df 378 if (hunk != RR_SIDE_2)
c0f16f8e 379 break;
5b2fd956
SB
380 if (strbuf_cmp(&one, &two) > 0)
381 strbuf_swap(&one, &two);
221444f5 382 has_conflicts = 1;
5ebbdad3
TG
383 rerere_strbuf_putconflict(out, '<', marker_size);
384 strbuf_addbuf(out, &one);
385 rerere_strbuf_putconflict(out, '=', marker_size);
386 strbuf_addbuf(out, &two);
387 rerere_strbuf_putconflict(out, '>', marker_size);
c0f16f8e 388 if (ctx) {
0d7c419a 389 the_hash_algo->update_fn(ctx, one.buf ?
390 one.buf : "",
391 one.len + 1);
392 the_hash_algo->update_fn(ctx, two.buf ?
393 two.buf : "",
394 two.len + 1);
5b2fd956 395 }
c0f16f8e 396 break;
cc58d7df 397 } else if (hunk == RR_SIDE_1)
e992d1eb 398 strbuf_addbuf(&one, &buf);
387c9d49
JH
399 else if (hunk == RR_ORIGINAL)
400 ; /* discard */
cc58d7df 401 else if (hunk == RR_SIDE_2)
e992d1eb 402 strbuf_addbuf(&two, &buf);
5b2fd956
SB
403 }
404 strbuf_release(&one);
405 strbuf_release(&two);
d58ee6db 406 strbuf_release(&buf);
5b2fd956 407
c0f16f8e
TG
408 return has_conflicts;
409}
410
411/*
412 * Read contents a file with conflicts, normalize the conflicts
413 * by (1) discarding the common ancestor version in diff3-style,
414 * (2) reordering our side and their side so that whichever sorts
415 * alphabetically earlier comes before the other one, while
416 * computing the "conflict ID", which is just an SHA-1 hash of
417 * one side of the conflict, NUL, the other side of the conflict,
418 * and NUL concatenated together.
419 *
420 * Return 1 if conflict hunks are found, 0 if there are no conflict
15beaaa3 421 * hunks and -1 if an error occurred.
c0f16f8e 422 */
0d7c419a 423static int handle_path(unsigned char *hash, struct rerere_io *io, int marker_size)
c0f16f8e 424{
0d7c419a 425 git_hash_ctx ctx;
5ebbdad3 426 struct strbuf buf = STRBUF_INIT, out = STRBUF_INIT;
c0f16f8e 427 int has_conflicts = 0;
0d7c419a 428 if (hash)
429 the_hash_algo->init_fn(&ctx);
c0f16f8e
TG
430
431 while (!io->getline(&buf, io)) {
432 if (is_cmarker(buf.buf, '<', marker_size)) {
5ebbdad3 433 has_conflicts = handle_conflict(&out, io, marker_size,
0d7c419a 434 hash ? &ctx : NULL);
c0f16f8e
TG
435 if (has_conflicts < 0)
436 break;
5ebbdad3
TG
437 rerere_io_putmem(out.buf, out.len, io);
438 strbuf_reset(&out);
c0f16f8e
TG
439 } else
440 rerere_io_putstr(buf.buf, io);
441 }
442 strbuf_release(&buf);
5ebbdad3 443 strbuf_release(&out);
c0f16f8e 444
0d7c419a 445 if (hash)
446 the_hash_algo->final_fn(hash, &ctx);
c0f16f8e 447
221444f5 448 return has_conflicts;
27d6b085
JH
449}
450
cc899eca
JH
451/*
452 * Scan the path for conflicts, do the "handle_path()" thing above, and
453 * return the number of conflict hunks found.
454 */
d829d491
JH
455static int handle_file(struct index_state *istate,
456 const char *path, unsigned char *hash, const char *output)
27d6b085 457{
221444f5 458 int has_conflicts = 0;
27d6b085 459 struct rerere_io_file io;
35843b11 460 int marker_size = ll_merge_marker_size(istate, path);
27d6b085
JH
461
462 memset(&io, 0, sizeof(io));
463 io.io.getline = rerere_file_getline;
464 io.input = fopen(path, "r");
465 io.io.wrerror = 0;
466 if (!io.input)
2373b650 467 return error_errno(_("could not open '%s'"), path);
27d6b085
JH
468
469 if (output) {
470 io.io.output = fopen(output, "w");
471 if (!io.io.output) {
2373b650 472 error_errno(_("could not write '%s'"), output);
27d6b085 473 fclose(io.input);
f7566f07 474 return -1;
27d6b085
JH
475 }
476 }
477
0d7c419a 478 has_conflicts = handle_path(hash, (struct rerere_io *)&io, marker_size);
27d6b085
JH
479
480 fclose(io.input);
481 if (io.io.wrerror)
2373b650 482 error(_("there were errors while writing '%s' (%s)"),
27d6b085
JH
483 path, strerror(io.io.wrerror));
484 if (io.io.output && fclose(io.io.output))
2373b650 485 io.io.wrerror = error_errno(_("failed to flush '%s'"), path);
27d6b085 486
221444f5 487 if (has_conflicts < 0) {
5b2fd956 488 if (output)
691f1a28 489 unlink_or_warn(output);
2373b650 490 return error(_("could not parse conflict hunks in '%s'"), path);
5b2fd956 491 }
27d6b085 492 if (io.io.wrerror)
47d32af2 493 return -1;
221444f5 494 return has_conflicts;
5b2fd956
SB
495}
496
4b68c2a0
JH
497/*
498 * Look at a cache entry at "i" and see if it is not conflicting,
499 * conflicting and we are willing to handle, or conflicting and
500 * we are unable to handle, and return the determination in *type.
501 * Return the cache index to be looked at next, by skipping the
502 * stages we have already looked at in this invocation of this
503 * function.
504 */
35843b11 505static int check_one_conflict(struct index_state *istate, int i, int *type)
5b2fd956 506{
35843b11 507 const struct cache_entry *e = istate->cache[i];
ac49f5ca
MZ
508
509 if (!ce_stage(e)) {
510 *type = RESOLVED;
511 return i + 1;
512 }
513
514 *type = PUNTED;
11877b9e 515 while (i < istate->cache_nr && ce_stage(istate->cache[i]) == 1)
fb70a06d 516 i++;
ac49f5ca
MZ
517
518 /* Only handle regular files with both stages #2 and #3 */
35843b11
NTND
519 if (i + 1 < istate->cache_nr) {
520 const struct cache_entry *e2 = istate->cache[i];
521 const struct cache_entry *e3 = istate->cache[i + 1];
5b2fd956
SB
522 if (ce_stage(e2) == 2 &&
523 ce_stage(e3) == 3 &&
ac49f5ca 524 ce_same_name(e, e3) &&
5b2fd956 525 S_ISREG(e2->ce_mode) &&
ac49f5ca
MZ
526 S_ISREG(e3->ce_mode))
527 *type = THREE_STAGED;
528 }
529
530 /* Skip the entries with the same name */
35843b11 531 while (i < istate->cache_nr && ce_same_name(e, istate->cache[i]))
ac49f5ca
MZ
532 i++;
533 return i;
534}
535
4b68c2a0
JH
536/*
537 * Scan the index and find paths that have conflicts that rerere can
538 * handle, i.e. the ones that has both stages #2 and #3.
539 *
540 * NEEDSWORK: we do not record or replay a previous "resolve by
541 * deletion" for a delete-modify conflict, as that is inherently risky
542 * without knowing what modification is being discarded. The only
543 * safe case, i.e. both side doing the deletion and modification that
544 * are identical to the previous round, might want to be handled,
545 * though.
546 */
35843b11 547static int find_conflict(struct repository *r, struct string_list *conflict)
ac49f5ca
MZ
548{
549 int i;
35843b11 550
e1ff0a32 551 if (repo_read_index(r) < 0)
2373b650 552 return error(_("index file corrupt"));
ac49f5ca 553
35843b11 554 for (i = 0; i < r->index->cache_nr;) {
ac49f5ca 555 int conflict_type;
35843b11
NTND
556 const struct cache_entry *e = r->index->cache[i];
557 i = check_one_conflict(r->index, i, &conflict_type);
ac49f5ca
MZ
558 if (conflict_type == THREE_STAGED)
559 string_list_insert(conflict, (const char *)e->name);
560 }
561 return 0;
562}
563
4b68c2a0
JH
564/*
565 * The merge_rr list is meant to hold outstanding conflicted paths
566 * that rerere could handle. Abuse the list by adding other types of
567 * entries to allow the caller to show "rerere remaining".
568 *
569 * - Conflicted paths that rerere does not handle are added
570 * - Conflicted paths that have been resolved are marked as such
571 * by storing RERERE_RESOLVED to .util field (where conflict ID
572 * is expected to be stored).
573 *
574 * Do *not* write MERGE_RR file out after calling this function.
575 *
576 * NEEDSWORK: we may want to fix the caller that implements "rerere
577 * remaining" to do this without abusing merge_rr.
578 */
35843b11 579int rerere_remaining(struct repository *r, struct string_list *merge_rr)
ac49f5ca
MZ
580{
581 int i;
35843b11 582
55e6b354 583 if (setup_rerere(r, merge_rr, RERERE_READONLY))
9dd330e6 584 return 0;
e1ff0a32 585 if (repo_read_index(r) < 0)
2373b650 586 return error(_("index file corrupt"));
ac49f5ca 587
35843b11 588 for (i = 0; i < r->index->cache_nr;) {
ac49f5ca 589 int conflict_type;
35843b11
NTND
590 const struct cache_entry *e = r->index->cache[i];
591 i = check_one_conflict(r->index, i, &conflict_type);
ac49f5ca
MZ
592 if (conflict_type == PUNTED)
593 string_list_insert(merge_rr, (const char *)e->name);
594 else if (conflict_type == RESOLVED) {
595 struct string_list_item *it;
596 it = string_list_lookup(merge_rr, (const char *)e->name);
afe8a907 597 if (it) {
1d51eced 598 free_rerere_id(it);
ac49f5ca
MZ
599 it->util = RERERE_RESOLVED;
600 }
5b2fd956
SB
601 }
602 }
603 return 0;
604}
605
0ce02b36
JH
606/*
607 * Try using the given conflict resolution "ID" to see
608 * if that recorded conflict resolves cleanly what we
609 * got in the "cur".
610 */
35843b11
NTND
611static int try_merge(struct index_state *istate,
612 const struct rerere_id *id, const char *path,
0ce02b36
JH
613 mmfile_t *cur, mmbuffer_t *result)
614{
35f69671 615 enum ll_merge_result ret;
0ce02b36
JH
616 mmfile_t base = {NULL, 0}, other = {NULL, 0};
617
618 if (read_mmfile(&base, rerere_path(id, "preimage")) ||
35f69671
EN
619 read_mmfile(&other, rerere_path(id, "postimage"))) {
620 ret = LL_MERGE_CONFLICT;
621 } else {
0ce02b36
JH
622 /*
623 * A three-way merge. Note that this honors user-customizable
624 * low-level merge driver settings.
625 */
32eaa468 626 ret = ll_merge(result, path, &base, NULL, cur, "", &other, "",
35843b11 627 istate, NULL);
35f69671 628 }
0ce02b36
JH
629
630 free(base.ptr);
631 free(other.ptr);
632
633 return ret;
634}
635
cc899eca 636/*
18bb9934 637 * Find the conflict identified by "id"; the change between its
cc899eca
JH
638 * "preimage" (i.e. a previous contents with conflict markers) and its
639 * "postimage" (i.e. the corresponding contents with conflicts
640 * resolved) may apply cleanly to the contents stored in "path", i.e.
641 * the conflict this time around.
642 *
643 * Returns 0 for successful replay of recorded resolution, or non-zero
644 * for failure.
645 */
35843b11 646static int merge(struct index_state *istate, const struct rerere_id *id, const char *path)
5b2fd956 647{
15ed07d5 648 FILE *f;
5b2fd956 649 int ret;
0ce02b36 650 mmfile_t cur = {NULL, 0};
5b2fd956 651 mmbuffer_t result = {NULL, 0};
5b2fd956 652
cc899eca
JH
653 /*
654 * Normalize the conflicts in path and write it out to
655 * "thisimage" temporary file.
656 */
35843b11 657 if ((handle_file(istate, path, NULL, rerere_path(id, "thisimage")) < 0) ||
0ce02b36 658 read_mmfile(&cur, rerere_path(id, "thisimage"))) {
689b8c29
BW
659 ret = 1;
660 goto out;
661 }
cc899eca 662
35843b11 663 ret = try_merge(istate, id, path, &cur, &result);
15ed07d5
JH
664 if (ret)
665 goto out;
666
667 /*
668 * A successful replay of recorded resolution.
669 * Mark that "postimage" was used to help gc.
670 */
671 if (utime(rerere_path(id, "postimage"), NULL) < 0)
2373b650 672 warning_errno(_("failed utime() on '%s'"),
033e011e 673 rerere_path(id, "postimage"));
15ed07d5
JH
674
675 /* Update "path" with the resolution */
676 f = fopen(path, "w");
677 if (!f)
2373b650 678 return error_errno(_("could not open '%s'"), path);
15ed07d5 679 if (fwrite(result.ptr, result.size, 1, f) != 1)
2373b650 680 error_errno(_("could not write '%s'"), path);
15ed07d5 681 if (fclose(f))
2373b650 682 return error_errno(_("writing '%s' failed"), path);
5b2fd956 683
689b8c29 684out:
5b2fd956 685 free(cur.ptr);
5b2fd956
SB
686 free(result.ptr);
687
688 return ret;
689}
690
35843b11 691static void update_paths(struct repository *r, struct string_list *update)
5b2fd956 692{
0fa5a2ed 693 struct lock_file index_lock = LOCK_INIT;
5b2fd956 694 int i;
5b2fd956 695
3a95f31d 696 repo_hold_locked_index(r, &index_lock, LOCK_DIE_ON_ERROR);
5b2fd956
SB
697
698 for (i = 0; i < update->nr; i++) {
c455c87c 699 struct string_list_item *item = &update->items[i];
35843b11 700 if (add_file_to_index(r->index, item->string, 0))
89ea9035 701 exit(128);
2373b650 702 fprintf_ln(stderr, _("Staged '%s' using previous resolution."),
a14c7ab8 703 item->string);
5b2fd956
SB
704 }
705
35843b11 706 if (write_locked_index(r->index, &index_lock,
61000814 707 COMMIT_LOCK | SKIP_IF_UNCHANGED))
2373b650 708 die(_("unable to write new index file"));
5b2fd956
SB
709}
710
629716d2
JH
711static void remove_variant(struct rerere_id *id)
712{
713 unlink_or_warn(rerere_path(id, "postimage"));
714 unlink_or_warn(rerere_path(id, "preimage"));
715 id->collection->status[id->variant] = 0;
716}
717
8e7768b2
JH
718/*
719 * The path indicated by rr_item may still have conflict for which we
720 * have a recorded resolution, in which case replay it and optionally
721 * update it. Or it may have been resolved by the user and we may
722 * only have the preimage for that conflict, in which case the result
723 * needs to be recorded as a resolution in a postimage file.
724 */
35843b11
NTND
725static void do_rerere_one_path(struct index_state *istate,
726 struct string_list_item *rr_item,
8e7768b2
JH
727 struct string_list *update)
728{
729 const char *path = rr_item->string;
a13d1370 730 struct rerere_id *id = rr_item->util;
629716d2 731 struct rerere_dir *rr_dir = id->collection;
a13d1370
JH
732 int variant;
733
a13d1370 734 variant = id->variant;
8e7768b2 735
629716d2
JH
736 /* Has the user resolved it already? */
737 if (variant >= 0) {
35843b11 738 if (!handle_file(istate, path, NULL, NULL)) {
629716d2
JH
739 copy_file(rerere_path(id, "postimage"), path, 0666);
740 id->collection->status[variant] |= RR_HAS_POSTIMAGE;
2373b650 741 fprintf_ln(stderr, _("Recorded resolution for '%s'."), path);
629716d2
JH
742 free_rerere_id(rr_item);
743 rr_item->util = NULL;
744 return;
745 }
c0a5423b 746 /*
629716d2
JH
747 * There may be other variants that can cleanly
748 * replay. Try them and update the variant number for
749 * this one.
c0a5423b 750 */
629716d2
JH
751 }
752
753 /* Does any existing resolution apply cleanly? */
754 for (variant = 0; variant < rr_dir->status_nr; variant++) {
755 const int both = RR_HAS_PREIMAGE | RR_HAS_POSTIMAGE;
756 struct rerere_id vid = *id;
757
758 if ((rr_dir->status[variant] & both) != both)
759 continue;
8e7768b2 760
629716d2 761 vid.variant = variant;
35843b11 762 if (merge(istate, &vid, path))
629716d2
JH
763 continue; /* failed to replay */
764
765 /*
766 * If there already is a different variant that applies
767 * cleanly, there is no point maintaining our own variant.
768 */
769 if (0 <= id->variant && id->variant != variant)
770 remove_variant(id);
8e7768b2
JH
771
772 if (rerere_autoupdate)
773 string_list_insert(update, path);
774 else
2373b650
TG
775 fprintf_ln(stderr,
776 _("Resolved '%s' using previous resolution."),
777 path);
629716d2
JH
778 free_rerere_id(rr_item);
779 rr_item->util = NULL;
925d73c4 780 return;
8e7768b2 781 }
629716d2
JH
782
783 /* None of the existing one applies; we need a new variant */
784 assign_variant(id);
785
786 variant = id->variant;
35843b11 787 handle_file(istate, path, NULL, rerere_path(id, "preimage"));
629716d2
JH
788 if (id->collection->status[variant] & RR_HAS_POSTIMAGE) {
789 const char *path = rerere_path(id, "postimage");
790 if (unlink(path))
2373b650 791 die_errno(_("cannot unlink stray '%s'"), path);
629716d2
JH
792 id->collection->status[variant] &= ~RR_HAS_POSTIMAGE;
793 }
794 id->collection->status[variant] |= RR_HAS_PREIMAGE;
2373b650 795 fprintf_ln(stderr, _("Recorded preimage for '%s'"), path);
8e7768b2
JH
796}
797
35843b11
NTND
798static int do_plain_rerere(struct repository *r,
799 struct string_list *rr, int fd)
5b2fd956 800{
183113a5
TF
801 struct string_list conflict = STRING_LIST_INIT_DUP;
802 struct string_list update = STRING_LIST_INIT_DUP;
5b2fd956
SB
803 int i;
804
35843b11 805 find_conflict(r, &conflict);
5b2fd956
SB
806
807 /*
cc899eca
JH
808 * MERGE_RR records paths with conflicts immediately after
809 * merge failed. Some of the conflicted paths might have been
810 * hand resolved in the working tree since then, but the
811 * initial run would catch all and register their preimages.
5b2fd956 812 */
5b2fd956 813 for (i = 0; i < conflict.nr; i++) {
1d51eced 814 struct rerere_id *id;
0d7c419a 815 unsigned char hash[GIT_MAX_RAWSZ];
c455c87c 816 const char *path = conflict.items[i].string;
1d51eced 817 int ret;
5b2fd956 818
c7a25d37
JH
819 /*
820 * Ask handle_file() to scan and assign a
821 * conflict ID. No need to write anything out
822 * yet.
823 */
d829d491 824 ret = handle_file(r->index, path, hash, NULL);
bd7dfa54 825 if (ret != 0 && string_list_has_string(rr, path)) {
93406a28
TG
826 remove_variant(string_list_lookup(rr, path)->util);
827 string_list_remove(rr, path, 1);
828 }
c7a25d37
JH
829 if (ret < 1)
830 continue;
5b2fd956 831
0d7c419a 832 id = new_rerere_id(hash);
18bb9934 833 string_list_insert(rr, path)->util = id;
cc899eca 834
c0a5423b
JH
835 /* Ensure that the directory exists. */
836 mkdir_in_gitdir(rerere_path(id, NULL));
5b2fd956
SB
837 }
838
8e7768b2 839 for (i = 0; i < rr->nr; i++)
35843b11 840 do_rerere_one_path(r->index, &rr->items[i], &update);
5b2fd956
SB
841
842 if (update.nr)
35843b11 843 update_paths(r, &update);
5b2fd956
SB
844
845 return write_rr(rr, fd);
846}
847
633e5ad3 848static void git_rerere_config(void)
5b2fd956 849{
633e5ad3
TA
850 git_config_get_bool("rerere.enabled", &rerere_enabled);
851 git_config_get_bool("rerere.autoupdate", &rerere_autoupdate);
852 git_config(git_default_config, NULL);
5b2fd956
SB
853}
854
f932729c
JK
855static GIT_PATH_FUNC(git_path_rr_cache, "rr-cache")
856
5b2fd956
SB
857static int is_rerere_enabled(void)
858{
5b2fd956
SB
859 int rr_cache_exists;
860
861 if (!rerere_enabled)
862 return 0;
863
f932729c 864 rr_cache_exists = is_directory(git_path_rr_cache());
5b2fd956
SB
865 if (rerere_enabled < 0)
866 return rr_cache_exists;
867
f932729c 868 if (!rr_cache_exists && mkdir_in_gitdir(git_path_rr_cache()))
2373b650 869 die(_("could not create directory '%s'"), git_path_rr_cache());
5b2fd956
SB
870 return 1;
871}
872
55e6b354 873int setup_rerere(struct repository *r, struct string_list *merge_rr, int flags)
5b2fd956
SB
874{
875 int fd;
876
633e5ad3 877 git_rerere_config();
5b2fd956
SB
878 if (!is_rerere_enabled())
879 return -1;
880
cb6020bb
JH
881 if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
882 rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
9dd330e6
JK
883 if (flags & RERERE_READONLY)
884 fd = 0;
885 else
102de880 886 fd = hold_lock_file_for_update(&write_lock,
55e6b354 887 git_path_merge_rr(r),
9dd330e6 888 LOCK_DIE_ON_ERROR);
55e6b354 889 read_rr(r, merge_rr);
5b2fd956
SB
890 return fd;
891}
892
cc899eca
JH
893/*
894 * The main entry point that is called internally from codepaths that
895 * perform mergy operations, possibly leaving conflicted index entries
896 * and working tree files.
897 */
35843b11 898int repo_rerere(struct repository *r, int flags)
5b2fd956 899{
183113a5 900 struct string_list merge_rr = STRING_LIST_INIT_DUP;
1869bbe1 901 int fd, status;
5b2fd956 902
55e6b354 903 fd = setup_rerere(r, &merge_rr, flags);
5b2fd956
SB
904 if (fd < 0)
905 return 0;
35843b11 906 status = do_plain_rerere(r, &merge_rr, fd);
1869bbe1
JH
907 free_rerere_dirs();
908 return status;
5b2fd956 909}
dea4562b 910
3d730ed9
JH
911/*
912 * Subclass of rerere_io that reads from an in-core buffer that is a
913 * strbuf
914 */
915struct rerere_io_mem {
916 struct rerere_io io;
917 struct strbuf input;
918};
919
920/*
921 * ... and its getline() method implementation
922 */
923static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
924{
925 struct rerere_io_mem *io = (struct rerere_io_mem *)io_;
926 char *ep;
927 size_t len;
928
929 strbuf_release(sb);
930 if (!io->input.len)
931 return -1;
932 ep = memchr(io->input.buf, '\n', io->input.len);
933 if (!ep)
934 ep = io->input.buf + io->input.len;
935 else if (*ep == '\n')
936 ep++;
937 len = ep - io->input.buf;
938 strbuf_add(sb, io->input.buf, len);
939 strbuf_remove(&io->input, 0, len);
940 return 0;
941}
942
d829d491
JH
943static int handle_cache(struct index_state *istate,
944 const char *path, unsigned char *hash, const char *output)
3d730ed9
JH
945{
946 mmfile_t mmfile[3] = {{NULL}};
947 mmbuffer_t result = {NULL, 0};
948 const struct cache_entry *ce;
221444f5 949 int pos, len, i, has_conflicts;
3d730ed9 950 struct rerere_io_mem io;
35843b11 951 int marker_size = ll_merge_marker_size(istate, path);
3d730ed9
JH
952
953 /*
954 * Reproduce the conflicted merge in-core
955 */
956 len = strlen(path);
35843b11 957 pos = index_name_pos(istate, path, len);
3d730ed9
JH
958 if (0 <= pos)
959 return -1;
960 pos = -pos - 1;
961
35843b11 962 while (pos < istate->cache_nr) {
3d730ed9
JH
963 enum object_type type;
964 unsigned long size;
965
35843b11 966 ce = istate->cache[pos++];
3d730ed9
JH
967 if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
968 break;
969 i = ce_stage(ce) - 1;
970 if (!mmfile[i].ptr) {
b4f5aca4 971 mmfile[i].ptr = read_object_file(&ce->oid, &type,
972 &size);
3d730ed9
JH
973 mmfile[i].size = size;
974 }
975 }
976 for (i = 0; i < 3; i++)
977 if (!mmfile[i].ptr && !mmfile[i].size)
978 mmfile[i].ptr = xstrdup("");
979
980 /*
981 * NEEDSWORK: handle conflicts from merges with
982 * merge.renormalize set, too?
983 */
984 ll_merge(&result, path, &mmfile[0], NULL,
985 &mmfile[1], "ours",
32eaa468 986 &mmfile[2], "theirs",
35843b11 987 istate, NULL);
3d730ed9
JH
988 for (i = 0; i < 3; i++)
989 free(mmfile[i].ptr);
990
991 memset(&io, 0, sizeof(io));
992 io.io.getline = rerere_mem_getline;
993 if (output)
994 io.io.output = fopen(output, "w");
995 else
996 io.io.output = NULL;
997 strbuf_init(&io.input, 0);
998 strbuf_attach(&io.input, result.ptr, result.size, result.size);
999
1000 /*
1001 * Grab the conflict ID and optionally write the original
1002 * contents with conflict markers out.
1003 */
0d7c419a 1004 has_conflicts = handle_path(hash, (struct rerere_io *)&io, marker_size);
3d730ed9
JH
1005 strbuf_release(&io.input);
1006 if (io.io.output)
1007 fclose(io.io.output);
221444f5 1008 return has_conflicts;
5b2fd956 1009}
dea4562b 1010
35843b11
NTND
1011static int rerere_forget_one_path(struct index_state *istate,
1012 const char *path,
1013 struct string_list *rr)
dea4562b
JH
1014{
1015 const char *filename;
1d51eced 1016 struct rerere_id *id;
0d7c419a 1017 unsigned char hash[GIT_MAX_RAWSZ];
dea4562b 1018 int ret;
8d9b5a4a 1019 struct string_list_item *item;
dea4562b 1020
963ec003
JH
1021 /*
1022 * Recreate the original conflict from the stages in the
1023 * index and compute the conflict ID
1024 */
d829d491 1025 ret = handle_cache(istate, path, hash, NULL);
dea4562b 1026 if (ret < 1)
2373b650 1027 return error(_("could not parse conflict hunks in '%s'"), path);
963ec003
JH
1028
1029 /* Nuke the recorded resolution for the conflict */
0d7c419a 1030 id = new_rerere_id(hash);
890fca84
JH
1031
1032 for (id->variant = 0;
1033 id->variant < id->collection->status_nr;
1034 id->variant++) {
1035 mmfile_t cur = { NULL, 0 };
1036 mmbuffer_t result = {NULL, 0};
1037 int cleanly_resolved;
1038
1039 if (!has_rerere_resolution(id))
1040 continue;
1041
d829d491 1042 handle_cache(istate, path, hash, rerere_path(id, "thisimage"));
890fca84
JH
1043 if (read_mmfile(&cur, rerere_path(id, "thisimage"))) {
1044 free(cur.ptr);
2373b650 1045 error(_("failed to update conflicted state in '%s'"), path);
8f449614 1046 goto fail_exit;
890fca84 1047 }
35843b11 1048 cleanly_resolved = !try_merge(istate, id, path, &cur, &result);
890fca84
JH
1049 free(result.ptr);
1050 free(cur.ptr);
1051 if (cleanly_resolved)
1052 break;
1053 }
1054
8f449614 1055 if (id->collection->status_nr <= id->variant) {
2373b650 1056 error(_("no remembered resolution for '%s'"), path);
8f449614
JH
1057 goto fail_exit;
1058 }
890fca84 1059
18bb9934 1060 filename = rerere_path(id, "postimage");
8f449614
JH
1061 if (unlink(filename)) {
1062 if (errno == ENOENT)
2373b650 1063 error(_("no remembered resolution for '%s'"), path);
8f449614 1064 else
2373b650 1065 error_errno(_("cannot unlink '%s'"), filename);
8f449614 1066 goto fail_exit;
d9d501b0 1067 }
dea4562b 1068
963ec003
JH
1069 /*
1070 * Update the preimage so that the user can resolve the
1071 * conflict in the working tree, run us again to record
1072 * the postimage.
1073 */
d829d491 1074 handle_cache(istate, path, hash, rerere_path(id, "preimage"));
2373b650 1075 fprintf_ln(stderr, _("Updated preimage for '%s'"), path);
dea4562b 1076
963ec003
JH
1077 /*
1078 * And remember that we can record resolution for this
1079 * conflict when the user is done.
1080 */
8d9b5a4a 1081 item = string_list_insert(rr, path);
1d51eced 1082 free_rerere_id(item);
18bb9934 1083 item->util = id;
2373b650 1084 fprintf(stderr, _("Forgot resolution for '%s'\n"), path);
dea4562b 1085 return 0;
8f449614
JH
1086
1087fail_exit:
1088 free(id);
1089 return -1;
dea4562b
JH
1090}
1091
35843b11 1092int rerere_forget(struct repository *r, struct pathspec *pathspec)
dea4562b
JH
1093{
1094 int i, fd;
183113a5
TF
1095 struct string_list conflict = STRING_LIST_INIT_DUP;
1096 struct string_list merge_rr = STRING_LIST_INIT_DUP;
dea4562b 1097
e1ff0a32 1098 if (repo_read_index(r) < 0)
2373b650 1099 return error(_("index file corrupt"));
dea4562b 1100
55e6b354 1101 fd = setup_rerere(r, &merge_rr, RERERE_NOAUTOUPDATE);
0544574c
JK
1102 if (fd < 0)
1103 return 0;
dea4562b 1104
963ec003
JH
1105 /*
1106 * The paths may have been resolved (incorrectly);
1107 * recover the original conflicted state and then
1108 * find the conflicted paths.
1109 */
35843b11
NTND
1110 unmerge_index(r->index, pathspec);
1111 find_conflict(r, &conflict);
dea4562b
JH
1112 for (i = 0; i < conflict.nr; i++) {
1113 struct string_list_item *it = &conflict.items[i];
35843b11 1114 if (!match_pathspec(r->index, pathspec, it->string,
ae8d0824 1115 strlen(it->string), 0, NULL, 0))
dea4562b 1116 continue;
35843b11 1117 rerere_forget_one_path(r->index, it->string, &merge_rr);
dea4562b
JH
1118 }
1119 return write_rr(&merge_rr, fd);
1120}
0f891e7d 1121
e828de82
JH
1122/*
1123 * Garbage collection support
1124 */
1d51eced 1125
5ea82279 1126static timestamp_t rerere_created_at(struct rerere_id *id)
0f891e7d
JH
1127{
1128 struct stat st;
1d51eced 1129
18bb9934 1130 return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
0f891e7d
JH
1131}
1132
5ea82279 1133static timestamp_t rerere_last_used_at(struct rerere_id *id)
0f891e7d
JH
1134{
1135 struct stat st;
1d51eced 1136
18bb9934 1137 return stat(rerere_path(id, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
0f891e7d
JH
1138}
1139
e828de82
JH
1140/*
1141 * Remove the recorded resolution for a given conflict ID
1142 */
1d51eced 1143static void unlink_rr_item(struct rerere_id *id)
0f891e7d 1144{
1be1e851
JH
1145 unlink_or_warn(rerere_path(id, "thisimage"));
1146 remove_variant(id);
1147 id->collection->status[id->variant] = 0;
1148}
1149
5ea82279
JH
1150static void prune_one(struct rerere_id *id,
1151 timestamp_t cutoff_resolve, timestamp_t cutoff_noresolve)
1be1e851 1152{
5ea82279
JH
1153 timestamp_t then;
1154 timestamp_t cutoff;
1be1e851
JH
1155
1156 then = rerere_last_used_at(id);
1157 if (then)
1158 cutoff = cutoff_resolve;
1159 else {
1160 then = rerere_created_at(id);
1161 if (!then)
1162 return;
1163 cutoff = cutoff_noresolve;
1164 }
5ea82279 1165 if (then < cutoff)
1be1e851 1166 unlink_rr_item(id);
0f891e7d
JH
1167}
1168
2bc1a87e
JK
1169/* Does the basename in "path" look plausibly like an rr-cache entry? */
1170static int is_rr_cache_dirname(const char *path)
1171{
098c173f
JK
1172 struct object_id oid;
1173 const char *end;
1174 return !parse_oid_hex(path, &oid, &end) && !*end;
2bc1a87e
JK
1175}
1176
55e6b354 1177void rerere_gc(struct repository *r, struct string_list *rr)
0f891e7d
JH
1178{
1179 struct string_list to_remove = STRING_LIST_INIT_DUP;
1180 DIR *dir;
1181 struct dirent *e;
1be1e851 1182 int i;
5ea82279
JH
1183 timestamp_t now = time(NULL);
1184 timestamp_t cutoff_noresolve = now - 15 * 86400;
1185 timestamp_t cutoff_resolve = now - 60 * 86400;
0f891e7d 1186
55e6b354 1187 if (setup_rerere(r, rr, 0) < 0)
9dd330e6
JK
1188 return;
1189
6e96cb52
JH
1190 git_config_get_expiry_in_days("gc.rerereresolved", &cutoff_resolve, now);
1191 git_config_get_expiry_in_days("gc.rerereunresolved", &cutoff_noresolve, now);
633e5ad3 1192 git_config(git_default_config, NULL);
0f891e7d
JH
1193 dir = opendir(git_path("rr-cache"));
1194 if (!dir)
2373b650 1195 die_errno(_("unable to open rr-cache directory"));
e828de82 1196 /* Collect stale conflict IDs ... */
b548f0f1 1197 while ((e = readdir_skip_dot_and_dotdot(dir))) {
1be1e851
JH
1198 struct rerere_dir *rr_dir;
1199 struct rerere_id id;
1200 int now_empty;
1201
2bc1a87e 1202 if (!is_rr_cache_dirname(e->d_name))
1be1e851
JH
1203 continue; /* or should we remove e->d_name? */
1204
2bc1a87e
JK
1205 rr_dir = find_rerere_dir(e->d_name);
1206
1be1e851
JH
1207 now_empty = 1;
1208 for (id.variant = 0, id.collection = rr_dir;
1209 id.variant < id.collection->status_nr;
1210 id.variant++) {
5ea82279 1211 prune_one(&id, cutoff_resolve, cutoff_noresolve);
1be1e851
JH
1212 if (id.collection->status[id.variant])
1213 now_empty = 0;
0f891e7d 1214 }
1be1e851 1215 if (now_empty)
0f891e7d
JH
1216 string_list_append(&to_remove, e->d_name);
1217 }
a9930e35 1218 closedir(dir);
1be1e851
JH
1219
1220 /* ... and then remove the empty directories */
0f891e7d 1221 for (i = 0; i < to_remove.nr; i++)
1be1e851 1222 rmdir(git_path("rr-cache/%s", to_remove.items[i].string));
0f891e7d 1223 string_list_clear(&to_remove, 0);
9dd330e6 1224 rollback_lock_file(&write_lock);
0f891e7d
JH
1225}
1226
e828de82
JH
1227/*
1228 * During a conflict resolution, after "rerere" recorded the
1229 * preimages, abandon them if the user did not resolve them or
1230 * record their resolutions. And drop $GIT_DIR/MERGE_RR.
1231 *
1232 * NEEDSWORK: shouldn't we be calling this from "reset --hard"?
1233 */
55e6b354 1234void rerere_clear(struct repository *r, struct string_list *merge_rr)
0f891e7d
JH
1235{
1236 int i;
1237
55e6b354 1238 if (setup_rerere(r, merge_rr, 0) < 0)
9dd330e6
JK
1239 return;
1240
0f891e7d 1241 for (i = 0; i < merge_rr->nr; i++) {
1d51eced 1242 struct rerere_id *id = merge_rr->items[i].util;
1be1e851 1243 if (!has_rerere_resolution(id)) {
18bb9934 1244 unlink_rr_item(id);
1be1e851
JH
1245 rmdir(rerere_path(id, NULL));
1246 }
0f891e7d 1247 }
55e6b354 1248 unlink_or_warn(git_path_merge_rr(r));
9dd330e6 1249 rollback_lock_file(&write_lock);
0f891e7d 1250}