int rerere_forget(struct pathspec *pathspec) { int i, fd; struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list merge_rr = STRING_LIST_INIT_DUP; if (read_cache() < 0) return error(_("index file corrupt")); fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); if (fd < 0) return 0; /* * The paths may have been resolved (incorrectly); * recover the original conflicted state and then * find the conflicted paths. */ unmerge_cache(pathspec); find_conflict(&conflict); for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; if (!match_pathspec(&the_index, pathspec, it->string, strlen(it->string), 0, NULL, 0)) continue; rerere_forget_one_path(it->string, &merge_rr); } return write_rr(&merge_rr, fd); }
static int do_plain_rerere(struct repository *r, struct string_list *rr, int fd) { struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP; int i; find_conflict(r, &conflict); /* * MERGE_RR records paths with conflicts immediately after * merge failed. Some of the conflicted paths might have been * hand resolved in the working tree since then, but the * initial run would catch all and register their preimages. */ for (i = 0; i < conflict.nr; i++) { struct rerere_id *id; unsigned char hash[GIT_MAX_RAWSZ]; const char *path = conflict.items[i].string; int ret; /* * Ask handle_file() to scan and assign a * conflict ID. No need to write anything out * yet. */ ret = handle_file(r->index, path, hash, NULL); if (ret != 0 && string_list_has_string(rr, path)) { remove_variant(string_list_lookup(rr, path)->util); string_list_remove(rr, path, 1); } if (ret < 1) continue; id = new_rerere_id(hash); string_list_insert(rr, path)->util = id; /* Ensure that the directory exists. */ mkdir_in_gitdir(rerere_path(id, NULL)); } for (i = 0; i < rr->nr; i++) do_rerere_one_path(r->index, &rr->items[i], &update); if (update.nr) update_paths(r, &update); return write_rr(rr, fd); }
int rerere_forget(struct pathspec *pathspec) { int i, fd; struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list merge_rr = STRING_LIST_INIT_DUP; if (read_cache() < 0) return error("Could not read index"); fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); unmerge_cache(pathspec); find_conflict(&conflict); for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; if (!match_pathspec(pathspec, it->string, strlen(it->string), 0, NULL, 0)) continue; rerere_forget_one_path(it->string, &merge_rr); } return write_rr(&merge_rr, fd); }
static int do_plain_rerere(struct string_list *rr, int fd) { struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP; int i; find_conflict(&conflict); /* * MERGE_RR records paths with conflicts immediately after merge * failed. Some of the conflicted paths might have been hand resolved * in the working tree since then, but the initial run would catch all * and register their preimages. */ for (i = 0; i < conflict.nr; i++) { const char *path = conflict.items[i].string; if (!string_list_has_string(rr, path)) { unsigned char sha1[20]; char *hex; int ret; ret = handle_file(path, sha1, NULL); if (ret < 1) continue; hex = xstrdup(sha1_to_hex(sha1)); string_list_insert(rr, path)->util = hex; if (mkdir_in_gitdir(git_path("rr-cache/%s", hex))) continue; handle_file(path, NULL, rerere_path(hex, "preimage")); fprintf(stderr, "Recorded preimage for '%s'\n", path); } } /* * Now some of the paths that had conflicts earlier might have been * hand resolved. Others may be similar to a conflict already that * was resolved before. */ for (i = 0; i < rr->nr; i++) { int ret; const char *path = rr->items[i].string; const char *name = (const char *)rr->items[i].util; if (has_rerere_resolution(name)) { if (!merge(name, path)) { const char *msg; if (rerere_autoupdate) { string_list_insert(&update, path); msg = "Staged '%s' using previous resolution.\n"; } else msg = "Resolved '%s' using previous resolution.\n"; fprintf(stderr, msg, path); goto mark_resolved; } } /* Let's see if we have resolved it. */ ret = handle_file(path, NULL, NULL); if (ret) continue; fprintf(stderr, "Recorded resolution for '%s'.\n", path); copy_file(rerere_path(name, "postimage"), path, 0666); mark_resolved: rr->items[i].util = NULL; } if (update.nr) update_paths(&update); return write_rr(rr, fd); }
static int do_plain_rerere(struct string_list *rr, int fd) { struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP; int i; find_conflict(&conflict); /* * MERGE_RR records paths with conflicts immediately after * merge failed. Some of the conflicted paths might have been * hand resolved in the working tree since then, but the * initial run would catch all and register their preimages. */ for (i = 0; i < conflict.nr; i++) { struct rerere_id *id; unsigned char sha1[20]; const char *path = conflict.items[i].string; int ret; if (string_list_has_string(rr, path)) continue; /* * Ask handle_file() to scan and assign a * conflict ID. No need to write anything out * yet. */ ret = handle_file(path, sha1, NULL); if (ret < 1) continue; id = new_rerere_id(sha1); string_list_insert(rr, path)->util = id; /* * If the directory does not exist, create * it. mkdir_in_gitdir() will fail with * EEXIST if there already is one. * * NEEDSWORK: make sure "gc" does not remove * preimage without removing the directory. */ if (mkdir_in_gitdir(rerere_path(id, NULL))) continue; /* * We are the first to encounter this * conflict. Ask handle_file() to write the * normalized contents to the "preimage" file. */ handle_file(path, NULL, rerere_path(id, "preimage")); fprintf(stderr, "Recorded preimage for '%s'\n", path); } for (i = 0; i < rr->nr; i++) do_rerere_one_path(&rr->items[i], &update); if (update.nr) update_paths(&update); return write_rr(rr, fd); }