merge-recursive: avoid returning a wholesale struct

It is technically allowed, as per C89, for functions' return type to be complete structs (i.e. *not* just pointers to structs). However, it was just an oversight of this developer when converting Python code to C code in 6d297f8 (Status update on merge-recursive in C, 2006-07-08) which introduced such a return type. Besides, by converting this construct to pass in the struct, we can now start returning a value that can indicate errors in future patches. This will help the current effort to libify merge-recursive.c. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jul 26, 2016 at 18:06 UTC 3c8a51e89a90cb2a4016b1c30a10c7245bbdbeda
1 file changed +56 -50
merge-recursive.c
+56 -50
@@ -894,47 +894,47 @@ static int merge_3way(struct merge_options *o,
894 return merge_status;
895 }
896
897 -static struct merge_file_info merge_file_1(struct merge_options *o,
897 +static int merge_file_1(struct merge_options *o,
898 const struct diff_filespec *one,
899 const struct diff_filespec *a,
900 const struct diff_filespec *b,
901 const char *branch1,
902 - const char *branch2)
902 + const char *branch2,
903 + struct merge_file_info *result)
904 {
904 - struct merge_file_info result;
905 - result.merge = 0;
906 - result.clean = 1;
905 + result->merge = 0;
906 + result->clean = 1;
907
908 if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) {
909 - result.clean = 0;
909 + result->clean = 0;
910 if (S_ISREG(a->mode)) {
911 - result.mode = a->mode;
912 - oidcpy(&result.oid, &a->oid);
911 + result->mode = a->mode;
912 + oidcpy(&result->oid, &a->oid);
913 } else {
914 - result.mode = b->mode;
915 - oidcpy(&result.oid, &b->oid);
914 + result->mode = b->mode;
915 + oidcpy(&result->oid, &b->oid);
916 }
917 } else {
918 if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid))
919 - result.merge = 1;
919 + result->merge = 1;
920
921 /*
922 * Merge modes
923 */
924 if (a->mode == b->mode || a->mode == one->mode)
925 - result.mode = b->mode;
925 + result->mode = b->mode;
926 else {
927 - result.mode = a->mode;
927 + result->mode = a->mode;
928 if (b->mode != one->mode) {
929 - result.clean = 0;
930 - result.merge = 1;
929 + result->clean = 0;
930 + result->merge = 1;
931 }
932 }
933
934 if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid))
935 - oidcpy(&result.oid, &b->oid);
935 + oidcpy(&result->oid, &b->oid);
936 else if (oid_eq(&b->oid, &one->oid))
937 - oidcpy(&result.oid, &a->oid);
937 + oidcpy(&result->oid, &a->oid);
938 else if (S_ISREG(a->mode)) {
939 mmbuffer_t result_buf;
940 int merge_status;
@@ -946,64 +946,66 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
946 die(_("Failed to execute internal merge"));
947
948 if (write_sha1_file(result_buf.ptr, result_buf.size,
949 - blob_type, result.oid.hash))
949 + blob_type, result->oid.hash))
950 die(_("Unable to add %s to database"),
951 a->path);
952
953 free(result_buf.ptr);
954 - result.clean = (merge_status == 0);
954 + result->clean = (merge_status == 0);
955 } else if (S_ISGITLINK(a->mode)) {
956 - result.clean = merge_submodule(result.oid.hash,
956 + result->clean = merge_submodule(result->oid.hash,
957 one->path,
958 one->oid.hash,
959 a->oid.hash,
960 b->oid.hash,
961 !o->call_depth);
962 } else if (S_ISLNK(a->mode)) {
963 - oidcpy(&result.oid, &a->oid);
963 + oidcpy(&result->oid, &a->oid);
964
965 if (!oid_eq(&a->oid, &b->oid))
966 - result.clean = 0;
966 + result->clean = 0;
967 } else
968 die("BUG: unsupported object type in the tree");
969 }
970
971 - return result;
971 + return 0;
972 }
973
974 -static struct merge_file_info
975 -merge_file_special_markers(struct merge_options *o,
974 +static int merge_file_special_markers(struct merge_options *o,
975 const struct diff_filespec *one,
976 const struct diff_filespec *a,
977 const struct diff_filespec *b,
978 const char *branch1,
979 const char *filename1,
980 const char *branch2,
982 - const char *filename2)
981 + const char *filename2,
982 + struct merge_file_info *mfi)
983 {
984 char *side1 = NULL;
985 char *side2 = NULL;
986 - struct merge_file_info mfi;
986 + int ret;
987
988 if (filename1)
989 side1 = xstrfmt("%s:%s", branch1, filename1);
990 if (filename2)
991 side2 = xstrfmt("%s:%s", branch2, filename2);
992
993 - mfi = merge_file_1(o, one, a, b,
994 - side1 ? side1 : branch1, side2 ? side2 : branch2);
993 + ret = merge_file_1(o, one, a, b,
994 + side1 ? side1 : branch1,
995 + side2 ? side2 : branch2, mfi);
996 free(side1);
997 free(side2);
997 - return mfi;
998 + return ret;
999 }
1000
1000 -static struct merge_file_info merge_file_one(struct merge_options *o,
1001 +static int merge_file_one(struct merge_options *o,
1002 const char *path,
1003 const struct object_id *o_oid, int o_mode,
1004 const struct object_id *a_oid, int a_mode,
1005 const struct object_id *b_oid, int b_mode,
1006 const char *branch1,
1006 - const char *branch2)
1007 + const char *branch2,
1008 + struct merge_file_info *mfi)
1009 {
1010 struct diff_filespec one, a, b;
1011
@@ -1014,7 +1016,7 @@ static struct merge_file_info merge_file_one(struct merge_options *o,
1016 a.mode = a_mode;
1017 oidcpy(&b.oid, b_oid);
1018 b.mode = b_mode;
1017 - return merge_file_1(o, &one, &a, &b, branch1, branch2);
1019 + return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi);
1020 }
1021
1022 static void handle_change_delete(struct merge_options *o,
@@ -1187,11 +1189,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
1189 struct merge_file_info mfi;
1190 struct diff_filespec other;
1191 struct diff_filespec *add;
1190 - mfi = merge_file_one(o, one->path,
1192 + if (merge_file_one(o, one->path,
1193 &one->oid, one->mode,
1194 &a->oid, a->mode,
1195 &b->oid, b->mode,
1194 - ci->branch1, ci->branch2);
1196 + ci->branch1, ci->branch2, &mfi))
1197 + return;
1198 /*
1199 * FIXME: For rename/add-source conflicts (if we could detect
1200 * such), this is wrong. We should instead find a unique
@@ -1245,12 +1248,13 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
1248 remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
1249 remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
1250
1248 - mfi_c1 = merge_file_special_markers(o, a, c1, &ci->ren1_other,
1249 - o->branch1, c1->path,
1250 - o->branch2, ci->ren1_other.path);
1251 - mfi_c2 = merge_file_special_markers(o, b, &ci->ren2_other, c2,
1252 - o->branch1, ci->ren2_other.path,
1253 - o->branch2, c2->path);
1251 + if (merge_file_special_markers(o, a, c1, &ci->ren1_other,
1252 + o->branch1, c1->path,
1253 + o->branch2, ci->ren1_other.path, &mfi_c1) ||
1254 + merge_file_special_markers(o, b, &ci->ren2_other, c2,
1255 + o->branch1, ci->ren2_other.path,
1256 + o->branch2, c2->path, &mfi_c2))
1257 + return;
1258
1259 if (o->call_depth) {
1260 /*
@@ -1473,12 +1477,13 @@ static int process_renames(struct merge_options *o,
1477 ren1_dst, branch2);
1478 if (o->call_depth) {
1479 struct merge_file_info mfi;
1476 - mfi = merge_file_one(o, ren1_dst, &null_oid, 0,
1477 - &ren1->pair->two->oid,
1478 - ren1->pair->two->mode,
1479 - &dst_other.oid,
1480 - dst_other.mode,
1481 - branch1, branch2);
1480 + if (merge_file_one(o, ren1_dst, &null_oid, 0,
1481 + &ren1->pair->two->oid,
1482 + ren1->pair->two->mode,
1483 + &dst_other.oid,
1484 + dst_other.mode,
1485 + branch1, branch2, &mfi))
1486 + return -1;
1487 output(o, 1, _("Adding merged %s"), ren1_dst);
1488 update_file(o, 0, &mfi.oid,
1489 mfi.mode, ren1_dst);
@@ -1636,9 +1641,10 @@ static int merge_content(struct merge_options *o,
1641 if (dir_in_way(path, !o->call_depth))
1642 df_conflict_remains = 1;
1643 }
1639 - mfi = merge_file_special_markers(o, &one, &a, &b,
1640 - o->branch1, path1,
1641 - o->branch2, path2);
1644 + if (merge_file_special_markers(o, &one, &a, &b,
1645 + o->branch1, path1,
1646 + o->branch2, path2, &mfi))
1647 + return -1;
1648
1649 if (mfi.clean && !df_conflict_remains &&
1650 oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {