1e68b8a62d8c9ad1458e8a59fa190ac77e734af7
   1#include "cache.h"
   2#include "lockfile.h"
   3#include "string-list.h"
   4#include "rerere.h"
   5#include "xdiff-interface.h"
   6#include "dir.h"
   7#include "resolve-undo.h"
   8#include "ll-merge.h"
   9#include "attr.h"
  10#include "pathspec.h"
  11
  12#define RESOLVED 0
  13#define PUNTED 1
  14#define THREE_STAGED 2
  15void *RERERE_RESOLVED = &RERERE_RESOLVED;
  16
  17/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
  18static int rerere_enabled = -1;
  19
  20/* automatically update cleanly resolved paths to the index */
  21static int rerere_autoupdate;
  22
  23static char *merge_rr_path;
  24
  25const char *rerere_path(const char *hex, const char *file)
  26{
  27        return git_path("rr-cache/%s/%s", hex, file);
  28}
  29
  30static int has_rerere_resolution(const char *hex)
  31{
  32        struct stat st;
  33        return !stat(rerere_path(hex, "postimage"), &st);
  34}
  35
  36/*
  37 * $GIT_DIR/MERGE_RR file is a collection of records, each of which is
  38 * "conflict ID", a HT and pathname, terminated with a NUL, and is
  39 * used to keep track of the set of paths that "rerere" may need to
  40 * work on (i.e. what is left by the previous invocation of "git
  41 * rerere" during the current conflict resolution session).
  42 */
  43static void read_rr(struct string_list *rr)
  44{
  45        struct strbuf buf = STRBUF_INIT;
  46        FILE *in = fopen(merge_rr_path, "r");
  47
  48        if (!in)
  49                return;
  50        while (!strbuf_getwholeline(&buf, in, '\0')) {
  51                char *path;
  52                unsigned char sha1[20];
  53
  54                /* There has to be the hash, tab, path and then NUL */
  55                if (buf.len < 42 || get_sha1_hex(buf.buf, sha1))
  56                        die("corrupt MERGE_RR");
  57
  58                if (buf.buf[40] != '\t')
  59                        die("corrupt MERGE_RR");
  60                buf.buf[40] = '\0';
  61                path = buf.buf + 41;
  62
  63                string_list_insert(rr, path)->util = xstrdup(buf.buf);
  64        }
  65        strbuf_release(&buf);
  66        fclose(in);
  67}
  68
  69static struct lock_file write_lock;
  70
  71static int write_rr(struct string_list *rr, int out_fd)
  72{
  73        int i;
  74        for (i = 0; i < rr->nr; i++) {
  75                struct strbuf buf = STRBUF_INIT;
  76
  77                assert(rr->items[i].util != RERERE_RESOLVED);
  78                if (!rr->items[i].util)
  79                        continue;
  80                strbuf_addf(&buf, "%s\t%s%c",
  81                            (char *)rr->items[i].util,
  82                            rr->items[i].string, 0);
  83                if (write_in_full(out_fd, buf.buf, buf.len) != buf.len)
  84                        die("unable to write rerere record");
  85
  86                strbuf_release(&buf);
  87        }
  88        if (commit_lock_file(&write_lock) != 0)
  89                die("unable to write rerere record");
  90        return 0;
  91}
  92
  93/*
  94 * "rerere" interacts with conflicted file contents using this I/O
  95 * abstraction.  It reads a conflicted contents from one place via
  96 * "getline()" method, and optionally can write it out after
  97 * normalizing the conflicted hunks to the "output".  Subclasses of
  98 * rerere_io embed this structure at the beginning of their own
  99 * rerere_io object.
 100 */
 101struct rerere_io {
 102        int (*getline)(struct strbuf *, struct rerere_io *);
 103        FILE *output;
 104        int wrerror;
 105        /* some more stuff */
 106};
 107
 108static void ferr_write(const void *p, size_t count, FILE *fp, int *err)
 109{
 110        if (!count || *err)
 111                return;
 112        if (fwrite(p, count, 1, fp) != 1)
 113                *err = errno;
 114}
 115
 116static inline void ferr_puts(const char *s, FILE *fp, int *err)
 117{
 118        ferr_write(s, strlen(s), fp, err);
 119}
 120
 121static void rerere_io_putstr(const char *str, struct rerere_io *io)
 122{
 123        if (io->output)
 124                ferr_puts(str, io->output, &io->wrerror);
 125}
 126
 127/*
 128 * Write a conflict marker to io->output (if defined).
 129 */
 130static void rerere_io_putconflict(int ch, int size, struct rerere_io *io)
 131{
 132        char buf[64];
 133
 134        while (size) {
 135                if (size <= sizeof(buf) - 2) {
 136                        memset(buf, ch, size);
 137                        buf[size] = '\n';
 138                        buf[size + 1] = '\0';
 139                        size = 0;
 140                } else {
 141                        int sz = sizeof(buf) - 1;
 142
 143                        /*
 144                         * Make sure we will not write everything out
 145                         * in this round by leaving at least 1 byte
 146                         * for the next round, giving the next round
 147                         * a chance to add the terminating LF.  Yuck.
 148                         */
 149                        if (size <= sz)
 150                                sz -= (sz - size) + 1;
 151                        memset(buf, ch, sz);
 152                        buf[sz] = '\0';
 153                        size -= sz;
 154                }
 155                rerere_io_putstr(buf, io);
 156        }
 157}
 158
 159static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io)
 160{
 161        if (io->output)
 162                ferr_write(mem, sz, io->output, &io->wrerror);
 163}
 164
 165/*
 166 * Subclass of rerere_io that reads from an on-disk file
 167 */
 168struct rerere_io_file {
 169        struct rerere_io io;
 170        FILE *input;
 171};
 172
 173/*
 174 * ... and its getline() method implementation
 175 */
 176static int rerere_file_getline(struct strbuf *sb, struct rerere_io *io_)
 177{
 178        struct rerere_io_file *io = (struct rerere_io_file *)io_;
 179        return strbuf_getwholeline(sb, io->input, '\n');
 180}
 181
 182/*
 183 * Require the exact number of conflict marker letters, no more, no
 184 * less, followed by SP or any whitespace
 185 * (including LF).
 186 */
 187static int is_cmarker(char *buf, int marker_char, int marker_size)
 188{
 189        int want_sp;
 190
 191        /*
 192         * The beginning of our version and the end of their version
 193         * always are labeled like "<<<<< ours" or ">>>>> theirs",
 194         * hence we set want_sp for them.  Note that the version from
 195         * the common ancestor in diff3-style output is not always
 196         * labelled (e.g. "||||| common" is often seen but "|||||"
 197         * alone is also valid), so we do not set want_sp.
 198         */
 199        want_sp = (marker_char == '<') || (marker_char == '>');
 200
 201        while (marker_size--)
 202                if (*buf++ != marker_char)
 203                        return 0;
 204        if (want_sp && *buf != ' ')
 205                return 0;
 206        return isspace(*buf);
 207}
 208
 209static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_size)
 210{
 211        git_SHA_CTX ctx;
 212        int hunk_no = 0;
 213        enum {
 214                RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL
 215        } hunk = RR_CONTEXT;
 216        struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
 217        struct strbuf buf = STRBUF_INIT;
 218
 219        if (sha1)
 220                git_SHA1_Init(&ctx);
 221
 222        while (!io->getline(&buf, io)) {
 223                if (is_cmarker(buf.buf, '<', marker_size)) {
 224                        if (hunk != RR_CONTEXT)
 225                                goto bad;
 226                        hunk = RR_SIDE_1;
 227                } else if (is_cmarker(buf.buf, '|', marker_size)) {
 228                        if (hunk != RR_SIDE_1)
 229                                goto bad;
 230                        hunk = RR_ORIGINAL;
 231                } else if (is_cmarker(buf.buf, '=', marker_size)) {
 232                        if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
 233                                goto bad;
 234                        hunk = RR_SIDE_2;
 235                } else if (is_cmarker(buf.buf, '>', marker_size)) {
 236                        if (hunk != RR_SIDE_2)
 237                                goto bad;
 238                        if (strbuf_cmp(&one, &two) > 0)
 239                                strbuf_swap(&one, &two);
 240                        hunk_no++;
 241                        hunk = RR_CONTEXT;
 242                        rerere_io_putconflict('<', marker_size, io);
 243                        rerere_io_putmem(one.buf, one.len, io);
 244                        rerere_io_putconflict('=', marker_size, io);
 245                        rerere_io_putmem(two.buf, two.len, io);
 246                        rerere_io_putconflict('>', marker_size, io);
 247                        if (sha1) {
 248                                git_SHA1_Update(&ctx, one.buf ? one.buf : "",
 249                                            one.len + 1);
 250                                git_SHA1_Update(&ctx, two.buf ? two.buf : "",
 251                                            two.len + 1);
 252                        }
 253                        strbuf_reset(&one);
 254                        strbuf_reset(&two);
 255                } else if (hunk == RR_SIDE_1)
 256                        strbuf_addbuf(&one, &buf);
 257                else if (hunk == RR_ORIGINAL)
 258                        ; /* discard */
 259                else if (hunk == RR_SIDE_2)
 260                        strbuf_addbuf(&two, &buf);
 261                else
 262                        rerere_io_putstr(buf.buf, io);
 263                continue;
 264        bad:
 265                hunk = 99; /* force error exit */
 266                break;
 267        }
 268        strbuf_release(&one);
 269        strbuf_release(&two);
 270        strbuf_release(&buf);
 271
 272        if (sha1)
 273                git_SHA1_Final(sha1, &ctx);
 274        if (hunk != RR_CONTEXT)
 275                return -1;
 276        return hunk_no;
 277}
 278
 279static int handle_file(const char *path, unsigned char *sha1, const char *output)
 280{
 281        int hunk_no = 0;
 282        struct rerere_io_file io;
 283        int marker_size = ll_merge_marker_size(path);
 284
 285        memset(&io, 0, sizeof(io));
 286        io.io.getline = rerere_file_getline;
 287        io.input = fopen(path, "r");
 288        io.io.wrerror = 0;
 289        if (!io.input)
 290                return error("Could not open %s", path);
 291
 292        if (output) {
 293                io.io.output = fopen(output, "w");
 294                if (!io.io.output) {
 295                        fclose(io.input);
 296                        return error("Could not write %s", output);
 297                }
 298        }
 299
 300        hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size);
 301
 302        fclose(io.input);
 303        if (io.io.wrerror)
 304                error("There were errors while writing %s (%s)",
 305                      path, strerror(io.io.wrerror));
 306        if (io.io.output && fclose(io.io.output))
 307                io.io.wrerror = error("Failed to flush %s: %s",
 308                                      path, strerror(errno));
 309
 310        if (hunk_no < 0) {
 311                if (output)
 312                        unlink_or_warn(output);
 313                return error("Could not parse conflict hunks in %s", path);
 314        }
 315        if (io.io.wrerror)
 316                return -1;
 317        return hunk_no;
 318}
 319
 320/*
 321 * Subclass of rerere_io that reads from an in-core buffer that is a
 322 * strbuf
 323 */
 324struct rerere_io_mem {
 325        struct rerere_io io;
 326        struct strbuf input;
 327};
 328
 329/*
 330 * ... and its getline() method implementation
 331 */
 332static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
 333{
 334        struct rerere_io_mem *io = (struct rerere_io_mem *)io_;
 335        char *ep;
 336        size_t len;
 337
 338        strbuf_release(sb);
 339        if (!io->input.len)
 340                return -1;
 341        ep = memchr(io->input.buf, '\n', io->input.len);
 342        if (!ep)
 343                ep = io->input.buf + io->input.len;
 344        else if (*ep == '\n')
 345                ep++;
 346        len = ep - io->input.buf;
 347        strbuf_add(sb, io->input.buf, len);
 348        strbuf_remove(&io->input, 0, len);
 349        return 0;
 350}
 351
 352static int handle_cache(const char *path, unsigned char *sha1, const char *output)
 353{
 354        mmfile_t mmfile[3] = {{NULL}};
 355        mmbuffer_t result = {NULL, 0};
 356        const struct cache_entry *ce;
 357        int pos, len, i, hunk_no;
 358        struct rerere_io_mem io;
 359        int marker_size = ll_merge_marker_size(path);
 360
 361        /*
 362         * Reproduce the conflicted merge in-core
 363         */
 364        len = strlen(path);
 365        pos = cache_name_pos(path, len);
 366        if (0 <= pos)
 367                return -1;
 368        pos = -pos - 1;
 369
 370        while (pos < active_nr) {
 371                enum object_type type;
 372                unsigned long size;
 373
 374                ce = active_cache[pos++];
 375                if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
 376                        break;
 377                i = ce_stage(ce) - 1;
 378                if (!mmfile[i].ptr) {
 379                        mmfile[i].ptr = read_sha1_file(ce->sha1, &type, &size);
 380                        mmfile[i].size = size;
 381                }
 382        }
 383        for (i = 0; i < 3; i++)
 384                if (!mmfile[i].ptr && !mmfile[i].size)
 385                        mmfile[i].ptr = xstrdup("");
 386
 387        /*
 388         * NEEDSWORK: handle conflicts from merges with
 389         * merge.renormalize set, too
 390         */
 391        ll_merge(&result, path, &mmfile[0], NULL,
 392                 &mmfile[1], "ours",
 393                 &mmfile[2], "theirs", NULL);
 394        for (i = 0; i < 3; i++)
 395                free(mmfile[i].ptr);
 396
 397        memset(&io, 0, sizeof(io));
 398        io.io.getline = rerere_mem_getline;
 399        if (output)
 400                io.io.output = fopen(output, "w");
 401        else
 402                io.io.output = NULL;
 403        strbuf_init(&io.input, 0);
 404        strbuf_attach(&io.input, result.ptr, result.size, result.size);
 405
 406        hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size);
 407        strbuf_release(&io.input);
 408        if (io.io.output)
 409                fclose(io.io.output);
 410        return hunk_no;
 411}
 412
 413/*
 414 * Look at a cache entry at "i" and see if it is not conflicting,
 415 * conflicting and we are willing to handle, or conflicting and
 416 * we are unable to handle, and return the determination in *type.
 417 * Return the cache index to be looked at next, by skipping the
 418 * stages we have already looked at in this invocation of this
 419 * function.
 420 */
 421static int check_one_conflict(int i, int *type)
 422{
 423        const struct cache_entry *e = active_cache[i];
 424
 425        if (!ce_stage(e)) {
 426                *type = RESOLVED;
 427                return i + 1;
 428        }
 429
 430        *type = PUNTED;
 431        while (ce_stage(active_cache[i]) == 1)
 432                i++;
 433
 434        /* Only handle regular files with both stages #2 and #3 */
 435        if (i + 1 < active_nr) {
 436                const struct cache_entry *e2 = active_cache[i];
 437                const struct cache_entry *e3 = active_cache[i + 1];
 438                if (ce_stage(e2) == 2 &&
 439                    ce_stage(e3) == 3 &&
 440                    ce_same_name(e, e3) &&
 441                    S_ISREG(e2->ce_mode) &&
 442                    S_ISREG(e3->ce_mode))
 443                        *type = THREE_STAGED;
 444        }
 445
 446        /* Skip the entries with the same name */
 447        while (i < active_nr && ce_same_name(e, active_cache[i]))
 448                i++;
 449        return i;
 450}
 451
 452/*
 453 * Scan the index and find paths that have conflicts that rerere can
 454 * handle, i.e. the ones that has both stages #2 and #3.
 455 *
 456 * NEEDSWORK: we do not record or replay a previous "resolve by
 457 * deletion" for a delete-modify conflict, as that is inherently risky
 458 * without knowing what modification is being discarded.  The only
 459 * safe case, i.e. both side doing the deletion and modification that
 460 * are identical to the previous round, might want to be handled,
 461 * though.
 462 */
 463static int find_conflict(struct string_list *conflict)
 464{
 465        int i;
 466        if (read_cache() < 0)
 467                return error("Could not read index");
 468
 469        for (i = 0; i < active_nr;) {
 470                int conflict_type;
 471                const struct cache_entry *e = active_cache[i];
 472                i = check_one_conflict(i, &conflict_type);
 473                if (conflict_type == THREE_STAGED)
 474                        string_list_insert(conflict, (const char *)e->name);
 475        }
 476        return 0;
 477}
 478
 479/*
 480 * The merge_rr list is meant to hold outstanding conflicted paths
 481 * that rerere could handle.  Abuse the list by adding other types of
 482 * entries to allow the caller to show "rerere remaining".
 483 *
 484 * - Conflicted paths that rerere does not handle are added
 485 * - Conflicted paths that have been resolved are marked as such
 486 *   by storing RERERE_RESOLVED to .util field (where conflict ID
 487 *   is expected to be stored).
 488 *
 489 * Do *not* write MERGE_RR file out after calling this function.
 490 *
 491 * NEEDSWORK: we may want to fix the caller that implements "rerere
 492 * remaining" to do this without abusing merge_rr.
 493 */
 494int rerere_remaining(struct string_list *merge_rr)
 495{
 496        int i;
 497        if (read_cache() < 0)
 498                return error("Could not read index");
 499
 500        for (i = 0; i < active_nr;) {
 501                int conflict_type;
 502                const struct cache_entry *e = active_cache[i];
 503                i = check_one_conflict(i, &conflict_type);
 504                if (conflict_type == PUNTED)
 505                        string_list_insert(merge_rr, (const char *)e->name);
 506                else if (conflict_type == RESOLVED) {
 507                        struct string_list_item *it;
 508                        it = string_list_lookup(merge_rr, (const char *)e->name);
 509                        if (it != NULL) {
 510                                free(it->util);
 511                                it->util = RERERE_RESOLVED;
 512                        }
 513                }
 514        }
 515        return 0;
 516}
 517
 518static int merge(const char *name, const char *path)
 519{
 520        int ret;
 521        mmfile_t cur = {NULL, 0}, base = {NULL, 0}, other = {NULL, 0};
 522        mmbuffer_t result = {NULL, 0};
 523
 524        if (handle_file(path, NULL, rerere_path(name, "thisimage")) < 0)
 525                return 1;
 526
 527        if (read_mmfile(&cur, rerere_path(name, "thisimage")) ||
 528                        read_mmfile(&base, rerere_path(name, "preimage")) ||
 529                        read_mmfile(&other, rerere_path(name, "postimage"))) {
 530                ret = 1;
 531                goto out;
 532        }
 533        ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", NULL);
 534        if (!ret) {
 535                FILE *f;
 536
 537                if (utime(rerere_path(name, "postimage"), NULL) < 0)
 538                        warning("failed utime() on %s: %s",
 539                                        rerere_path(name, "postimage"),
 540                                        strerror(errno));
 541                f = fopen(path, "w");
 542                if (!f)
 543                        return error("Could not open %s: %s", path,
 544                                     strerror(errno));
 545                if (fwrite(result.ptr, result.size, 1, f) != 1)
 546                        error("Could not write %s: %s", path, strerror(errno));
 547                if (fclose(f))
 548                        return error("Writing %s failed: %s", path,
 549                                     strerror(errno));
 550        }
 551
 552out:
 553        free(cur.ptr);
 554        free(base.ptr);
 555        free(other.ptr);
 556        free(result.ptr);
 557
 558        return ret;
 559}
 560
 561static struct lock_file index_lock;
 562
 563static void update_paths(struct string_list *update)
 564{
 565        int i;
 566
 567        hold_locked_index(&index_lock, 1);
 568
 569        for (i = 0; i < update->nr; i++) {
 570                struct string_list_item *item = &update->items[i];
 571                if (add_file_to_cache(item->string, 0))
 572                        exit(128);
 573                fprintf(stderr, "Staged '%s' using previous resolution.\n",
 574                        item->string);
 575        }
 576
 577        if (active_cache_changed) {
 578                if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
 579                        die("Unable to write new index file");
 580        } else
 581                rollback_lock_file(&index_lock);
 582}
 583
 584static int do_plain_rerere(struct string_list *rr, int fd)
 585{
 586        struct string_list conflict = STRING_LIST_INIT_DUP;
 587        struct string_list update = STRING_LIST_INIT_DUP;
 588        int i;
 589
 590        find_conflict(&conflict);
 591
 592        /*
 593         * MERGE_RR records paths with conflicts immediately after merge
 594         * failed.  Some of the conflicted paths might have been hand resolved
 595         * in the working tree since then, but the initial run would catch all
 596         * and register their preimages.
 597         */
 598
 599        for (i = 0; i < conflict.nr; i++) {
 600                const char *path = conflict.items[i].string;
 601                if (!string_list_has_string(rr, path)) {
 602                        unsigned char sha1[20];
 603                        char *hex;
 604                        int ret;
 605                        ret = handle_file(path, sha1, NULL);
 606                        if (ret < 1)
 607                                continue;
 608                        hex = xstrdup(sha1_to_hex(sha1));
 609                        string_list_insert(rr, path)->util = hex;
 610                        if (mkdir_in_gitdir(git_path("rr-cache/%s", hex)))
 611                                continue;
 612                        handle_file(path, NULL, rerere_path(hex, "preimage"));
 613                        fprintf(stderr, "Recorded preimage for '%s'\n", path);
 614                }
 615        }
 616
 617        /*
 618         * Now some of the paths that had conflicts earlier might have been
 619         * hand resolved.  Others may be similar to a conflict already that
 620         * was resolved before.
 621         */
 622
 623        for (i = 0; i < rr->nr; i++) {
 624                int ret;
 625                const char *path = rr->items[i].string;
 626                const char *name = (const char *)rr->items[i].util;
 627
 628                if (has_rerere_resolution(name)) {
 629                        if (merge(name, path))
 630                                continue;
 631
 632                        if (rerere_autoupdate)
 633                                string_list_insert(&update, path);
 634                        else
 635                                fprintf(stderr,
 636                                        "Resolved '%s' using previous resolution.\n",
 637                                        path);
 638                        goto mark_resolved;
 639                }
 640
 641                /* Let's see if we have resolved it. */
 642                ret = handle_file(path, NULL, NULL);
 643                if (ret)
 644                        continue;
 645
 646                fprintf(stderr, "Recorded resolution for '%s'.\n", path);
 647                copy_file(rerere_path(name, "postimage"), path, 0666);
 648        mark_resolved:
 649                free(rr->items[i].util);
 650                rr->items[i].util = NULL;
 651        }
 652
 653        if (update.nr)
 654                update_paths(&update);
 655
 656        return write_rr(rr, fd);
 657}
 658
 659static void git_rerere_config(void)
 660{
 661        git_config_get_bool("rerere.enabled", &rerere_enabled);
 662        git_config_get_bool("rerere.autoupdate", &rerere_autoupdate);
 663        git_config(git_default_config, NULL);
 664}
 665
 666static int is_rerere_enabled(void)
 667{
 668        const char *rr_cache;
 669        int rr_cache_exists;
 670
 671        if (!rerere_enabled)
 672                return 0;
 673
 674        rr_cache = git_path("rr-cache");
 675        rr_cache_exists = is_directory(rr_cache);
 676        if (rerere_enabled < 0)
 677                return rr_cache_exists;
 678
 679        if (!rr_cache_exists && mkdir_in_gitdir(rr_cache))
 680                die("Could not create directory %s", rr_cache);
 681        return 1;
 682}
 683
 684int setup_rerere(struct string_list *merge_rr, int flags)
 685{
 686        int fd;
 687
 688        git_rerere_config();
 689        if (!is_rerere_enabled())
 690                return -1;
 691
 692        if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
 693                rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
 694        merge_rr_path = git_pathdup("MERGE_RR");
 695        fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
 696                                       LOCK_DIE_ON_ERROR);
 697        read_rr(merge_rr);
 698        return fd;
 699}
 700
 701int rerere(int flags)
 702{
 703        struct string_list merge_rr = STRING_LIST_INIT_DUP;
 704        int fd;
 705
 706        fd = setup_rerere(&merge_rr, flags);
 707        if (fd < 0)
 708                return 0;
 709        return do_plain_rerere(&merge_rr, fd);
 710}
 711
 712static int rerere_forget_one_path(const char *path, struct string_list *rr)
 713{
 714        const char *filename;
 715        char *hex;
 716        unsigned char sha1[20];
 717        int ret;
 718        struct string_list_item *item;
 719
 720        ret = handle_cache(path, sha1, NULL);
 721        if (ret < 1)
 722                return error("Could not parse conflict hunks in '%s'", path);
 723        hex = xstrdup(sha1_to_hex(sha1));
 724        filename = rerere_path(hex, "postimage");
 725        if (unlink(filename))
 726                return (errno == ENOENT
 727                        ? error("no remembered resolution for %s", path)
 728                        : error("cannot unlink %s: %s", filename, strerror(errno)));
 729
 730        handle_cache(path, sha1, rerere_path(hex, "preimage"));
 731        fprintf(stderr, "Updated preimage for '%s'\n", path);
 732
 733        item = string_list_insert(rr, path);
 734        free(item->util);
 735        item->util = hex;
 736        fprintf(stderr, "Forgot resolution for %s\n", path);
 737        return 0;
 738}
 739
 740int rerere_forget(struct pathspec *pathspec)
 741{
 742        int i, fd;
 743        struct string_list conflict = STRING_LIST_INIT_DUP;
 744        struct string_list merge_rr = STRING_LIST_INIT_DUP;
 745
 746        if (read_cache() < 0)
 747                return error("Could not read index");
 748
 749        fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
 750
 751        unmerge_cache(pathspec);
 752        find_conflict(&conflict);
 753        for (i = 0; i < conflict.nr; i++) {
 754                struct string_list_item *it = &conflict.items[i];
 755                if (!match_pathspec(pathspec, it->string,
 756                                    strlen(it->string), 0, NULL, 0))
 757                        continue;
 758                rerere_forget_one_path(it->string, &merge_rr);
 759        }
 760        return write_rr(&merge_rr, fd);
 761}
 762
 763static time_t rerere_created_at(const char *name)
 764{
 765        struct stat st;
 766        return stat(rerere_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
 767}
 768
 769static time_t rerere_last_used_at(const char *name)
 770{
 771        struct stat st;
 772        return stat(rerere_path(name, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
 773}
 774
 775static void unlink_rr_item(const char *name)
 776{
 777        unlink(rerere_path(name, "thisimage"));
 778        unlink(rerere_path(name, "preimage"));
 779        unlink(rerere_path(name, "postimage"));
 780        rmdir(git_path("rr-cache/%s", name));
 781}
 782
 783void rerere_gc(struct string_list *rr)
 784{
 785        struct string_list to_remove = STRING_LIST_INIT_DUP;
 786        DIR *dir;
 787        struct dirent *e;
 788        int i, cutoff;
 789        time_t now = time(NULL), then;
 790        int cutoff_noresolve = 15;
 791        int cutoff_resolve = 60;
 792
 793        git_config_get_int("gc.rerereresolved", &cutoff_resolve);
 794        git_config_get_int("gc.rerereunresolved", &cutoff_noresolve);
 795        git_config(git_default_config, NULL);
 796        dir = opendir(git_path("rr-cache"));
 797        if (!dir)
 798                die_errno("unable to open rr-cache directory");
 799        while ((e = readdir(dir))) {
 800                if (is_dot_or_dotdot(e->d_name))
 801                        continue;
 802
 803                then = rerere_last_used_at(e->d_name);
 804                if (then) {
 805                        cutoff = cutoff_resolve;
 806                } else {
 807                        then = rerere_created_at(e->d_name);
 808                        if (!then)
 809                                continue;
 810                        cutoff = cutoff_noresolve;
 811                }
 812                if (then < now - cutoff * 86400)
 813                        string_list_append(&to_remove, e->d_name);
 814        }
 815        closedir(dir);
 816        for (i = 0; i < to_remove.nr; i++)
 817                unlink_rr_item(to_remove.items[i].string);
 818        string_list_clear(&to_remove, 0);
 819}
 820
 821void rerere_clear(struct string_list *merge_rr)
 822{
 823        int i;
 824
 825        for (i = 0; i < merge_rr->nr; i++) {
 826                const char *name = (const char *)merge_rr->items[i].util;
 827                if (!has_rerere_resolution(name))
 828                        unlink_rr_item(name);
 829        }
 830        unlink_or_warn(git_path("MERGE_RR"));
 831}