a2811b687a76bfc0f6829ee781270fd446618028
1/*
2 * Builtin "git am"
3 *
4 * Based on git-am.sh by Junio C Hamano.
5 */
6#include "cache.h"
7#include "builtin.h"
8#include "exec_cmd.h"
9#include "parse-options.h"
10#include "dir.h"
11#include "run-command.h"
12#include "quote.h"
13#include "lockfile.h"
14#include "cache-tree.h"
15#include "refs.h"
16#include "commit.h"
17
18/**
19 * Returns 1 if the file is empty or does not exist, 0 otherwise.
20 */
21static int is_empty_file(const char *filename)
22{
23 struct stat st;
24
25 if (stat(filename, &st) < 0) {
26 if (errno == ENOENT)
27 return 1;
28 die_errno(_("could not stat %s"), filename);
29 }
30
31 return !st.st_size;
32}
33
34/**
35 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators.
36 */
37static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp)
38{
39 if (strbuf_getwholeline(sb, fp, '\n'))
40 return EOF;
41 if (sb->buf[sb->len - 1] == '\n') {
42 strbuf_setlen(sb, sb->len - 1);
43 if (sb->len > 0 && sb->buf[sb->len - 1] == '\r')
44 strbuf_setlen(sb, sb->len - 1);
45 }
46 return 0;
47}
48
49/**
50 * Returns the length of the first line of msg.
51 */
52static int linelen(const char *msg)
53{
54 return strchrnul(msg, '\n') - msg;
55}
56
57enum patch_format {
58 PATCH_FORMAT_UNKNOWN = 0,
59 PATCH_FORMAT_MBOX
60};
61
62struct am_state {
63 /* state directory path */
64 char *dir;
65
66 /* current and last patch numbers, 1-indexed */
67 int cur;
68 int last;
69
70 /* commit metadata and message */
71 char *author_name;
72 char *author_email;
73 char *author_date;
74 char *msg;
75 size_t msg_len;
76
77 /* number of digits in patch filename */
78 int prec;
79};
80
81/**
82 * Initializes am_state with the default values. The state directory is set to
83 * dir.
84 */
85static void am_state_init(struct am_state *state, const char *dir)
86{
87 memset(state, 0, sizeof(*state));
88
89 assert(dir);
90 state->dir = xstrdup(dir);
91
92 state->prec = 4;
93}
94
95/**
96 * Releases memory allocated by an am_state.
97 */
98static void am_state_release(struct am_state *state)
99{
100 free(state->dir);
101 free(state->author_name);
102 free(state->author_email);
103 free(state->author_date);
104 free(state->msg);
105}
106
107/**
108 * Returns path relative to the am_state directory.
109 */
110static inline const char *am_path(const struct am_state *state, const char *path)
111{
112 return mkpath("%s/%s", state->dir, path);
113}
114
115/**
116 * Returns 1 if there is an am session in progress, 0 otherwise.
117 */
118static int am_in_progress(const struct am_state *state)
119{
120 struct stat st;
121
122 if (lstat(state->dir, &st) < 0 || !S_ISDIR(st.st_mode))
123 return 0;
124 if (lstat(am_path(state, "last"), &st) || !S_ISREG(st.st_mode))
125 return 0;
126 if (lstat(am_path(state, "next"), &st) || !S_ISREG(st.st_mode))
127 return 0;
128 return 1;
129}
130
131/**
132 * Reads the contents of `file` in the `state` directory into `sb`. Returns the
133 * number of bytes read on success, -1 if the file does not exist. If `trim` is
134 * set, trailing whitespace will be removed.
135 */
136static int read_state_file(struct strbuf *sb, const struct am_state *state,
137 const char *file, int trim)
138{
139 strbuf_reset(sb);
140
141 if (strbuf_read_file(sb, am_path(state, file), 0) >= 0) {
142 if (trim)
143 strbuf_trim(sb);
144
145 return sb->len;
146 }
147
148 if (errno == ENOENT)
149 return -1;
150
151 die_errno(_("could not read '%s'"), am_path(state, file));
152}
153
154/**
155 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE
156 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must
157 * match `key`. Returns NULL on failure.
158 *
159 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from
160 * the author-script.
161 */
162static char *read_shell_var(FILE *fp, const char *key)
163{
164 struct strbuf sb = STRBUF_INIT;
165 const char *str;
166
167 if (strbuf_getline(&sb, fp, '\n'))
168 goto fail;
169
170 if (!skip_prefix(sb.buf, key, &str))
171 goto fail;
172
173 if (!skip_prefix(str, "=", &str))
174 goto fail;
175
176 strbuf_remove(&sb, 0, str - sb.buf);
177
178 str = sq_dequote(sb.buf);
179 if (!str)
180 goto fail;
181
182 return strbuf_detach(&sb, NULL);
183
184fail:
185 strbuf_release(&sb);
186 return NULL;
187}
188
189/**
190 * Reads and parses the state directory's "author-script" file, and sets
191 * state->author_name, state->author_email and state->author_date accordingly.
192 * Returns 0 on success, -1 if the file could not be parsed.
193 *
194 * The author script is of the format:
195 *
196 * GIT_AUTHOR_NAME='$author_name'
197 * GIT_AUTHOR_EMAIL='$author_email'
198 * GIT_AUTHOR_DATE='$author_date'
199 *
200 * where $author_name, $author_email and $author_date are quoted. We are strict
201 * with our parsing, as the file was meant to be eval'd in the old git-am.sh
202 * script, and thus if the file differs from what this function expects, it is
203 * better to bail out than to do something that the user does not expect.
204 */
205static int read_author_script(struct am_state *state)
206{
207 const char *filename = am_path(state, "author-script");
208 FILE *fp;
209
210 assert(!state->author_name);
211 assert(!state->author_email);
212 assert(!state->author_date);
213
214 fp = fopen(filename, "r");
215 if (!fp) {
216 if (errno == ENOENT)
217 return 0;
218 die_errno(_("could not open '%s' for reading"), filename);
219 }
220
221 state->author_name = read_shell_var(fp, "GIT_AUTHOR_NAME");
222 if (!state->author_name) {
223 fclose(fp);
224 return -1;
225 }
226
227 state->author_email = read_shell_var(fp, "GIT_AUTHOR_EMAIL");
228 if (!state->author_email) {
229 fclose(fp);
230 return -1;
231 }
232
233 state->author_date = read_shell_var(fp, "GIT_AUTHOR_DATE");
234 if (!state->author_date) {
235 fclose(fp);
236 return -1;
237 }
238
239 if (fgetc(fp) != EOF) {
240 fclose(fp);
241 return -1;
242 }
243
244 fclose(fp);
245 return 0;
246}
247
248/**
249 * Saves state->author_name, state->author_email and state->author_date in the
250 * state directory's "author-script" file.
251 */
252static void write_author_script(const struct am_state *state)
253{
254 struct strbuf sb = STRBUF_INIT;
255
256 strbuf_addstr(&sb, "GIT_AUTHOR_NAME=");
257 sq_quote_buf(&sb, state->author_name);
258 strbuf_addch(&sb, '\n');
259
260 strbuf_addstr(&sb, "GIT_AUTHOR_EMAIL=");
261 sq_quote_buf(&sb, state->author_email);
262 strbuf_addch(&sb, '\n');
263
264 strbuf_addstr(&sb, "GIT_AUTHOR_DATE=");
265 sq_quote_buf(&sb, state->author_date);
266 strbuf_addch(&sb, '\n');
267
268 write_file(am_path(state, "author-script"), 1, "%s", sb.buf);
269
270 strbuf_release(&sb);
271}
272
273/**
274 * Reads the commit message from the state directory's "final-commit" file,
275 * setting state->msg to its contents and state->msg_len to the length of its
276 * contents in bytes.
277 *
278 * Returns 0 on success, -1 if the file does not exist.
279 */
280static int read_commit_msg(struct am_state *state)
281{
282 struct strbuf sb = STRBUF_INIT;
283
284 assert(!state->msg);
285
286 if (read_state_file(&sb, state, "final-commit", 0) < 0) {
287 strbuf_release(&sb);
288 return -1;
289 }
290
291 state->msg = strbuf_detach(&sb, &state->msg_len);
292 return 0;
293}
294
295/**
296 * Saves state->msg in the state directory's "final-commit" file.
297 */
298static void write_commit_msg(const struct am_state *state)
299{
300 int fd;
301 const char *filename = am_path(state, "final-commit");
302
303 fd = xopen(filename, O_WRONLY | O_CREAT, 0666);
304 if (write_in_full(fd, state->msg, state->msg_len) < 0)
305 die_errno(_("could not write to %s"), filename);
306 close(fd);
307}
308
309/**
310 * Loads state from disk.
311 */
312static void am_load(struct am_state *state)
313{
314 struct strbuf sb = STRBUF_INIT;
315
316 if (read_state_file(&sb, state, "next", 1) < 0)
317 die("BUG: state file 'next' does not exist");
318 state->cur = strtol(sb.buf, NULL, 10);
319
320 if (read_state_file(&sb, state, "last", 1) < 0)
321 die("BUG: state file 'last' does not exist");
322 state->last = strtol(sb.buf, NULL, 10);
323
324 if (read_author_script(state) < 0)
325 die(_("could not parse author script"));
326
327 read_commit_msg(state);
328
329 strbuf_release(&sb);
330}
331
332/**
333 * Removes the am_state directory, forcefully terminating the current am
334 * session.
335 */
336static void am_destroy(const struct am_state *state)
337{
338 struct strbuf sb = STRBUF_INIT;
339
340 strbuf_addstr(&sb, state->dir);
341 remove_dir_recursively(&sb, 0);
342 strbuf_release(&sb);
343}
344
345/**
346 * Determines if the file looks like a piece of RFC2822 mail by grabbing all
347 * non-indented lines and checking if they look like they begin with valid
348 * header field names.
349 *
350 * Returns 1 if the file looks like a piece of mail, 0 otherwise.
351 */
352static int is_mail(FILE *fp)
353{
354 const char *header_regex = "^[!-9;-~]+:";
355 struct strbuf sb = STRBUF_INIT;
356 regex_t regex;
357 int ret = 1;
358
359 if (fseek(fp, 0L, SEEK_SET))
360 die_errno(_("fseek failed"));
361
362 if (regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED))
363 die("invalid pattern: %s", header_regex);
364
365 while (!strbuf_getline_crlf(&sb, fp)) {
366 if (!sb.len)
367 break; /* End of header */
368
369 /* Ignore indented folded lines */
370 if (*sb.buf == '\t' || *sb.buf == ' ')
371 continue;
372
373 /* It's a header if it matches header_regex */
374 if (regexec(®ex, sb.buf, 0, NULL, 0)) {
375 ret = 0;
376 goto done;
377 }
378 }
379
380done:
381 regfree(®ex);
382 strbuf_release(&sb);
383 return ret;
384}
385
386/**
387 * Attempts to detect the patch_format of the patches contained in `paths`,
388 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if
389 * detection fails.
390 */
391static int detect_patch_format(const char **paths)
392{
393 enum patch_format ret = PATCH_FORMAT_UNKNOWN;
394 struct strbuf l1 = STRBUF_INIT;
395 FILE *fp;
396
397 /*
398 * We default to mbox format if input is from stdin and for directories
399 */
400 if (!*paths || !strcmp(*paths, "-") || is_directory(*paths))
401 return PATCH_FORMAT_MBOX;
402
403 /*
404 * Otherwise, check the first few lines of the first patch, starting
405 * from the first non-blank line, to try to detect its format.
406 */
407
408 fp = xfopen(*paths, "r");
409
410 while (!strbuf_getline_crlf(&l1, fp)) {
411 if (l1.len)
412 break;
413 }
414
415 if (starts_with(l1.buf, "From ") || starts_with(l1.buf, "From: ")) {
416 ret = PATCH_FORMAT_MBOX;
417 goto done;
418 }
419
420 if (l1.len && is_mail(fp)) {
421 ret = PATCH_FORMAT_MBOX;
422 goto done;
423 }
424
425done:
426 fclose(fp);
427 strbuf_release(&l1);
428 return ret;
429}
430
431/**
432 * Splits out individual email patches from `paths`, where each path is either
433 * a mbox file or a Maildir. Returns 0 on success, -1 on failure.
434 */
435static int split_mail_mbox(struct am_state *state, const char **paths)
436{
437 struct child_process cp = CHILD_PROCESS_INIT;
438 struct strbuf last = STRBUF_INIT;
439
440 cp.git_cmd = 1;
441 argv_array_push(&cp.args, "mailsplit");
442 argv_array_pushf(&cp.args, "-d%d", state->prec);
443 argv_array_pushf(&cp.args, "-o%s", state->dir);
444 argv_array_push(&cp.args, "-b");
445 argv_array_push(&cp.args, "--");
446 argv_array_pushv(&cp.args, paths);
447
448 if (capture_command(&cp, &last, 8))
449 return -1;
450
451 state->cur = 1;
452 state->last = strtol(last.buf, NULL, 10);
453
454 return 0;
455}
456
457/**
458 * Splits a list of files/directories into individual email patches. Each path
459 * in `paths` must be a file/directory that is formatted according to
460 * `patch_format`.
461 *
462 * Once split out, the individual email patches will be stored in the state
463 * directory, with each patch's filename being its index, padded to state->prec
464 * digits.
465 *
466 * state->cur will be set to the index of the first mail, and state->last will
467 * be set to the index of the last mail.
468 *
469 * Returns 0 on success, -1 on failure.
470 */
471static int split_mail(struct am_state *state, enum patch_format patch_format,
472 const char **paths)
473{
474 switch (patch_format) {
475 case PATCH_FORMAT_MBOX:
476 return split_mail_mbox(state, paths);
477 default:
478 die("BUG: invalid patch_format");
479 }
480 return -1;
481}
482
483/**
484 * Setup a new am session for applying patches
485 */
486static void am_setup(struct am_state *state, enum patch_format patch_format,
487 const char **paths)
488{
489 if (!patch_format)
490 patch_format = detect_patch_format(paths);
491
492 if (!patch_format) {
493 fprintf_ln(stderr, _("Patch format detection failed."));
494 exit(128);
495 }
496
497 if (mkdir(state->dir, 0777) < 0 && errno != EEXIST)
498 die_errno(_("failed to create directory '%s'"), state->dir);
499
500 if (split_mail(state, patch_format, paths) < 0) {
501 am_destroy(state);
502 die(_("Failed to split patches."));
503 }
504
505 /*
506 * NOTE: Since the "next" and "last" files determine if an am_state
507 * session is in progress, they should be written last.
508 */
509
510 write_file(am_path(state, "next"), 1, "%d", state->cur);
511
512 write_file(am_path(state, "last"), 1, "%d", state->last);
513}
514
515/**
516 * Increments the patch pointer, and cleans am_state for the application of the
517 * next patch.
518 */
519static void am_next(struct am_state *state)
520{
521 free(state->author_name);
522 state->author_name = NULL;
523
524 free(state->author_email);
525 state->author_email = NULL;
526
527 free(state->author_date);
528 state->author_date = NULL;
529
530 free(state->msg);
531 state->msg = NULL;
532 state->msg_len = 0;
533
534 unlink(am_path(state, "author-script"));
535 unlink(am_path(state, "final-commit"));
536
537 state->cur++;
538 write_file(am_path(state, "next"), 1, "%d", state->cur);
539}
540
541/**
542 * Returns the filename of the current patch email.
543 */
544static const char *msgnum(const struct am_state *state)
545{
546 static struct strbuf sb = STRBUF_INIT;
547
548 strbuf_reset(&sb);
549 strbuf_addf(&sb, "%0*d", state->prec, state->cur);
550
551 return sb.buf;
552}
553
554/**
555 * Refresh and write index.
556 */
557static void refresh_and_write_cache(void)
558{
559 struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
560
561 hold_locked_index(lock_file, 1);
562 refresh_cache(REFRESH_QUIET);
563 if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
564 die(_("unable to write index file"));
565}
566
567/**
568 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.
569 * state->msg will be set to the patch message. state->author_name,
570 * state->author_email and state->author_date will be set to the patch author's
571 * name, email and date respectively. The patch body will be written to the
572 * state directory's "patch" file.
573 *
574 * Returns 1 if the patch should be skipped, 0 otherwise.
575 */
576static int parse_mail(struct am_state *state, const char *mail)
577{
578 FILE *fp;
579 struct child_process cp = CHILD_PROCESS_INIT;
580 struct strbuf sb = STRBUF_INIT;
581 struct strbuf msg = STRBUF_INIT;
582 struct strbuf author_name = STRBUF_INIT;
583 struct strbuf author_date = STRBUF_INIT;
584 struct strbuf author_email = STRBUF_INIT;
585 int ret = 0;
586
587 cp.git_cmd = 1;
588 cp.in = xopen(mail, O_RDONLY, 0);
589 cp.out = xopen(am_path(state, "info"), O_WRONLY | O_CREAT, 0777);
590
591 argv_array_push(&cp.args, "mailinfo");
592 argv_array_push(&cp.args, am_path(state, "msg"));
593 argv_array_push(&cp.args, am_path(state, "patch"));
594
595 if (run_command(&cp) < 0)
596 die("could not parse patch");
597
598 close(cp.in);
599 close(cp.out);
600
601 /* Extract message and author information */
602 fp = xfopen(am_path(state, "info"), "r");
603 while (!strbuf_getline(&sb, fp, '\n')) {
604 const char *x;
605
606 if (skip_prefix(sb.buf, "Subject: ", &x)) {
607 if (msg.len)
608 strbuf_addch(&msg, '\n');
609 strbuf_addstr(&msg, x);
610 } else if (skip_prefix(sb.buf, "Author: ", &x))
611 strbuf_addstr(&author_name, x);
612 else if (skip_prefix(sb.buf, "Email: ", &x))
613 strbuf_addstr(&author_email, x);
614 else if (skip_prefix(sb.buf, "Date: ", &x))
615 strbuf_addstr(&author_date, x);
616 }
617 fclose(fp);
618
619 /* Skip pine's internal folder data */
620 if (!strcmp(author_name.buf, "Mail System Internal Data")) {
621 ret = 1;
622 goto finish;
623 }
624
625 if (is_empty_file(am_path(state, "patch"))) {
626 printf_ln(_("Patch is empty. Was it split wrong?"));
627 exit(128);
628 }
629
630 strbuf_addstr(&msg, "\n\n");
631 if (strbuf_read_file(&msg, am_path(state, "msg"), 0) < 0)
632 die_errno(_("could not read '%s'"), am_path(state, "msg"));
633 stripspace(&msg, 0);
634
635 assert(!state->author_name);
636 state->author_name = strbuf_detach(&author_name, NULL);
637
638 assert(!state->author_email);
639 state->author_email = strbuf_detach(&author_email, NULL);
640
641 assert(!state->author_date);
642 state->author_date = strbuf_detach(&author_date, NULL);
643
644 assert(!state->msg);
645 state->msg = strbuf_detach(&msg, &state->msg_len);
646
647finish:
648 strbuf_release(&msg);
649 strbuf_release(&author_date);
650 strbuf_release(&author_email);
651 strbuf_release(&author_name);
652 strbuf_release(&sb);
653 return ret;
654}
655
656/**
657 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise.
658 */
659static int run_apply(const struct am_state *state)
660{
661 struct child_process cp = CHILD_PROCESS_INIT;
662
663 cp.git_cmd = 1;
664
665 argv_array_push(&cp.args, "apply");
666 argv_array_push(&cp.args, "--index");
667 argv_array_push(&cp.args, am_path(state, "patch"));
668
669 if (run_command(&cp))
670 return -1;
671
672 /* Reload index as git-apply will have modified it. */
673 discard_cache();
674 read_cache();
675
676 return 0;
677}
678
679/**
680 * Commits the current index with state->msg as the commit message and
681 * state->author_name, state->author_email and state->author_date as the author
682 * information.
683 */
684static void do_commit(const struct am_state *state)
685{
686 unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],
687 commit[GIT_SHA1_RAWSZ];
688 unsigned char *ptr;
689 struct commit_list *parents = NULL;
690 const char *reflog_msg, *author;
691 struct strbuf sb = STRBUF_INIT;
692
693 if (write_cache_as_tree(tree, 0, NULL))
694 die(_("git write-tree failed to write a tree"));
695
696 if (!get_sha1_commit("HEAD", parent)) {
697 ptr = parent;
698 commit_list_insert(lookup_commit(parent), &parents);
699 } else {
700 ptr = NULL;
701 fprintf_ln(stderr, _("applying to an empty history"));
702 }
703
704 author = fmt_ident(state->author_name, state->author_email,
705 state->author_date, IDENT_STRICT);
706
707 if (commit_tree(state->msg, state->msg_len, tree, parents, commit,
708 author, NULL))
709 die(_("failed to write commit object"));
710
711 reflog_msg = getenv("GIT_REFLOG_ACTION");
712 if (!reflog_msg)
713 reflog_msg = "am";
714
715 strbuf_addf(&sb, "%s: %.*s", reflog_msg, linelen(state->msg),
716 state->msg);
717
718 update_ref(sb.buf, "HEAD", commit, ptr, 0, UPDATE_REFS_DIE_ON_ERR);
719
720 strbuf_release(&sb);
721}
722
723/**
724 * Applies all queued mail.
725 */
726static void am_run(struct am_state *state)
727{
728 const char *argv_gc_auto[] = {"gc", "--auto", NULL};
729
730 refresh_and_write_cache();
731
732 while (state->cur <= state->last) {
733 const char *mail = am_path(state, msgnum(state));
734
735 if (!file_exists(mail))
736 goto next;
737
738 if (parse_mail(state, mail))
739 goto next; /* mail should be skipped */
740
741 write_author_script(state);
742 write_commit_msg(state);
743
744 printf_ln(_("Applying: %.*s"), linelen(state->msg), state->msg);
745
746 if (run_apply(state) < 0) {
747 int advice_amworkdir = 1;
748
749 printf_ln(_("Patch failed at %s %.*s"), msgnum(state),
750 linelen(state->msg), state->msg);
751
752 git_config_get_bool("advice.amworkdir", &advice_amworkdir);
753
754 if (advice_amworkdir)
755 printf_ln(_("The copy of the patch that failed is found in: %s"),
756 am_path(state, "patch"));
757
758 exit(128);
759 }
760
761 do_commit(state);
762
763next:
764 am_next(state);
765 }
766
767 am_destroy(state);
768 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
769}
770
771/**
772 * parse_options() callback that validates and sets opt->value to the
773 * PATCH_FORMAT_* enum value corresponding to `arg`.
774 */
775static int parse_opt_patchformat(const struct option *opt, const char *arg, int unset)
776{
777 int *opt_value = opt->value;
778
779 if (!strcmp(arg, "mbox"))
780 *opt_value = PATCH_FORMAT_MBOX;
781 else
782 return error(_("Invalid value for --patch-format: %s"), arg);
783 return 0;
784}
785
786int cmd_am(int argc, const char **argv, const char *prefix)
787{
788 struct am_state state;
789 int patch_format = PATCH_FORMAT_UNKNOWN;
790
791 const char * const usage[] = {
792 N_("git am [options] [(<mbox>|<Maildir>)...]"),
793 NULL
794 };
795
796 struct option options[] = {
797 OPT_CALLBACK(0, "patch-format", &patch_format, N_("format"),
798 N_("format the patch(es) are in"),
799 parse_opt_patchformat),
800 OPT_END()
801 };
802
803 /*
804 * NEEDSWORK: Once all the features of git-am.sh have been
805 * re-implemented in builtin/am.c, this preamble can be removed.
806 */
807 if (!getenv("_GIT_USE_BUILTIN_AM")) {
808 const char *path = mkpath("%s/git-am", git_exec_path());
809
810 if (sane_execvp(path, (char **)argv) < 0)
811 die_errno("could not exec %s", path);
812 } else {
813 prefix = setup_git_directory();
814 trace_repo_setup(prefix);
815 setup_work_tree();
816 }
817
818 git_config(git_default_config, NULL);
819
820 am_state_init(&state, git_path("rebase-apply"));
821
822 argc = parse_options(argc, argv, prefix, options, usage, 0);
823
824 if (read_index_preload(&the_index, NULL) < 0)
825 die(_("failed to read the index"));
826
827 if (am_in_progress(&state))
828 am_load(&state);
829 else {
830 struct argv_array paths = ARGV_ARRAY_INIT;
831 int i;
832
833 for (i = 0; i < argc; i++) {
834 if (is_absolute_path(argv[i]) || !prefix)
835 argv_array_push(&paths, argv[i]);
836 else
837 argv_array_push(&paths, mkpath("%s/%s", prefix, argv[i]));
838 }
839
840 am_setup(&state, patch_format, paths.argv);
841
842 argv_array_clear(&paths);
843 }
844
845 am_run(&state);
846
847 am_state_release(&state);
848
849 return 0;
850}