rerere.c: remove implicit dependency on the_index

The reason rerere(), rerere_forget() and rerere_remaining() take a struct repository instead of struct index_state is not obvious from the patch: Deep in update_paths() and find_conflict(), hold_locked_index() and read_index() are called. These functions assumes the index path at $GIT_DIR/index which is not always true when you take an arbitrary index state. Taking a repository will allow us to point to the right index path later when we replace them with repo_ versions. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Sep 21, 2018 at 17:57 UTC 35843b1123e2772c5db6d7db5abf279c3253ae57
8 files changed +81 -68
apply.c
+1 -1
@@ -4630,7 +4630,7 @@ static int write_out_results(struct apply_state *state, struct patch *list)
4630 }
4631 string_list_clear(&cpath, 0);
4632
4633 - rerere(0);
4633 + repo_rerere(state->repo, 0);
4634 }
4635
4636 return errs;
builtin/am.c
+2 -2
@@ -1604,7 +1604,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
1604 o.verbosity = 0;
1605
1606 if (merge_recursive_generic(&o, &our_tree, &their_tree, 1, bases, &result)) {
1607 - rerere(state->allow_rerere_autoupdate);
1607 + repo_rerere(the_repository, state->allow_rerere_autoupdate);
1608 free(their_tree_name);
1609 return error(_("Failed to merge in the changes."));
1610 }
@@ -1899,7 +1899,7 @@ static void am_resolve(struct am_state *state)
1899 goto next;
1900 }
1901
1902 - rerere(0);
1902 + repo_rerere(the_repository, 0);
1903
1904 do_commit(state);
1905
builtin/commit.c
+1 -1
@@ -1651,7 +1651,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
1651 "new_index file. Check that disk is not full and quota is\n"
1652 "not exceeded, and then \"git reset HEAD\" to recover."));
1653
1654 - rerere(0);
1654 + repo_rerere(the_repository, 0);
1655 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
1656 run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
1657 if (amend && !no_post_rewrite) {
builtin/merge.c
+1 -1
@@ -899,7 +899,7 @@ static int suggest_conflicts(void)
899 fputs(msgbuf.buf, fp);
900 strbuf_release(&msgbuf);
901 fclose(fp);
902 - rerere(allow_rerere_auto);
902 + repo_rerere(the_repository, allow_rerere_auto);
903 printf(_("Automatic merge failed; "
904 "fix conflicts and then commit the result.\n"));
905 return 1;
builtin/rerere.c
+3 -3
@@ -70,7 +70,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
70 flags = RERERE_NOAUTOUPDATE;
71
72 if (argc < 1)
73 - return rerere(flags);
73 + return repo_rerere(the_repository, flags);
74
75 if (!strcmp(argv[0], "forget")) {
76 struct pathspec pathspec;
@@ -78,7 +78,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
78 warning("'git rerere forget' without paths is deprecated");
79 parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD,
80 prefix, argv + 1);
81 - return rerere_forget(&pathspec);
81 + return rerere_forget(the_repository, &pathspec);
82 }
83
84 if (!strcmp(argv[0], "clear")) {
@@ -91,7 +91,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
91 for (i = 0; i < merge_rr.nr; i++)
92 printf("%s\n", merge_rr.items[i].string);
93 } else if (!strcmp(argv[0], "remaining")) {
94 - rerere_remaining(&merge_rr);
94 + rerere_remaining(the_repository, &merge_rr);
95 for (i = 0; i < merge_rr.nr; i++) {
96 if (merge_rr.items[i].util != RERERE_RESOLVED)
97 printf("%s\n", merge_rr.items[i].string);
rerere.c
+64 -55
@@ -474,11 +474,12 @@ static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_siz
474 * Scan the path for conflicts, do the "handle_path()" thing above, and
475 * return the number of conflict hunks found.
476 */
477 -static int handle_file(const char *path, unsigned char *sha1, const char *output)
477 +static int handle_file(struct index_state *istate, const char *path,
478 + unsigned char *sha1, const char *output)
479 {
480 int hunk_no = 0;
481 struct rerere_io_file io;
481 - int marker_size = ll_merge_marker_size(&the_index, path);
482 + int marker_size = ll_merge_marker_size(istate, path);
483
484 memset(&io, 0, sizeof(io));
485 io.io.getline = rerere_file_getline;
@@ -523,9 +524,9 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output
524 * stages we have already looked at in this invocation of this
525 * function.
526 */
526 -static int check_one_conflict(int i, int *type)
527 +static int check_one_conflict(struct index_state *istate, int i, int *type)
528 {
528 - const struct cache_entry *e = active_cache[i];
529 + const struct cache_entry *e = istate->cache[i];
530
531 if (!ce_stage(e)) {
532 *type = RESOLVED;
@@ -533,13 +534,13 @@ static int check_one_conflict(int i, int *type)
534 }
535
536 *type = PUNTED;
536 - while (ce_stage(active_cache[i]) == 1)
537 + while (ce_stage(istate->cache[i]) == 1)
538 i++;
539
540 /* Only handle regular files with both stages #2 and #3 */
540 - if (i + 1 < active_nr) {
541 - const struct cache_entry *e2 = active_cache[i];
542 - const struct cache_entry *e3 = active_cache[i + 1];
541 + if (i + 1 < istate->cache_nr) {
542 + const struct cache_entry *e2 = istate->cache[i];
543 + const struct cache_entry *e3 = istate->cache[i + 1];
544 if (ce_stage(e2) == 2 &&
545 ce_stage(e3) == 3 &&
546 ce_same_name(e, e3) &&
@@ -549,7 +550,7 @@ static int check_one_conflict(int i, int *type)
550 }
551
552 /* Skip the entries with the same name */
552 - while (i < active_nr && ce_same_name(e, active_cache[i]))
553 + while (i < istate->cache_nr && ce_same_name(e, istate->cache[i]))
554 i++;
555 return i;
556 }
@@ -565,16 +566,17 @@ static int check_one_conflict(int i, int *type)
566 * are identical to the previous round, might want to be handled,
567 * though.
568 */
568 -static int find_conflict(struct string_list *conflict)
569 +static int find_conflict(struct repository *r, struct string_list *conflict)
570 {
571 int i;
571 - if (read_cache() < 0)
572 +
573 + if (read_index(r->index) < 0)
574 return error("Could not read index");
575
574 - for (i = 0; i < active_nr;) {
576 + for (i = 0; i < r->index->cache_nr;) {
577 int conflict_type;
576 - const struct cache_entry *e = active_cache[i];
577 - i = check_one_conflict(i, &conflict_type);
578 + const struct cache_entry *e = r->index->cache[i];
579 + i = check_one_conflict(r->index, i, &conflict_type);
580 if (conflict_type == THREE_STAGED)
581 string_list_insert(conflict, (const char *)e->name);
582 }
@@ -596,18 +598,19 @@ static int find_conflict(struct string_list *conflict)
598 * NEEDSWORK: we may want to fix the caller that implements "rerere
599 * remaining" to do this without abusing merge_rr.
600 */
599 -int rerere_remaining(struct string_list *merge_rr)
601 +int rerere_remaining(struct repository *r, struct string_list *merge_rr)
602 {
603 int i;
604 +
605 if (setup_rerere(merge_rr, RERERE_READONLY))
606 return 0;
604 - if (read_cache() < 0)
607 + if (read_index(r->index) < 0)
608 return error("Could not read index");
609
607 - for (i = 0; i < active_nr;) {
610 + for (i = 0; i < r->index->cache_nr;) {
611 int conflict_type;
609 - const struct cache_entry *e = active_cache[i];
610 - i = check_one_conflict(i, &conflict_type);
612 + const struct cache_entry *e = r->index->cache[i];
613 + i = check_one_conflict(r->index, i, &conflict_type);
614 if (conflict_type == PUNTED)
615 string_list_insert(merge_rr, (const char *)e->name);
616 else if (conflict_type == RESOLVED) {
@@ -627,7 +630,8 @@ int rerere_remaining(struct string_list *merge_rr)
630 * if that recorded conflict resolves cleanly what we
631 * got in the "cur".
632 */
630 -static int try_merge(const struct rerere_id *id, const char *path,
633 +static int try_merge(struct index_state *istate,
634 + const struct rerere_id *id, const char *path,
635 mmfile_t *cur, mmbuffer_t *result)
636 {
637 int ret;
@@ -642,7 +646,7 @@ static int try_merge(const struct rerere_id *id, const char *path,
646 * low-level merge driver settings.
647 */
648 ret = ll_merge(result, path, &base, NULL, cur, "", &other, "",
645 - &the_index, NULL);
649 + istate, NULL);
650
651 free(base.ptr);
652 free(other.ptr);
@@ -660,7 +664,7 @@ static int try_merge(const struct rerere_id *id, const char *path,
664 * Returns 0 for successful replay of recorded resolution, or non-zero
665 * for failure.
666 */
663 -static int merge(const struct rerere_id *id, const char *path)
667 +static int merge(struct index_state *istate, const struct rerere_id *id, const char *path)
668 {
669 FILE *f;
670 int ret;
@@ -671,13 +675,13 @@ static int merge(const struct rerere_id *id, const char *path)
675 * Normalize the conflicts in path and write it out to
676 * "thisimage" temporary file.
677 */
674 - if ((handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) ||
678 + if ((handle_file(istate, path, NULL, rerere_path(id, "thisimage")) < 0) ||
679 read_mmfile(&cur, rerere_path(id, "thisimage"))) {
680 ret = 1;
681 goto out;
682 }
683
680 - ret = try_merge(id, path, &cur, &result);
684 + ret = try_merge(istate, id, path, &cur, &result);
685 if (ret)
686 goto out;
687
@@ -705,7 +709,7 @@ out:
709 return ret;
710 }
711
708 -static void update_paths(struct string_list *update)
712 +static void update_paths(struct repository *r, struct string_list *update)
713 {
714 struct lock_file index_lock = LOCK_INIT;
715 int i;
@@ -714,13 +718,13 @@ static void update_paths(struct string_list *update)
718
719 for (i = 0; i < update->nr; i++) {
720 struct string_list_item *item = &update->items[i];
717 - if (add_file_to_cache(item->string, 0))
721 + if (add_file_to_index(r->index, item->string, 0))
722 exit(128);
723 fprintf(stderr, "Staged '%s' using previous resolution.\n",
724 item->string);
725 }
726
723 - if (write_locked_index(&the_index, &index_lock,
727 + if (write_locked_index(r->index, &index_lock,
728 COMMIT_LOCK | SKIP_IF_UNCHANGED))
729 die("Unable to write new index file");
730 }
@@ -739,7 +743,8 @@ static void remove_variant(struct rerere_id *id)
743 * only have the preimage for that conflict, in which case the result
744 * needs to be recorded as a resolution in a postimage file.
745 */
742 -static void do_rerere_one_path(struct string_list_item *rr_item,
746 +static void do_rerere_one_path(struct index_state *istate,
747 + struct string_list_item *rr_item,
748 struct string_list *update)
749 {
750 const char *path = rr_item->string;
@@ -751,7 +756,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
756
757 /* Has the user resolved it already? */
758 if (variant >= 0) {
754 - if (!handle_file(path, NULL, NULL)) {
759 + if (!handle_file(istate, path, NULL, NULL)) {
760 copy_file(rerere_path(id, "postimage"), path, 0666);
761 id->collection->status[variant] |= RR_HAS_POSTIMAGE;
762 fprintf(stderr, "Recorded resolution for '%s'.\n", path);
@@ -775,7 +780,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
780 continue;
781
782 vid.variant = variant;
778 - if (merge(&vid, path))
783 + if (merge(istate, &vid, path))
784 continue; /* failed to replay */
785
786 /*
@@ -800,7 +805,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
805 assign_variant(id);
806
807 variant = id->variant;
803 - handle_file(path, NULL, rerere_path(id, "preimage"));
808 + handle_file(istate, path, NULL, rerere_path(id, "preimage"));
809 if (id->collection->status[variant] & RR_HAS_POSTIMAGE) {
810 const char *path = rerere_path(id, "postimage");
811 if (unlink(path))
@@ -811,13 +816,14 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
816 fprintf(stderr, "Recorded preimage for '%s'\n", path);
817 }
818
814 -static int do_plain_rerere(struct string_list *rr, int fd)
819 +static int do_plain_rerere(struct repository *r,
820 + struct string_list *rr, int fd)
821 {
822 struct string_list conflict = STRING_LIST_INIT_DUP;
823 struct string_list update = STRING_LIST_INIT_DUP;
824 int i;
825
820 - find_conflict(&conflict);
826 + find_conflict(r, &conflict);
827
828 /*
829 * MERGE_RR records paths with conflicts immediately after
@@ -839,7 +845,7 @@ static int do_plain_rerere(struct string_list *rr, int fd)
845 * conflict ID. No need to write anything out
846 * yet.
847 */
842 - ret = handle_file(path, sha1, NULL);
848 + ret = handle_file(r->index, path, sha1, NULL);
849 if (ret < 1)
850 continue;
851
@@ -851,10 +857,10 @@ static int do_plain_rerere(struct string_list *rr, int fd)
857 }
858
859 for (i = 0; i < rr->nr; i++)
854 - do_rerere_one_path(&rr->items[i], &update);
860 + do_rerere_one_path(r->index, &rr->items[i], &update);
861
862 if (update.nr)
857 - update_paths(&update);
863 + update_paths(r, &update);
864
865 return write_rr(rr, fd);
866 }
@@ -909,7 +915,7 @@ int setup_rerere(struct string_list *merge_rr, int flags)
915 * perform mergy operations, possibly leaving conflicted index entries
916 * and working tree files.
917 */
912 -int rerere(int flags)
918 +int repo_rerere(struct repository *r, int flags)
919 {
920 struct string_list merge_rr = STRING_LIST_INIT_DUP;
921 int fd, status;
@@ -917,7 +923,7 @@ int rerere(int flags)
923 fd = setup_rerere(&merge_rr, flags);
924 if (fd < 0)
925 return 0;
920 - status = do_plain_rerere(&merge_rr, fd);
926 + status = do_plain_rerere(r, &merge_rr, fd);
927 free_rerere_dirs();
928 return status;
929 }
@@ -954,29 +960,30 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
960 return 0;
961 }
962
957 -static int handle_cache(const char *path, unsigned char *sha1, const char *output)
963 +static int handle_cache(struct index_state *istate, const char *path,
964 + unsigned char *sha1, const char *output)
965 {
966 mmfile_t mmfile[3] = {{NULL}};
967 mmbuffer_t result = {NULL, 0};
968 const struct cache_entry *ce;
969 int pos, len, i, hunk_no;
970 struct rerere_io_mem io;
964 - int marker_size = ll_merge_marker_size(&the_index, path);
971 + int marker_size = ll_merge_marker_size(istate, path);
972
973 /*
974 * Reproduce the conflicted merge in-core
975 */
976 len = strlen(path);
970 - pos = cache_name_pos(path, len);
977 + pos = index_name_pos(istate, path, len);
978 if (0 <= pos)
979 return -1;
980 pos = -pos - 1;
981
975 - while (pos < active_nr) {
982 + while (pos < istate->cache_nr) {
983 enum object_type type;
984 unsigned long size;
985
979 - ce = active_cache[pos++];
986 + ce = istate->cache[pos++];
987 if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
988 break;
989 i = ce_stage(ce) - 1;
@@ -997,7 +1004,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
1004 ll_merge(&result, path, &mmfile[0], NULL,
1005 &mmfile[1], "ours",
1006 &mmfile[2], "theirs",
1000 - &the_index, NULL);
1007 + istate, NULL);
1008 for (i = 0; i < 3; i++)
1009 free(mmfile[i].ptr);
1010
@@ -1021,7 +1028,9 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
1028 return hunk_no;
1029 }
1030
1024 -static int rerere_forget_one_path(const char *path, struct string_list *rr)
1031 +static int rerere_forget_one_path(struct index_state *istate,
1032 + const char *path,
1033 + struct string_list *rr)
1034 {
1035 const char *filename;
1036 struct rerere_id *id;
@@ -1033,7 +1042,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
1042 * Recreate the original conflict from the stages in the
1043 * index and compute the conflict ID
1044 */
1036 - ret = handle_cache(path, sha1, NULL);
1045 + ret = handle_cache(istate, path, sha1, NULL);
1046 if (ret < 1)
1047 return error("Could not parse conflict hunks in '%s'", path);
1048
@@ -1050,13 +1059,13 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
1059 if (!has_rerere_resolution(id))
1060 continue;
1061
1053 - handle_cache(path, sha1, rerere_path(id, "thisimage"));
1062 + handle_cache(istate, path, sha1, rerere_path(id, "thisimage"));
1063 if (read_mmfile(&cur, rerere_path(id, "thisimage"))) {
1064 free(cur.ptr);
1065 error("Failed to update conflicted state in '%s'", path);
1066 goto fail_exit;
1067 }
1059 - cleanly_resolved = !try_merge(id, path, &cur, &result);
1068 + cleanly_resolved = !try_merge(istate, id, path, &cur, &result);
1069 free(result.ptr);
1070 free(cur.ptr);
1071 if (cleanly_resolved)
@@ -1082,7 +1091,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
1091 * conflict in the working tree, run us again to record
1092 * the postimage.
1093 */
1085 - handle_cache(path, sha1, rerere_path(id, "preimage"));
1094 + handle_cache(istate, path, sha1, rerere_path(id, "preimage"));
1095 fprintf(stderr, "Updated preimage for '%s'\n", path);
1096
1097 /*
@@ -1100,13 +1109,13 @@ fail_exit:
1109 return -1;
1110 }
1111
1103 -int rerere_forget(struct pathspec *pathspec)
1112 +int rerere_forget(struct repository *r, struct pathspec *pathspec)
1113 {
1114 int i, fd;
1115 struct string_list conflict = STRING_LIST_INIT_DUP;
1116 struct string_list merge_rr = STRING_LIST_INIT_DUP;
1117
1109 - if (read_cache() < 0)
1118 + if (read_index(r->index) < 0)
1119 return error("Could not read index");
1120
1121 fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
@@ -1118,14 +1127,14 @@ int rerere_forget(struct pathspec *pathspec)
1127 * recover the original conflicted state and then
1128 * find the conflicted paths.
1129 */
1121 - unmerge_cache(pathspec);
1122 - find_conflict(&conflict);
1130 + unmerge_index(r->index, pathspec);
1131 + find_conflict(r, &conflict);
1132 for (i = 0; i < conflict.nr; i++) {
1133 struct string_list_item *it = &conflict.items[i];
1125 - if (!match_pathspec(&the_index, pathspec, it->string,
1134 + if (!match_pathspec(r->index, pathspec, it->string,
1135 strlen(it->string), 0, NULL, 0))
1136 continue;
1128 - rerere_forget_one_path(it->string, &merge_rr);
1137 + rerere_forget_one_path(r->index, it->string, &merge_rr);
1138 }
1139 return write_rr(&merge_rr, fd);
1140 }
rerere.h
+7 -3
@@ -4,6 +4,7 @@
4 #include "string-list.h"
5
6 struct pathspec;
7 +struct repository;
8
9 #define RERERE_AUTOUPDATE 01
10 #define RERERE_NOAUTOUPDATE 02
@@ -23,7 +24,10 @@ struct rerere_id {
24 };
25
26 int setup_rerere(struct string_list *, int);
26 -int rerere(int);
27 +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
28 +#define rerere(flags) repo_rerere(the_repository, flags)
29 +#endif
30 +int repo_rerere(struct repository *, int);
31 /*
32 * Given the conflict ID and the name of a "file" used for replaying
33 * the recorded resolution (e.g. "preimage", "postimage"), return the
@@ -31,8 +35,8 @@ int rerere(int);
35 * return the path to the directory that houses these files.
36 */
37 const char *rerere_path(const struct rerere_id *, const char *file);
34 -int rerere_forget(struct pathspec *);
35 -int rerere_remaining(struct string_list *);
38 +int rerere_forget(struct repository *, struct pathspec *);
39 +int rerere_remaining(struct repository *, struct string_list *);
40 void rerere_clear(struct string_list *);
41 void rerere_gc(struct string_list *);
42
sequencer.c
+2 -2
@@ -1856,7 +1856,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
1856 : _("could not apply %s... %s"),
1857 short_commit_name(commit), msg.subject);
1858 print_advice(res == 1, opts);
1859 - rerere(opts->allow_rerere_auto);
1859 + repo_rerere(the_repository, opts->allow_rerere_auto);
1860 goto leave;
1861 }
1862
@@ -3175,7 +3175,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
3175
3176 rollback_lock_file(&lock);
3177 if (ret)
3178 - rerere(opts->allow_rerere_auto);
3178 + repo_rerere(the_repository, opts->allow_rerere_auto);
3179 else
3180 /*
3181 * In case of problems, we now want to return a positive