builtin/apply: make apply_patch() return -1 or -128 instead of die()ing
To libify `git apply` functionality we have to signal errors to the caller instead of die()ing. As a first step in this direction, let's make apply_patch() return -1 or -128 in case of errors instead of dying. For now its only caller apply_all_patches() will exit(128) when apply_patch() return -128 and it will exit(1) when it returns -1. We exit() with code 128 because that was what die() was doing and we want to keep the distinction between exiting with code 1 and exiting with code 128. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
Aug 8, 2016 at 23:03 UTC
f07a9f7643c8b261b5d03d9c288c44916277f05e
1 file changed
+45
-15
builtin/apply.c
+45
-15
@@ -4404,6 +4404,15 @@ static struct lock_file lock_file;
4404
#define INACCURATE_EOF (1<<0)
4405
#define RECOUNT (1<<1)
4406
4407
+/*
4408
+ * Try to apply a patch.
4409
+ *
4410
+ * Returns:
4411
+ * -128 if a bad error happened (like patch unreadable)
4412
+ * -1 if patch did not apply and user cannot deal with it
4413
+ * 0 if the patch applied
4414
+ * 1 if the patch did not apply but user might fix it
4415
+ */
4416
static int apply_patch(struct apply_state *state,
4417
int fd,
4418
const char *filename,
@@ -4413,6 +4422,7 @@ static int apply_patch(struct apply_state *state,
4422
struct strbuf buf = STRBUF_INIT; /* owns the patch text */
4423
struct patch *list = NULL, **listp = &list;
4424
int skipped_patch = 0;
4425
+ int res = 0;
4426
4427
state->patch_input_file = filename;
4428
read_patch_file(&buf, fd);
@@ -4445,8 +4455,11 @@ static int apply_patch(struct apply_state *state,
4455
offset += nr;
4456
}
4457
4448
- if (!list && !skipped_patch)
4449
- die(_("unrecognized input"));
4458
+ if (!list && !skipped_patch) {
4459
+ error(_("unrecognized input"));
4460
+ res = -128;
4461
+ goto end;
4462
+ }
4463
4464
if (state->whitespace_error && (state->ws_error_action == die_on_ws_error))
4465
state->apply = 0;
@@ -4455,21 +4468,23 @@ static int apply_patch(struct apply_state *state,
4468
if (state->update_index && state->newfd < 0)
4469
state->newfd = hold_locked_index(state->lock_file, 1);
4470
4458
- if (state->check_index) {
4459
- if (read_cache() < 0)
4460
- die(_("unable to read index file"));
4471
+ if (state->check_index && read_cache() < 0) {
4472
+ error(_("unable to read index file"));
4473
+ res = -128;
4474
+ goto end;
4475
}
4476
4477
if ((state->check || state->apply) &&
4478
check_patch_list(state, list) < 0 &&
4465
- !state->apply_with_reject)
4466
- exit(1);
4479
+ !state->apply_with_reject) {
4480
+ res = -1;
4481
+ goto end;
4482
+ }
4483
4484
if (state->apply && write_out_results(state, list)) {
4469
- if (state->apply_with_reject)
4470
- exit(1);
4485
/* with --3way, we still need to write the index out */
4472
- return 1;
4486
+ res = state->apply_with_reject ? -1 : 1;
4487
+ goto end;
4488
}
4489
4490
if (state->fake_ancestor)
@@ -4484,10 +4499,11 @@ static int apply_patch(struct apply_state *state,
4499
if (state->summary)
4500
summary_patch_list(list);
4501
4502
+end:
4503
free_patch_list(list);
4504
strbuf_release(&buf);
4505
string_list_clear(&state->fn_table, 0);
4490
- return 0;
4506
+ return res;
4507
}
4508
4509
static void git_apply_config(void)
@@ -4628,6 +4644,7 @@ static int apply_all_patches(struct apply_state *state,
4644
int options)
4645
{
4646
int i;
4647
+ int res;
4648
int errs = 0;
4649
int read_stdin = 1;
4650
@@ -4636,7 +4653,10 @@ static int apply_all_patches(struct apply_state *state,
4653
int fd;
4654
4655
if (!strcmp(arg, "-")) {
4639
- errs |= apply_patch(state, 0, "<stdin>", options);
4656
+ res = apply_patch(state, 0, "<stdin>", options);
4657
+ if (res < 0)
4658
+ goto end;
4659
+ errs |= res;
4660
read_stdin = 0;
4661
continue;
4662
} else if (0 < state->prefix_length)
@@ -4649,12 +4669,19 @@ static int apply_all_patches(struct apply_state *state,
4669
die_errno(_("can't open patch '%s'"), arg);
4670
read_stdin = 0;
4671
set_default_whitespace_mode(state);
4652
- errs |= apply_patch(state, fd, arg, options);
4672
+ res = apply_patch(state, fd, arg, options);
4673
+ if (res < 0)
4674
+ goto end;
4675
+ errs |= res;
4676
close(fd);
4677
}
4678
set_default_whitespace_mode(state);
4656
- if (read_stdin)
4657
- errs |= apply_patch(state, 0, "<stdin>", options);
4679
+ if (read_stdin) {
4680
+ res = apply_patch(state, 0, "<stdin>", options);
4681
+ if (res < 0)
4682
+ goto end;
4683
+ errs |= res;
4684
+ }
4685
4686
if (state->whitespace_error) {
4687
if (state->squelch_whitespace_errors &&
@@ -4690,6 +4717,9 @@ static int apply_all_patches(struct apply_state *state,
4717
}
4718
4719
return !!errs;
4720
+
4721
+end:
4722
+ exit(res == -1 ? 1 : 128);
4723
}
4724
4725
int cmd_apply(int argc, const char **argv, const char *prefix)