/* * $GIT_DIR/MERGE_RR file is a collection of records, each of which is * "conflict ID", a HT and pathname, terminated with a NUL, and is * used to keep track of the set of paths that "rerere" may need to * work on (i.e. what is left by the previous invocation of "git * rerere" during the current conflict resolution session). */ static void read_rr(struct string_list *rr) { struct strbuf buf = STRBUF_INIT; FILE *in = fopen(git_path_merge_rr(), "r"); if (!in) return; while (!strbuf_getwholeline(&buf, in, '\0')) { char *path; unsigned char sha1[20]; struct rerere_id *id; /* There has to be the hash, tab, path and then NUL */ if (buf.len < 42 || get_sha1_hex(buf.buf, sha1)) die("corrupt MERGE_RR"); if (buf.buf[40] != '\t') die("corrupt MERGE_RR"); buf.buf[40] = '\0'; path = buf.buf + 41; id = new_rerere_id_hex(buf.buf); string_list_insert(rr, path)->util = id; } strbuf_release(&buf); fclose(in); }
static void read_rr(struct string_list *rr) { unsigned char sha1[20]; char buf[PATH_MAX]; FILE *in = fopen(git_path_merge_rr(), "r"); if (!in) return; while (fread(buf, 40, 1, in) == 1) { int i; char *name; if (get_sha1_hex(buf, sha1)) die("corrupt MERGE_RR"); buf[40] = '\0'; name = xstrdup(buf); if (fgetc(in) != '\t') die("corrupt MERGE_RR"); for (i = 0; i < sizeof(buf); i++) { int c = fgetc(in); if (c < 0) die("corrupt MERGE_RR"); buf[i] = c; if (c == 0) break; } if (i == sizeof(buf)) die("filename too long"); string_list_insert(rr, buf)->util = name; } fclose(in); }
void remove_branch_state(void) { unlink(git_path_cherry_pick_head()); unlink(git_path_revert_head()); unlink(git_path_merge_head()); unlink(git_path_merge_rr()); unlink(git_path_merge_msg()); unlink(git_path_merge_mode()); unlink(git_path_squash_msg()); }
/* * During a conflict resolution, after "rerere" recorded the * preimages, abandon them if the user did not resolve them or * record their resolutions. And drop $GIT_DIR/MERGE_RR. * * NEEDSWORK: shouldn't we be calling this from "reset --hard"? */ void rerere_clear(struct string_list *merge_rr) { int i; if (setup_rerere(merge_rr, 0) < 0) return; for (i = 0; i < merge_rr->nr; i++) { struct rerere_id *id = merge_rr->items[i].util; if (!has_rerere_resolution(id)) unlink_rr_item(id); } unlink_or_warn(git_path_merge_rr()); rollback_lock_file(&write_lock); }
int setup_rerere(struct string_list *merge_rr, int flags) { int fd; git_rerere_config(); if (!is_rerere_enabled()) return -1; if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE)) rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE); if (flags & RERERE_READONLY) fd = 0; else fd = hold_lock_file_for_update(&write_lock, git_path_merge_rr(), LOCK_DIE_ON_ERROR); read_rr(merge_rr); return fd; }
/* * $GIT_DIR/MERGE_RR file is a collection of records, each of which is * "conflict ID", a HT and pathname, terminated with a NUL, and is * used to keep track of the set of paths that "rerere" may need to * work on (i.e. what is left by the previous invocation of "git * rerere" during the current conflict resolution session). */ static void read_rr(struct repository *r, struct string_list *rr) { struct strbuf buf = STRBUF_INIT; FILE *in = fopen_or_warn(git_path_merge_rr(r), "r"); if (!in) return; while (!strbuf_getwholeline(&buf, in, '\0')) { char *path; unsigned char hash[GIT_MAX_RAWSZ]; struct rerere_id *id; int variant; const unsigned hexsz = the_hash_algo->hexsz; /* There has to be the hash, tab, path and then NUL */ if (buf.len < hexsz + 2 || get_sha1_hex(buf.buf, hash)) die(_("corrupt MERGE_RR")); if (buf.buf[hexsz] != '.') { variant = 0; path = buf.buf + hexsz; } else { errno = 0; variant = strtol(buf.buf + hexsz + 1, &path, 10); if (errno) die(_("corrupt MERGE_RR")); } if (*(path++) != '\t') die(_("corrupt MERGE_RR")); buf.buf[hexsz] = '\0'; id = new_rerere_id_hex(buf.buf); id->variant = variant; string_list_insert(rr, path)->util = id; } strbuf_release(&buf); fclose(in); }
/* * $GIT_DIR/MERGE_RR file is a collection of records, each of which is * "conflict ID", a HT and pathname, terminated with a NUL, and is * used to keep track of the set of paths that "rerere" may need to * work on (i.e. what is left by the previous invocation of "git * rerere" during the current conflict resolution session). */ static void read_rr(struct string_list *rr) { struct strbuf buf = STRBUF_INIT; FILE *in = fopen_or_warn(git_path_merge_rr(), "r"); if (!in) return; while (!strbuf_getwholeline(&buf, in, '\0')) { char *path; unsigned char sha1[20]; struct rerere_id *id; int variant; /* There has to be the hash, tab, path and then NUL */ if (buf.len < 42 || get_sha1_hex(buf.buf, sha1)) die("corrupt MERGE_RR"); if (buf.buf[40] != '.') { variant = 0; path = buf.buf + 40; } else { errno = 0; variant = strtol(buf.buf + 41, &path, 10); if (errno) die("corrupt MERGE_RR"); } if (*(path++) != '\t') die("corrupt MERGE_RR"); buf.buf[40] = '\0'; id = new_rerere_id_hex(buf.buf); id->variant = variant; string_list_insert(rr, path)->util = id; } strbuf_release(&buf); fclose(in); }