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>
This commit is contained in:

committed by
Junio C Hamano

parent
de8946de16
commit
3c8a51e89a
@ -894,47 +894,47 @@ static int merge_3way(struct merge_options *o,
|
|||||||
return merge_status;
|
return merge_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct merge_file_info merge_file_1(struct merge_options *o,
|
static int merge_file_1(struct merge_options *o,
|
||||||
const struct diff_filespec *one,
|
const struct diff_filespec *one,
|
||||||
const struct diff_filespec *a,
|
const struct diff_filespec *a,
|
||||||
const struct diff_filespec *b,
|
const struct diff_filespec *b,
|
||||||
const char *branch1,
|
const char *branch1,
|
||||||
const char *branch2)
|
const char *branch2,
|
||||||
|
struct merge_file_info *result)
|
||||||
{
|
{
|
||||||
struct merge_file_info result;
|
result->merge = 0;
|
||||||
result.merge = 0;
|
result->clean = 1;
|
||||||
result.clean = 1;
|
|
||||||
|
|
||||||
if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) {
|
if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) {
|
||||||
result.clean = 0;
|
result->clean = 0;
|
||||||
if (S_ISREG(a->mode)) {
|
if (S_ISREG(a->mode)) {
|
||||||
result.mode = a->mode;
|
result->mode = a->mode;
|
||||||
oidcpy(&result.oid, &a->oid);
|
oidcpy(&result->oid, &a->oid);
|
||||||
} else {
|
} else {
|
||||||
result.mode = b->mode;
|
result->mode = b->mode;
|
||||||
oidcpy(&result.oid, &b->oid);
|
oidcpy(&result->oid, &b->oid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid))
|
if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid))
|
||||||
result.merge = 1;
|
result->merge = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Merge modes
|
* Merge modes
|
||||||
*/
|
*/
|
||||||
if (a->mode == b->mode || a->mode == one->mode)
|
if (a->mode == b->mode || a->mode == one->mode)
|
||||||
result.mode = b->mode;
|
result->mode = b->mode;
|
||||||
else {
|
else {
|
||||||
result.mode = a->mode;
|
result->mode = a->mode;
|
||||||
if (b->mode != one->mode) {
|
if (b->mode != one->mode) {
|
||||||
result.clean = 0;
|
result->clean = 0;
|
||||||
result.merge = 1;
|
result->merge = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid))
|
if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid))
|
||||||
oidcpy(&result.oid, &b->oid);
|
oidcpy(&result->oid, &b->oid);
|
||||||
else if (oid_eq(&b->oid, &one->oid))
|
else if (oid_eq(&b->oid, &one->oid))
|
||||||
oidcpy(&result.oid, &a->oid);
|
oidcpy(&result->oid, &a->oid);
|
||||||
else if (S_ISREG(a->mode)) {
|
else if (S_ISREG(a->mode)) {
|
||||||
mmbuffer_t result_buf;
|
mmbuffer_t result_buf;
|
||||||
int merge_status;
|
int merge_status;
|
||||||
@ -946,64 +946,66 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
|
|||||||
die(_("Failed to execute internal merge"));
|
die(_("Failed to execute internal merge"));
|
||||||
|
|
||||||
if (write_sha1_file(result_buf.ptr, result_buf.size,
|
if (write_sha1_file(result_buf.ptr, result_buf.size,
|
||||||
blob_type, result.oid.hash))
|
blob_type, result->oid.hash))
|
||||||
die(_("Unable to add %s to database"),
|
die(_("Unable to add %s to database"),
|
||||||
a->path);
|
a->path);
|
||||||
|
|
||||||
free(result_buf.ptr);
|
free(result_buf.ptr);
|
||||||
result.clean = (merge_status == 0);
|
result->clean = (merge_status == 0);
|
||||||
} else if (S_ISGITLINK(a->mode)) {
|
} else if (S_ISGITLINK(a->mode)) {
|
||||||
result.clean = merge_submodule(result.oid.hash,
|
result->clean = merge_submodule(result->oid.hash,
|
||||||
one->path,
|
one->path,
|
||||||
one->oid.hash,
|
one->oid.hash,
|
||||||
a->oid.hash,
|
a->oid.hash,
|
||||||
b->oid.hash,
|
b->oid.hash,
|
||||||
!o->call_depth);
|
!o->call_depth);
|
||||||
} else if (S_ISLNK(a->mode)) {
|
} else if (S_ISLNK(a->mode)) {
|
||||||
oidcpy(&result.oid, &a->oid);
|
oidcpy(&result->oid, &a->oid);
|
||||||
|
|
||||||
if (!oid_eq(&a->oid, &b->oid))
|
if (!oid_eq(&a->oid, &b->oid))
|
||||||
result.clean = 0;
|
result->clean = 0;
|
||||||
} else
|
} else
|
||||||
die("BUG: unsupported object type in the tree");
|
die("BUG: unsupported object type in the tree");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct merge_file_info
|
static int merge_file_special_markers(struct merge_options *o,
|
||||||
merge_file_special_markers(struct merge_options *o,
|
|
||||||
const struct diff_filespec *one,
|
const struct diff_filespec *one,
|
||||||
const struct diff_filespec *a,
|
const struct diff_filespec *a,
|
||||||
const struct diff_filespec *b,
|
const struct diff_filespec *b,
|
||||||
const char *branch1,
|
const char *branch1,
|
||||||
const char *filename1,
|
const char *filename1,
|
||||||
const char *branch2,
|
const char *branch2,
|
||||||
const char *filename2)
|
const char *filename2,
|
||||||
|
struct merge_file_info *mfi)
|
||||||
{
|
{
|
||||||
char *side1 = NULL;
|
char *side1 = NULL;
|
||||||
char *side2 = NULL;
|
char *side2 = NULL;
|
||||||
struct merge_file_info mfi;
|
int ret;
|
||||||
|
|
||||||
if (filename1)
|
if (filename1)
|
||||||
side1 = xstrfmt("%s:%s", branch1, filename1);
|
side1 = xstrfmt("%s:%s", branch1, filename1);
|
||||||
if (filename2)
|
if (filename2)
|
||||||
side2 = xstrfmt("%s:%s", branch2, filename2);
|
side2 = xstrfmt("%s:%s", branch2, filename2);
|
||||||
|
|
||||||
mfi = merge_file_1(o, one, a, b,
|
ret = merge_file_1(o, one, a, b,
|
||||||
side1 ? side1 : branch1, side2 ? side2 : branch2);
|
side1 ? side1 : branch1,
|
||||||
|
side2 ? side2 : branch2, mfi);
|
||||||
free(side1);
|
free(side1);
|
||||||
free(side2);
|
free(side2);
|
||||||
return mfi;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct merge_file_info merge_file_one(struct merge_options *o,
|
static int merge_file_one(struct merge_options *o,
|
||||||
const char *path,
|
const char *path,
|
||||||
const struct object_id *o_oid, int o_mode,
|
const struct object_id *o_oid, int o_mode,
|
||||||
const struct object_id *a_oid, int a_mode,
|
const struct object_id *a_oid, int a_mode,
|
||||||
const struct object_id *b_oid, int b_mode,
|
const struct object_id *b_oid, int b_mode,
|
||||||
const char *branch1,
|
const char *branch1,
|
||||||
const char *branch2)
|
const char *branch2,
|
||||||
|
struct merge_file_info *mfi)
|
||||||
{
|
{
|
||||||
struct diff_filespec one, a, b;
|
struct diff_filespec one, a, b;
|
||||||
|
|
||||||
@ -1014,7 +1016,7 @@ static struct merge_file_info merge_file_one(struct merge_options *o,
|
|||||||
a.mode = a_mode;
|
a.mode = a_mode;
|
||||||
oidcpy(&b.oid, b_oid);
|
oidcpy(&b.oid, b_oid);
|
||||||
b.mode = b_mode;
|
b.mode = b_mode;
|
||||||
return merge_file_1(o, &one, &a, &b, branch1, branch2);
|
return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_change_delete(struct merge_options *o,
|
static void handle_change_delete(struct merge_options *o,
|
||||||
@ -1187,11 +1189,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
|
|||||||
struct merge_file_info mfi;
|
struct merge_file_info mfi;
|
||||||
struct diff_filespec other;
|
struct diff_filespec other;
|
||||||
struct diff_filespec *add;
|
struct diff_filespec *add;
|
||||||
mfi = merge_file_one(o, one->path,
|
if (merge_file_one(o, one->path,
|
||||||
&one->oid, one->mode,
|
&one->oid, one->mode,
|
||||||
&a->oid, a->mode,
|
&a->oid, a->mode,
|
||||||
&b->oid, b->mode,
|
&b->oid, b->mode,
|
||||||
ci->branch1, ci->branch2);
|
ci->branch1, ci->branch2, &mfi))
|
||||||
|
return;
|
||||||
/*
|
/*
|
||||||
* FIXME: For rename/add-source conflicts (if we could detect
|
* FIXME: For rename/add-source conflicts (if we could detect
|
||||||
* such), this is wrong. We should instead find a unique
|
* such), this is wrong. We should instead find a unique
|
||||||
@ -1245,12 +1248,13 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
|
|||||||
remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
|
remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
|
||||||
remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
|
remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
|
||||||
|
|
||||||
mfi_c1 = merge_file_special_markers(o, a, c1, &ci->ren1_other,
|
if (merge_file_special_markers(o, a, c1, &ci->ren1_other,
|
||||||
o->branch1, c1->path,
|
o->branch1, c1->path,
|
||||||
o->branch2, ci->ren1_other.path);
|
o->branch2, ci->ren1_other.path, &mfi_c1) ||
|
||||||
mfi_c2 = merge_file_special_markers(o, b, &ci->ren2_other, c2,
|
merge_file_special_markers(o, b, &ci->ren2_other, c2,
|
||||||
o->branch1, ci->ren2_other.path,
|
o->branch1, ci->ren2_other.path,
|
||||||
o->branch2, c2->path);
|
o->branch2, c2->path, &mfi_c2))
|
||||||
|
return;
|
||||||
|
|
||||||
if (o->call_depth) {
|
if (o->call_depth) {
|
||||||
/*
|
/*
|
||||||
@ -1473,12 +1477,13 @@ static int process_renames(struct merge_options *o,
|
|||||||
ren1_dst, branch2);
|
ren1_dst, branch2);
|
||||||
if (o->call_depth) {
|
if (o->call_depth) {
|
||||||
struct merge_file_info mfi;
|
struct merge_file_info mfi;
|
||||||
mfi = merge_file_one(o, ren1_dst, &null_oid, 0,
|
if (merge_file_one(o, ren1_dst, &null_oid, 0,
|
||||||
&ren1->pair->two->oid,
|
&ren1->pair->two->oid,
|
||||||
ren1->pair->two->mode,
|
ren1->pair->two->mode,
|
||||||
&dst_other.oid,
|
&dst_other.oid,
|
||||||
dst_other.mode,
|
dst_other.mode,
|
||||||
branch1, branch2);
|
branch1, branch2, &mfi))
|
||||||
|
return -1;
|
||||||
output(o, 1, _("Adding merged %s"), ren1_dst);
|
output(o, 1, _("Adding merged %s"), ren1_dst);
|
||||||
update_file(o, 0, &mfi.oid,
|
update_file(o, 0, &mfi.oid,
|
||||||
mfi.mode, ren1_dst);
|
mfi.mode, ren1_dst);
|
||||||
@ -1636,9 +1641,10 @@ static int merge_content(struct merge_options *o,
|
|||||||
if (dir_in_way(path, !o->call_depth))
|
if (dir_in_way(path, !o->call_depth))
|
||||||
df_conflict_remains = 1;
|
df_conflict_remains = 1;
|
||||||
}
|
}
|
||||||
mfi = merge_file_special_markers(o, &one, &a, &b,
|
if (merge_file_special_markers(o, &one, &a, &b,
|
||||||
o->branch1, path1,
|
o->branch1, path1,
|
||||||
o->branch2, path2);
|
o->branch2, path2, &mfi))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (mfi.clean && !df_conflict_remains &&
|
if (mfi.clean && !df_conflict_remains &&
|
||||||
oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {
|
oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {
|
||||||
|
Reference in New Issue
Block a user