Johannes Schindelin <johannes.schindelin@xxxxxx> writes: > diff --git a/merge-recursive.c b/merge-recursive.c > index 6ab7dfc..bb075e3 100644 > --- a/merge-recursive.c > +++ b/merge-recursive.c > @@ -266,8 +266,10 @@ struct tree *write_tree_from_memory(struct merge_options *o) > active_cache_tree = cache_tree(); > > if (!cache_tree_fully_valid(active_cache_tree) && > - cache_tree_update(&the_index, 0) < 0) > - die(_("error building trees")); > + cache_tree_update(&the_index, 0) < 0) { > + error(_("error building trees")); > + return NULL; > + } This actually is a BUG(), isn't it? We have already verified that the cache is merged, so cache_tree_update() ought to be able to come up with the whole-tree hash. > @@ -548,19 +550,17 @@ static int update_stages(const char *path, const struct diff_filespec *o, > */ > int clear = 1; > int options = ADD_CACHE_OK_TO_ADD | ADD_CACHE_SKIP_DFCHECK; > + int ret = 0; > + > if (clear) > - if (remove_file_from_cache(path)) > - return -1; > - if (o) > - if (add_cacheinfo(o->mode, o->sha1, path, 1, 0, options)) > - return -1; > - if (a) > - if (add_cacheinfo(a->mode, a->sha1, path, 2, 0, options)) > - return -1; > - if (b) > - if (add_cacheinfo(b->mode, b->sha1, path, 3, 0, options)) > - return -1; > - return 0; > + ret = remove_file_from_cache(path); > + if (!ret && o) > + ret = add_cacheinfo(o->mode, o->sha1, path, 1, 0, options); > + if (!ret && a) > + ret = add_cacheinfo(a->mode, a->sha1, path, 2, 0, options); > + if (!ret && b) > + ret = add_cacheinfo(b->mode, b->sha1, path, 3, 0, options); > + return ret; > } Aren't the preimage and the postimage doing the same thing? The only two differences I spot are (1) it is clear in the original that the returned value is -1 in the error case, even if the error convention of remove_file_from_cache() and add_cacheinfo() were "0 is good, others are bad"; and (2) the control flow is easier to follow in the original. > @@ -736,7 +736,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) > return error(msg, path, _(": perhaps a D/F conflict?")); > } > > -static void update_file_flags(struct merge_options *o, > +static int update_file_flags(struct merge_options *o, > const unsigned char *sha, > unsigned mode, > const char *path, > @@ -777,8 +777,7 @@ static void update_file_flags(struct merge_options *o, > > if (make_room_for_path(o, path) < 0) { > update_wd = 0; > - free(buf); > - goto update_index; > + goto free_buf; > } > if (S_ISREG(mode) || (!has_symlinks && S_ISLNK(mode))) { > int fd; > @@ -801,20 +800,22 @@ static void update_file_flags(struct merge_options *o, > } else > die(_("do not know what to do with %06o %s '%s'"), > mode, sha1_to_hex(sha), path); > +free_buf: > free(buf); I somehow find the above change harder to follow than the original. > } > update_index: > if (update_cache) > add_cacheinfo(mode, sha, path, 0, update_wd, ADD_CACHE_OK_TO_ADD); > + return 0; > } > This one is in line with the stated goal of the patch. > @@ -1028,21 +1030,23 @@ static void handle_change_delete(struct merge_options *o, > * correct; since there is no true "middle point" between > * them, simply reuse the base version for virtual merge base. > */ > - remove_file_from_cache(path); > - update_file(o, 0, o_sha, o_mode, renamed ? renamed : path); > + ret = remove_file_from_cache(path); > + if (!ret) > + ret = update_file(o, 0, o_sha, o_mode, > + renamed ? renamed : path); As you noted in the log message, this does change the behaviour. If remove returns non-zero for whatever reason, we still did update() in the original, but we no longer do. Does this have negative effect to the overall codeflow? Or, assuming that everybody returns -1 for errors, perhaps ret = remove(); ret |= update(); may be a more faithful and safe conversion? > @@ -1087,21 +1094,22 @@ static void conflict_rename_delete(struct merge_options *o, > b_mode = dest->mode; > } > > - handle_change_delete(o, > + ret = handle_change_delete(o, > o->call_depth ? orig->path : dest->path, > orig->sha1, orig->mode, > a_sha, a_mode, > b_sha, b_mode, > _("rename"), _("renamed")); > - > - if (o->call_depth) { > - remove_file_from_cache(dest->path); > - } else { > - update_stages(dest->path, NULL, > + if (ret < 0) > + return ret; > + if (o->call_depth) > + ret = remove_file_from_cache(dest->path); > + else > + ret = update_stages(dest->path, NULL, > rename_branch == o->branch1 ? dest : NULL, > rename_branch == o->branch1 ? NULL : dest); > - } Similarly, if handle_change_delete() returns non-zero, we no longer call remove() or update(). Is that a good behaviour change? > -static void handle_file(struct merge_options *o, > +static int handle_file(struct merge_options *o, > struct diff_filespec *rename, > int stage, > struct rename_conflict_info *ci) Likewise. > -static void conflict_rename_rename_1to2(struct merge_options *o, > +static int conflict_rename_rename_1to2(struct merge_options *o, > struct rename_conflict_info *ci) > { > ... > - if (merge_file_one(o, one->path, > + if ((ret = merge_file_one(o, one->path, > one->sha1, one->mode, > a->sha1, a->mode, > b->sha1, b->mode, > - ci->branch1, ci->branch2, &mfi) < 0) > - return; > + ci->branch1, ci->branch2, &mfi))) > + return ret; This does not change behaviour. > @@ -1194,7 +1208,8 @@ static void conflict_rename_rename_1to2(struct merge_options *o, > * pathname and then either rename the add-source file to that > * unique path, or use that unique path instead of src here. > */ > - update_file(o, 0, mfi.sha, mfi.mode, one->path); > + if ((ret = update_file(o, 0, mfi.sha, mfi.mode, one->path))) > + return ret; But this does. > @@ -1205,22 +1220,31 @@ static void conflict_rename_rename_1to2(struct merge_options *o, > * resolving the conflict at that path in its favor. > */ > add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); > - if (add) > - update_file(o, 0, add->sha1, add->mode, a->path); > + if (add) { > + if ((ret = update_file(o, 0, add->sha1, add->mode, > + a->path))) > + return ret; > + } So does this. > else > remove_file_from_cache(a->path); > add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); > - if (add) > - update_file(o, 0, add->sha1, add->mode, b->path); > + if (add) { > + if ((ret = update_file(o, 0, add->sha1, add->mode, > + b->path))) > + return ret; > + } And this. > } else { > - handle_file(o, a, 2, ci); > - handle_file(o, b, 3, ci); > + if ((ret = handle_file(o, a, 2, ci)) || > + (ret = handle_file(o, b, 3, ci))) > + return ret; And this. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html