summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/apply.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/builtin/apply.c b/builtin/apply.c
index ed923ca56f..435030a989 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -4404,6 +4404,15 @@ static struct lock_file lock_file;
#define INACCURATE_EOF (1<<0)
#define RECOUNT (1<<1)
+/*
+ * Try to apply a patch.
+ *
+ * Returns:
+ * -128 if a bad error happened (like patch unreadable)
+ * -1 if patch did not apply and user cannot deal with it
+ * 0 if the patch applied
+ * 1 if the patch did not apply but user might fix it
+ */
static int apply_patch(struct apply_state *state,
int fd,
const char *filename,
@@ -4413,6 +4422,7 @@ static int apply_patch(struct apply_state *state,
struct strbuf buf = STRBUF_INIT; /* owns the patch text */
struct patch *list = NULL, **listp = &list;
int skipped_patch = 0;
+ int res = 0;
state->patch_input_file = filename;
read_patch_file(&buf, fd);
@@ -4445,8 +4455,11 @@ static int apply_patch(struct apply_state *state,
offset += nr;
}
- if (!list && !skipped_patch)
- die(_("unrecognized input"));
+ if (!list && !skipped_patch) {
+ error(_("unrecognized input"));
+ res = -128;
+ goto end;
+ }
if (state->whitespace_error && (state->ws_error_action == die_on_ws_error))
state->apply = 0;
@@ -4455,21 +4468,23 @@ static int apply_patch(struct apply_state *state,
if (state->update_index && state->newfd < 0)
state->newfd = hold_locked_index(state->lock_file, 1);
- if (state->check_index) {
- if (read_cache() < 0)
- die(_("unable to read index file"));
+ if (state->check_index && read_cache() < 0) {
+ error(_("unable to read index file"));
+ res = -128;
+ goto end;
}
if ((state->check || state->apply) &&
check_patch_list(state, list) < 0 &&
- !state->apply_with_reject)
- exit(1);
+ !state->apply_with_reject) {
+ res = -1;
+ goto end;
+ }
if (state->apply && write_out_results(state, list)) {
- if (state->apply_with_reject)
- exit(1);
/* with --3way, we still need to write the index out */
- return 1;
+ res = state->apply_with_reject ? -1 : 1;
+ goto end;
}
if (state->fake_ancestor)
@@ -4484,10 +4499,11 @@ static int apply_patch(struct apply_state *state,
if (state->summary)
summary_patch_list(list);
+end:
free_patch_list(list);
strbuf_release(&buf);
string_list_clear(&state->fn_table, 0);
- return 0;
+ return res;
}
static void git_apply_config(void)
@@ -4628,6 +4644,7 @@ static int apply_all_patches(struct apply_state *state,
int options)
{
int i;
+ int res;
int errs = 0;
int read_stdin = 1;
@@ -4636,7 +4653,10 @@ static int apply_all_patches(struct apply_state *state,
int fd;
if (!strcmp(arg, "-")) {
- errs |= apply_patch(state, 0, "<stdin>", options);
+ res = apply_patch(state, 0, "<stdin>", options);
+ if (res < 0)
+ goto end;
+ errs |= res;
read_stdin = 0;
continue;
} else if (0 < state->prefix_length)
@@ -4649,12 +4669,19 @@ static int apply_all_patches(struct apply_state *state,
die_errno(_("can't open patch '%s'"), arg);
read_stdin = 0;
set_default_whitespace_mode(state);
- errs |= apply_patch(state, fd, arg, options);
+ res = apply_patch(state, fd, arg, options);
+ if (res < 0)
+ goto end;
+ errs |= res;
close(fd);
}
set_default_whitespace_mode(state);
- if (read_stdin)
- errs |= apply_patch(state, 0, "<stdin>", options);
+ if (read_stdin) {
+ res = apply_patch(state, 0, "<stdin>", options);
+ if (res < 0)
+ goto end;
+ errs |= res;
+ }
if (state->whitespace_error) {
if (state->squelch_whitespace_errors &&
@@ -4690,6 +4717,9 @@ static int apply_all_patches(struct apply_state *state,
}
return !!errs;
+
+end:
+ exit(res == -1 ? 1 : 128);
}
int cmd_apply(int argc, const char **argv, const char *prefix)