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) {