The recursive merge machinery is supposed to be a library function, i.e.
it should return an error when it fails. Originally the functions were
part of the builtin "merge-recursive", though, where it was simpler to
call die() and be done with error handling.

The existing callers were already prepared to detect negative return
values to indicate errors and to behave as previously: exit with code 128
(which is the same thing that die() does, after printing the message).

Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
 merge-recursive.c | 62 +++++++++++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 27 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index 6beb1e4..bc59815 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -275,8 +275,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;
+       }
 
        result = lookup_tree(active_cache_tree->sha1);
 
@@ -716,12 +718,10 @@ static int make_room_for_path(struct merge_options *o, 
const char *path)
        /* Make sure leading directories are created */
        status = safe_create_leading_directories_const(path);
        if (status) {
-               if (status == SCLD_EXISTS) {
+               if (status == SCLD_EXISTS)
                        /* something else exists */
-                       error(msg, path, _(": perhaps a D/F conflict?"));
-                       return -1;
-               }
-               die(msg, path, "");
+                       return error(msg, path, _(": perhaps a D/F conflict?"));
+               return error(msg, path, "");
        }
 
        /*
@@ -749,6 +749,8 @@ static int update_file_flags(struct merge_options *o,
                             int update_cache,
                             int update_wd)
 {
+       int ret = 0;
+
        if (o->call_depth)
                update_wd = 0;
 
@@ -769,9 +771,11 @@ static int update_file_flags(struct merge_options *o,
 
                buf = read_sha1_file(oid->hash, &type, &size);
                if (!buf)
-                       die(_("cannot read object %s '%s'"), oid_to_hex(oid), 
path);
-               if (type != OBJ_BLOB)
-                       die(_("blob expected for %s '%s'"), oid_to_hex(oid), 
path);
+                       return error(_("cannot read object %s '%s'"), 
oid_to_hex(oid), path);
+               if (type != OBJ_BLOB) {
+                       ret = error(_("blob expected for %s '%s'"), 
oid_to_hex(oid), path);
+                       goto free_buf;
+               }
                if (S_ISREG(mode)) {
                        struct strbuf strbuf = STRBUF_INIT;
                        if (convert_to_working_tree(path, buf, size, &strbuf)) {
@@ -792,8 +796,11 @@ static int update_file_flags(struct merge_options *o,
                        else
                                mode = 0666;
                        fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
-                       if (fd < 0)
-                               die_errno(_("failed to open '%s'"), path);
+                       if (fd < 0) {
+                               ret = error_errno(_("failed to open '%s'"),
+                                                 path);
+                               goto free_buf;
+                       }
                        write_in_full(fd, buf, size);
                        close(fd);
                } else if (S_ISLNK(mode)) {
@@ -801,18 +808,18 @@ static int update_file_flags(struct merge_options *o,
                        safe_create_leading_directories_const(path);
                        unlink(path);
                        if (symlink(lnk, path))
-                               die_errno(_("failed to symlink '%s'"), path);
+                               ret = error_errno(_("failed to symlink '%s'"), 
path);
                        free(lnk);
                } else
-                       die(_("do not know what to do with %06o %s '%s'"),
-                           mode, oid_to_hex(oid), path);
+                       ret = error(_("do not know what to do with %06o %s 
'%s'"),
+                                   mode, oid_to_hex(oid), path);
  free_buf:
                free(buf);
        }
  update_index:
-       if (update_cache)
+       if (!ret && update_cache)
                add_cacheinfo(mode, oid, path, 0, update_wd, 
ADD_CACHE_OK_TO_ADD);
-       return 0;
+       return ret;
 }
 
 static int update_file(struct merge_options *o,
@@ -938,20 +945,22 @@ static int merge_file_1(struct merge_options *o,
                        oidcpy(&result->oid, &a->oid);
                else if (S_ISREG(a->mode)) {
                        mmbuffer_t result_buf;
-                       int merge_status;
+                       int ret = 0, merge_status;
 
                        merge_status = merge_3way(o, &result_buf, one, a, b,
                                                  branch1, branch2);
 
                        if ((merge_status < 0) || !result_buf.ptr)
-                               die(_("Failed to execute internal merge"));
+                               ret = error(_("Failed to execute internal 
merge"));
 
-                       if (write_sha1_file(result_buf.ptr, result_buf.size,
-                                           blob_type, result->oid.hash))
-                               die(_("Unable to add %s to database"),
-                                   a->path);
+                       if (!ret && write_sha1_file(result_buf.ptr, 
result_buf.size,
+                                                   blob_type, 
result->oid.hash))
+                               ret = error(_("Unable to add %s to database"),
+                                           a->path);
 
                        free(result_buf.ptr);
+                       if (ret)
+                               return ret;
                        result->clean = (merge_status == 0);
                } else if (S_ISGITLINK(a->mode)) {
                        result->clean = merge_submodule(result->oid.hash,
@@ -1885,11 +1894,10 @@ int merge_trees(struct merge_options *o,
 
        if (code != 0) {
                if (show(o, 4) || o->call_depth)
-                       die(_("merging of trees %s and %s failed"),
+                       error(_("merging of trees %s and %s failed"),
                            oid_to_hex(&head->object.oid),
                            oid_to_hex(&merge->object.oid));
-               else
-                       exit(128);
+               return -1;
        }
 
        if (unmerged_cache()) {
@@ -2021,7 +2029,7 @@ int merge_recursive(struct merge_options *o,
                o->call_depth--;
 
                if (!merged_common_ancestors)
-                       die(_("merge returned no commit"));
+                       return error(_("merge returned no commit"));
        }
 
        discard_cache();
-- 
2.9.0.281.g286a8d9


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to