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