Coverage Report

Created: 2025-12-31 07:01

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