4 * Based on git-am.sh by Junio C Hamano.
9 #include "parse-options.h"
11 #include "run-command.h"
16 * Returns 1 if the file is empty or does not exist, 0 otherwise.
18 static int is_empty_file(const char *filename
)
22 if (stat(filename
, &st
) < 0) {
25 die_errno(_("could not stat %s"), filename
);
32 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators.
34 static int strbuf_getline_crlf(struct strbuf
*sb
, FILE *fp
)
36 if (strbuf_getwholeline(sb
, fp
, '\n'))
38 if (sb
->buf
[sb
->len
- 1] == '\n') {
39 strbuf_setlen(sb
, sb
->len
- 1);
40 if (sb
->len
> 0 && sb
->buf
[sb
->len
- 1] == '\r')
41 strbuf_setlen(sb
, sb
->len
- 1);
47 * Returns the length of the first line of msg.
49 static int linelen(const char *msg
)
51 return strchrnul(msg
, '\n') - msg
;
55 PATCH_FORMAT_UNKNOWN
= 0,
60 /* state directory path */
63 /* current and last patch numbers, 1-indexed */
67 /* commit metadata and message */
74 /* number of digits in patch filename */
79 * Initializes am_state with the default values. The state directory is set to
82 static void am_state_init(struct am_state
*state
, const char *dir
)
84 memset(state
, 0, sizeof(*state
));
87 state
->dir
= xstrdup(dir
);
93 * Releases memory allocated by an am_state.
95 static void am_state_release(struct am_state
*state
)
98 free(state
->author_name
);
99 free(state
->author_email
);
100 free(state
->author_date
);
105 * Returns path relative to the am_state directory.
107 static inline const char *am_path(const struct am_state
*state
, const char *path
)
109 return mkpath("%s/%s", state
->dir
, path
);
113 * Returns 1 if there is an am session in progress, 0 otherwise.
115 static int am_in_progress(const struct am_state
*state
)
119 if (lstat(state
->dir
, &st
) < 0 || !S_ISDIR(st
.st_mode
))
121 if (lstat(am_path(state
, "last"), &st
) || !S_ISREG(st
.st_mode
))
123 if (lstat(am_path(state
, "next"), &st
) || !S_ISREG(st
.st_mode
))
129 * Reads the contents of `file` in the `state` directory into `sb`. Returns the
130 * number of bytes read on success, -1 if the file does not exist. If `trim` is
131 * set, trailing whitespace will be removed.
133 static int read_state_file(struct strbuf
*sb
, const struct am_state
*state
,
134 const char *file
, int trim
)
138 if (strbuf_read_file(sb
, am_path(state
, file
), 0) >= 0) {
148 die_errno(_("could not read '%s'"), am_path(state
, file
));
152 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE
153 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must
154 * match `key`. Returns NULL on failure.
156 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from
159 static char *read_shell_var(FILE *fp
, const char *key
)
161 struct strbuf sb
= STRBUF_INIT
;
164 if (strbuf_getline(&sb
, fp
, '\n'))
167 if (!skip_prefix(sb
.buf
, key
, &str
))
170 if (!skip_prefix(str
, "=", &str
))
173 strbuf_remove(&sb
, 0, str
- sb
.buf
);
175 str
= sq_dequote(sb
.buf
);
179 return strbuf_detach(&sb
, NULL
);
187 * Reads and parses the state directory's "author-script" file, and sets
188 * state->author_name, state->author_email and state->author_date accordingly.
189 * Returns 0 on success, -1 if the file could not be parsed.
191 * The author script is of the format:
193 * GIT_AUTHOR_NAME='$author_name'
194 * GIT_AUTHOR_EMAIL='$author_email'
195 * GIT_AUTHOR_DATE='$author_date'
197 * where $author_name, $author_email and $author_date are quoted. We are strict
198 * with our parsing, as the file was meant to be eval'd in the old git-am.sh
199 * script, and thus if the file differs from what this function expects, it is
200 * better to bail out than to do something that the user does not expect.
202 static int read_author_script(struct am_state
*state
)
204 const char *filename
= am_path(state
, "author-script");
207 assert(!state
->author_name
);
208 assert(!state
->author_email
);
209 assert(!state
->author_date
);
211 fp
= fopen(filename
, "r");
215 die_errno(_("could not open '%s' for reading"), filename
);
218 state
->author_name
= read_shell_var(fp
, "GIT_AUTHOR_NAME");
219 if (!state
->author_name
) {
224 state
->author_email
= read_shell_var(fp
, "GIT_AUTHOR_EMAIL");
225 if (!state
->author_email
) {
230 state
->author_date
= read_shell_var(fp
, "GIT_AUTHOR_DATE");
231 if (!state
->author_date
) {
236 if (fgetc(fp
) != EOF
) {
246 * Saves state->author_name, state->author_email and state->author_date in the
247 * state directory's "author-script" file.
249 static void write_author_script(const struct am_state
*state
)
251 struct strbuf sb
= STRBUF_INIT
;
253 strbuf_addstr(&sb
, "GIT_AUTHOR_NAME=");
254 sq_quote_buf(&sb
, state
->author_name
);
255 strbuf_addch(&sb
, '\n');
257 strbuf_addstr(&sb
, "GIT_AUTHOR_EMAIL=");
258 sq_quote_buf(&sb
, state
->author_email
);
259 strbuf_addch(&sb
, '\n');
261 strbuf_addstr(&sb
, "GIT_AUTHOR_DATE=");
262 sq_quote_buf(&sb
, state
->author_date
);
263 strbuf_addch(&sb
, '\n');
265 write_file(am_path(state
, "author-script"), 1, "%s", sb
.buf
);
271 * Reads the commit message from the state directory's "final-commit" file,
272 * setting state->msg to its contents and state->msg_len to the length of its
275 * Returns 0 on success, -1 if the file does not exist.
277 static int read_commit_msg(struct am_state
*state
)
279 struct strbuf sb
= STRBUF_INIT
;
283 if (read_state_file(&sb
, state
, "final-commit", 0) < 0) {
288 state
->msg
= strbuf_detach(&sb
, &state
->msg_len
);
293 * Saves state->msg in the state directory's "final-commit" file.
295 static void write_commit_msg(const struct am_state
*state
)
298 const char *filename
= am_path(state
, "final-commit");
300 fd
= xopen(filename
, O_WRONLY
| O_CREAT
, 0666);
301 if (write_in_full(fd
, state
->msg
, state
->msg_len
) < 0)
302 die_errno(_("could not write to %s"), filename
);
307 * Loads state from disk.
309 static void am_load(struct am_state
*state
)
311 struct strbuf sb
= STRBUF_INIT
;
313 if (read_state_file(&sb
, state
, "next", 1) < 0)
314 die("BUG: state file 'next' does not exist");
315 state
->cur
= strtol(sb
.buf
, NULL
, 10);
317 if (read_state_file(&sb
, state
, "last", 1) < 0)
318 die("BUG: state file 'last' does not exist");
319 state
->last
= strtol(sb
.buf
, NULL
, 10);
321 if (read_author_script(state
) < 0)
322 die(_("could not parse author script"));
324 read_commit_msg(state
);
330 * Removes the am_state directory, forcefully terminating the current am
333 static void am_destroy(const struct am_state
*state
)
335 struct strbuf sb
= STRBUF_INIT
;
337 strbuf_addstr(&sb
, state
->dir
);
338 remove_dir_recursively(&sb
, 0);
343 * Determines if the file looks like a piece of RFC2822 mail by grabbing all
344 * non-indented lines and checking if they look like they begin with valid
345 * header field names.
347 * Returns 1 if the file looks like a piece of mail, 0 otherwise.
349 static int is_mail(FILE *fp
)
351 const char *header_regex
= "^[!-9;-~]+:";
352 struct strbuf sb
= STRBUF_INIT
;
356 if (fseek(fp
, 0L, SEEK_SET
))
357 die_errno(_("fseek failed"));
359 if (regcomp(®ex
, header_regex
, REG_NOSUB
| REG_EXTENDED
))
360 die("invalid pattern: %s", header_regex
);
362 while (!strbuf_getline_crlf(&sb
, fp
)) {
364 break; /* End of header */
366 /* Ignore indented folded lines */
367 if (*sb
.buf
== '\t' || *sb
.buf
== ' ')
370 /* It's a header if it matches header_regex */
371 if (regexec(®ex
, sb
.buf
, 0, NULL
, 0)) {
384 * Attempts to detect the patch_format of the patches contained in `paths`,
385 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if
388 static int detect_patch_format(const char **paths
)
390 enum patch_format ret
= PATCH_FORMAT_UNKNOWN
;
391 struct strbuf l1
= STRBUF_INIT
;
395 * We default to mbox format if input is from stdin and for directories
397 if (!*paths
|| !strcmp(*paths
, "-") || is_directory(*paths
))
398 return PATCH_FORMAT_MBOX
;
401 * Otherwise, check the first few lines of the first patch, starting
402 * from the first non-blank line, to try to detect its format.
405 fp
= xfopen(*paths
, "r");
407 while (!strbuf_getline_crlf(&l1
, fp
)) {
412 if (starts_with(l1
.buf
, "From ") || starts_with(l1
.buf
, "From: ")) {
413 ret
= PATCH_FORMAT_MBOX
;
417 if (l1
.len
&& is_mail(fp
)) {
418 ret
= PATCH_FORMAT_MBOX
;
429 * Splits out individual email patches from `paths`, where each path is either
430 * a mbox file or a Maildir. Returns 0 on success, -1 on failure.
432 static int split_mail_mbox(struct am_state
*state
, const char **paths
)
434 struct child_process cp
= CHILD_PROCESS_INIT
;
435 struct strbuf last
= STRBUF_INIT
;
438 argv_array_push(&cp
.args
, "mailsplit");
439 argv_array_pushf(&cp
.args
, "-d%d", state
->prec
);
440 argv_array_pushf(&cp
.args
, "-o%s", state
->dir
);
441 argv_array_push(&cp
.args
, "-b");
442 argv_array_push(&cp
.args
, "--");
443 argv_array_pushv(&cp
.args
, paths
);
445 if (capture_command(&cp
, &last
, 8))
449 state
->last
= strtol(last
.buf
, NULL
, 10);
455 * Splits a list of files/directories into individual email patches. Each path
456 * in `paths` must be a file/directory that is formatted according to
459 * Once split out, the individual email patches will be stored in the state
460 * directory, with each patch's filename being its index, padded to state->prec
463 * state->cur will be set to the index of the first mail, and state->last will
464 * be set to the index of the last mail.
466 * Returns 0 on success, -1 on failure.
468 static int split_mail(struct am_state
*state
, enum patch_format patch_format
,
471 switch (patch_format
) {
472 case PATCH_FORMAT_MBOX
:
473 return split_mail_mbox(state
, paths
);
475 die("BUG: invalid patch_format");
481 * Setup a new am session for applying patches
483 static void am_setup(struct am_state
*state
, enum patch_format patch_format
,
487 patch_format
= detect_patch_format(paths
);
490 fprintf_ln(stderr
, _("Patch format detection failed."));
494 if (mkdir(state
->dir
, 0777) < 0 && errno
!= EEXIST
)
495 die_errno(_("failed to create directory '%s'"), state
->dir
);
497 if (split_mail(state
, patch_format
, paths
) < 0) {
499 die(_("Failed to split patches."));
503 * NOTE: Since the "next" and "last" files determine if an am_state
504 * session is in progress, they should be written last.
507 write_file(am_path(state
, "next"), 1, "%d", state
->cur
);
509 write_file(am_path(state
, "last"), 1, "%d", state
->last
);
513 * Increments the patch pointer, and cleans am_state for the application of the
516 static void am_next(struct am_state
*state
)
518 free(state
->author_name
);
519 state
->author_name
= NULL
;
521 free(state
->author_email
);
522 state
->author_email
= NULL
;
524 free(state
->author_date
);
525 state
->author_date
= NULL
;
531 unlink(am_path(state
, "author-script"));
532 unlink(am_path(state
, "final-commit"));
535 write_file(am_path(state
, "next"), 1, "%d", state
->cur
);
539 * Returns the filename of the current patch email.
541 static const char *msgnum(const struct am_state
*state
)
543 static struct strbuf sb
= STRBUF_INIT
;
546 strbuf_addf(&sb
, "%0*d", state
->prec
, state
->cur
);
552 * Refresh and write index.
554 static void refresh_and_write_cache(void)
556 struct lock_file
*lock_file
= xcalloc(1, sizeof(struct lock_file
));
558 hold_locked_index(lock_file
, 1);
559 refresh_cache(REFRESH_QUIET
);
560 if (write_locked_index(&the_index
, lock_file
, COMMIT_LOCK
))
561 die(_("unable to write index file"));
565 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.
566 * state->msg will be set to the patch message. state->author_name,
567 * state->author_email and state->author_date will be set to the patch author's
568 * name, email and date respectively. The patch body will be written to the
569 * state directory's "patch" file.
571 * Returns 1 if the patch should be skipped, 0 otherwise.
573 static int parse_mail(struct am_state
*state
, const char *mail
)
576 struct child_process cp
= CHILD_PROCESS_INIT
;
577 struct strbuf sb
= STRBUF_INIT
;
578 struct strbuf msg
= STRBUF_INIT
;
579 struct strbuf author_name
= STRBUF_INIT
;
580 struct strbuf author_date
= STRBUF_INIT
;
581 struct strbuf author_email
= STRBUF_INIT
;
585 cp
.in
= xopen(mail
, O_RDONLY
, 0);
586 cp
.out
= xopen(am_path(state
, "info"), O_WRONLY
| O_CREAT
, 0777);
588 argv_array_push(&cp
.args
, "mailinfo");
589 argv_array_push(&cp
.args
, am_path(state
, "msg"));
590 argv_array_push(&cp
.args
, am_path(state
, "patch"));
592 if (run_command(&cp
) < 0)
593 die("could not parse patch");
598 /* Extract message and author information */
599 fp
= xfopen(am_path(state
, "info"), "r");
600 while (!strbuf_getline(&sb
, fp
, '\n')) {
603 if (skip_prefix(sb
.buf
, "Subject: ", &x
)) {
605 strbuf_addch(&msg
, '\n');
606 strbuf_addstr(&msg
, x
);
607 } else if (skip_prefix(sb
.buf
, "Author: ", &x
))
608 strbuf_addstr(&author_name
, x
);
609 else if (skip_prefix(sb
.buf
, "Email: ", &x
))
610 strbuf_addstr(&author_email
, x
);
611 else if (skip_prefix(sb
.buf
, "Date: ", &x
))
612 strbuf_addstr(&author_date
, x
);
616 /* Skip pine's internal folder data */
617 if (!strcmp(author_name
.buf
, "Mail System Internal Data")) {
622 if (is_empty_file(am_path(state
, "patch"))) {
623 printf_ln(_("Patch is empty. Was it split wrong?"));
627 strbuf_addstr(&msg
, "\n\n");
628 if (strbuf_read_file(&msg
, am_path(state
, "msg"), 0) < 0)
629 die_errno(_("could not read '%s'"), am_path(state
, "msg"));
632 assert(!state
->author_name
);
633 state
->author_name
= strbuf_detach(&author_name
, NULL
);
635 assert(!state
->author_email
);
636 state
->author_email
= strbuf_detach(&author_email
, NULL
);
638 assert(!state
->author_date
);
639 state
->author_date
= strbuf_detach(&author_date
, NULL
);
642 state
->msg
= strbuf_detach(&msg
, &state
->msg_len
);
645 strbuf_release(&msg
);
646 strbuf_release(&author_date
);
647 strbuf_release(&author_email
);
648 strbuf_release(&author_name
);
654 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise.
656 static int run_apply(const struct am_state
*state
)
658 struct child_process cp
= CHILD_PROCESS_INIT
;
662 argv_array_push(&cp
.args
, "apply");
663 argv_array_push(&cp
.args
, "--index");
664 argv_array_push(&cp
.args
, am_path(state
, "patch"));
666 if (run_command(&cp
))
669 /* Reload index as git-apply will have modified it. */
677 * Applies all queued mail.
679 static void am_run(struct am_state
*state
)
681 refresh_and_write_cache();
683 while (state
->cur
<= state
->last
) {
684 const char *mail
= am_path(state
, msgnum(state
));
686 if (!file_exists(mail
))
689 if (parse_mail(state
, mail
))
690 goto next
; /* mail should be skipped */
692 write_author_script(state
);
693 write_commit_msg(state
);
695 printf_ln(_("Applying: %.*s"), linelen(state
->msg
), state
->msg
);
697 if (run_apply(state
) < 0) {
698 int advice_amworkdir
= 1;
700 printf_ln(_("Patch failed at %s %.*s"), msgnum(state
),
701 linelen(state
->msg
), state
->msg
);
703 git_config_get_bool("advice.amworkdir", &advice_amworkdir
);
705 if (advice_amworkdir
)
706 printf_ln(_("The copy of the patch that failed is found in: %s"),
707 am_path(state
, "patch"));
713 * NEEDSWORK: After the patch has been applied to the index
714 * with git-apply, we need to make commit as well.
725 * parse_options() callback that validates and sets opt->value to the
726 * PATCH_FORMAT_* enum value corresponding to `arg`.
728 static int parse_opt_patchformat(const struct option
*opt
, const char *arg
, int unset
)
730 int *opt_value
= opt
->value
;
732 if (!strcmp(arg
, "mbox"))
733 *opt_value
= PATCH_FORMAT_MBOX
;
735 return error(_("Invalid value for --patch-format: %s"), arg
);
739 int cmd_am(int argc
, const char **argv
, const char *prefix
)
741 struct am_state state
;
742 int patch_format
= PATCH_FORMAT_UNKNOWN
;
744 const char * const usage
[] = {
745 N_("git am [options] [(<mbox>|<Maildir>)...]"),
749 struct option options
[] = {
750 OPT_CALLBACK(0, "patch-format", &patch_format
, N_("format"),
751 N_("format the patch(es) are in"),
752 parse_opt_patchformat
),
757 * NEEDSWORK: Once all the features of git-am.sh have been
758 * re-implemented in builtin/am.c, this preamble can be removed.
760 if (!getenv("_GIT_USE_BUILTIN_AM")) {
761 const char *path
= mkpath("%s/git-am", git_exec_path());
763 if (sane_execvp(path
, (char **)argv
) < 0)
764 die_errno("could not exec %s", path
);
766 prefix
= setup_git_directory();
767 trace_repo_setup(prefix
);
771 git_config(git_default_config
, NULL
);
773 am_state_init(&state
, git_path("rebase-apply"));
775 argc
= parse_options(argc
, argv
, prefix
, options
, usage
, 0);
777 if (read_index_preload(&the_index
, NULL
) < 0)
778 die(_("failed to read the index"));
780 if (am_in_progress(&state
))
783 struct argv_array paths
= ARGV_ARRAY_INIT
;
786 for (i
= 0; i
< argc
; i
++) {
787 if (is_absolute_path(argv
[i
]) || !prefix
)
788 argv_array_push(&paths
, argv
[i
]);
790 argv_array_push(&paths
, mkpath("%s/%s", prefix
, argv
[i
]));
793 am_setup(&state
, patch_format
, paths
.argv
);
795 argv_array_clear(&paths
);
800 am_state_release(&state
);