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"tempfile.h" 14#include"lockfile.h" 15#include"cache-tree.h" 16#include"refs.h" 17#include"commit.h" 18#include"diff.h" 19#include"diffcore.h" 20#include"unpack-trees.h" 21#include"branch.h" 22#include"sequencer.h" 23#include"revision.h" 24#include"merge-recursive.h" 25#include"revision.h" 26#include"log-tree.h" 27#include"notes-utils.h" 28#include"rerere.h" 29#include"prompt.h" 30#include"mailinfo.h" 31 32/** 33 * Returns 1 if the file is empty or does not exist, 0 otherwise. 34 */ 35static intis_empty_file(const char*filename) 36{ 37struct stat st; 38 39if(stat(filename, &st) <0) { 40if(errno == ENOENT) 41return1; 42die_errno(_("could not stat%s"), filename); 43} 44 45return!st.st_size; 46} 47 48/** 49 * Returns the length of the first line of msg. 50 */ 51static intlinelen(const char*msg) 52{ 53returnstrchrnul(msg,'\n') - msg; 54} 55 56/** 57 * Returns true if `str` consists of only whitespace, false otherwise. 58 */ 59static intstr_isspace(const char*str) 60{ 61for(; *str; str++) 62if(!isspace(*str)) 63return0; 64 65return1; 66} 67 68enum patch_format { 69 PATCH_FORMAT_UNKNOWN =0, 70 PATCH_FORMAT_MBOX, 71 PATCH_FORMAT_STGIT, 72 PATCH_FORMAT_STGIT_SERIES, 73 PATCH_FORMAT_HG 74}; 75 76enum keep_type { 77 KEEP_FALSE =0, 78 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 79 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 80}; 81 82enum scissors_type { 83 SCISSORS_UNSET = -1, 84 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 85 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 86}; 87 88enum signoff_type { 89 SIGNOFF_FALSE =0, 90 SIGNOFF_TRUE =1, 91 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 92}; 93 94struct am_state { 95/* state directory path */ 96char*dir; 97 98/* current and last patch numbers, 1-indexed */ 99int cur; 100int last; 101 102/* commit metadata and message */ 103char*author_name; 104char*author_email; 105char*author_date; 106char*msg; 107size_t msg_len; 108 109/* when --rebasing, records the original commit the patch came from */ 110unsigned char orig_commit[GIT_SHA1_RAWSZ]; 111 112/* number of digits in patch filename */ 113int prec; 114 115/* various operating modes and command line options */ 116int interactive; 117int threeway; 118int quiet; 119int signoff;/* enum signoff_type */ 120int utf8; 121int keep;/* enum keep_type */ 122int message_id; 123int scissors;/* enum scissors_type */ 124struct argv_array git_apply_opts; 125const char*resolvemsg; 126int committer_date_is_author_date; 127int ignore_date; 128int allow_rerere_autoupdate; 129const char*sign_commit; 130int rebasing; 131}; 132 133/** 134 * Initializes am_state with the default values. The state directory is set to 135 * dir. 136 */ 137static voidam_state_init(struct am_state *state,const char*dir) 138{ 139int gpgsign; 140 141memset(state,0,sizeof(*state)); 142 143assert(dir); 144 state->dir =xstrdup(dir); 145 146 state->prec =4; 147 148git_config_get_bool("am.threeway", &state->threeway); 149 150 state->utf8 =1; 151 152git_config_get_bool("am.messageid", &state->message_id); 153 154 state->scissors = SCISSORS_UNSET; 155 156argv_array_init(&state->git_apply_opts); 157 158if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 159 state->sign_commit = gpgsign ?"": NULL; 160} 161 162/** 163 * Releases memory allocated by an am_state. 164 */ 165static voidam_state_release(struct am_state *state) 166{ 167free(state->dir); 168free(state->author_name); 169free(state->author_email); 170free(state->author_date); 171free(state->msg); 172argv_array_clear(&state->git_apply_opts); 173} 174 175/** 176 * Returns path relative to the am_state directory. 177 */ 178staticinlineconst char*am_path(const struct am_state *state,const char*path) 179{ 180returnmkpath("%s/%s", state->dir, path); 181} 182 183/** 184 * For convenience to call write_file() 185 */ 186static intwrite_state_text(const struct am_state *state, 187const char*name,const char*string) 188{ 189returnwrite_file(am_path(state, name),"%s", string); 190} 191 192static intwrite_state_count(const struct am_state *state, 193const char*name,int value) 194{ 195returnwrite_file(am_path(state, name),"%d", value); 196} 197 198static intwrite_state_bool(const struct am_state *state, 199const char*name,int value) 200{ 201returnwrite_state_text(state, name, value ?"t":"f"); 202} 203 204/** 205 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 206 * at the end. 207 */ 208static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 209{ 210va_list ap; 211 212va_start(ap, fmt); 213if(!state->quiet) { 214vfprintf(fp, fmt, ap); 215putc('\n', fp); 216} 217va_end(ap); 218} 219 220/** 221 * Returns 1 if there is an am session in progress, 0 otherwise. 222 */ 223static intam_in_progress(const struct am_state *state) 224{ 225struct stat st; 226 227if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 228return0; 229if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 230return0; 231if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 232return0; 233return1; 234} 235 236/** 237 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 238 * number of bytes read on success, -1 if the file does not exist. If `trim` is 239 * set, trailing whitespace will be removed. 240 */ 241static intread_state_file(struct strbuf *sb,const struct am_state *state, 242const char*file,int trim) 243{ 244strbuf_reset(sb); 245 246if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 247if(trim) 248strbuf_trim(sb); 249 250return sb->len; 251} 252 253if(errno == ENOENT) 254return-1; 255 256die_errno(_("could not read '%s'"),am_path(state, file)); 257} 258 259/** 260 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 261 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 262 * match `key`. Returns NULL on failure. 263 * 264 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 265 * the author-script. 266 */ 267static char*read_shell_var(FILE*fp,const char*key) 268{ 269struct strbuf sb = STRBUF_INIT; 270const char*str; 271 272if(strbuf_getline_lf(&sb, fp)) 273goto fail; 274 275if(!skip_prefix(sb.buf, key, &str)) 276goto fail; 277 278if(!skip_prefix(str,"=", &str)) 279goto fail; 280 281strbuf_remove(&sb,0, str - sb.buf); 282 283 str =sq_dequote(sb.buf); 284if(!str) 285goto fail; 286 287returnstrbuf_detach(&sb, NULL); 288 289fail: 290strbuf_release(&sb); 291return NULL; 292} 293 294/** 295 * Reads and parses the state directory's "author-script" file, and sets 296 * state->author_name, state->author_email and state->author_date accordingly. 297 * Returns 0 on success, -1 if the file could not be parsed. 298 * 299 * The author script is of the format: 300 * 301 * GIT_AUTHOR_NAME='$author_name' 302 * GIT_AUTHOR_EMAIL='$author_email' 303 * GIT_AUTHOR_DATE='$author_date' 304 * 305 * where $author_name, $author_email and $author_date are quoted. We are strict 306 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 307 * script, and thus if the file differs from what this function expects, it is 308 * better to bail out than to do something that the user does not expect. 309 */ 310static intread_author_script(struct am_state *state) 311{ 312const char*filename =am_path(state,"author-script"); 313FILE*fp; 314 315assert(!state->author_name); 316assert(!state->author_email); 317assert(!state->author_date); 318 319 fp =fopen(filename,"r"); 320if(!fp) { 321if(errno == ENOENT) 322return0; 323die_errno(_("could not open '%s' for reading"), filename); 324} 325 326 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 327if(!state->author_name) { 328fclose(fp); 329return-1; 330} 331 332 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 333if(!state->author_email) { 334fclose(fp); 335return-1; 336} 337 338 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 339if(!state->author_date) { 340fclose(fp); 341return-1; 342} 343 344if(fgetc(fp) != EOF) { 345fclose(fp); 346return-1; 347} 348 349fclose(fp); 350return0; 351} 352 353/** 354 * Saves state->author_name, state->author_email and state->author_date in the 355 * state directory's "author-script" file. 356 */ 357static voidwrite_author_script(const struct am_state *state) 358{ 359struct strbuf sb = STRBUF_INIT; 360 361strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 362sq_quote_buf(&sb, state->author_name); 363strbuf_addch(&sb,'\n'); 364 365strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 366sq_quote_buf(&sb, state->author_email); 367strbuf_addch(&sb,'\n'); 368 369strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 370sq_quote_buf(&sb, state->author_date); 371strbuf_addch(&sb,'\n'); 372 373write_state_text(state,"author-script", sb.buf); 374 375strbuf_release(&sb); 376} 377 378/** 379 * Reads the commit message from the state directory's "final-commit" file, 380 * setting state->msg to its contents and state->msg_len to the length of its 381 * contents in bytes. 382 * 383 * Returns 0 on success, -1 if the file does not exist. 384 */ 385static intread_commit_msg(struct am_state *state) 386{ 387struct strbuf sb = STRBUF_INIT; 388 389assert(!state->msg); 390 391if(read_state_file(&sb, state,"final-commit",0) <0) { 392strbuf_release(&sb); 393return-1; 394} 395 396 state->msg =strbuf_detach(&sb, &state->msg_len); 397return0; 398} 399 400/** 401 * Saves state->msg in the state directory's "final-commit" file. 402 */ 403static voidwrite_commit_msg(const struct am_state *state) 404{ 405int fd; 406const char*filename =am_path(state,"final-commit"); 407 408 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 409if(write_in_full(fd, state->msg, state->msg_len) <0) 410die_errno(_("could not write to%s"), filename); 411close(fd); 412} 413 414/** 415 * Loads state from disk. 416 */ 417static voidam_load(struct am_state *state) 418{ 419struct strbuf sb = STRBUF_INIT; 420 421if(read_state_file(&sb, state,"next",1) <0) 422die("BUG: state file 'next' does not exist"); 423 state->cur =strtol(sb.buf, NULL,10); 424 425if(read_state_file(&sb, state,"last",1) <0) 426die("BUG: state file 'last' does not exist"); 427 state->last =strtol(sb.buf, NULL,10); 428 429if(read_author_script(state) <0) 430die(_("could not parse author script")); 431 432read_commit_msg(state); 433 434if(read_state_file(&sb, state,"original-commit",1) <0) 435hashclr(state->orig_commit); 436else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 437die(_("could not parse%s"),am_path(state,"original-commit")); 438 439read_state_file(&sb, state,"threeway",1); 440 state->threeway = !strcmp(sb.buf,"t"); 441 442read_state_file(&sb, state,"quiet",1); 443 state->quiet = !strcmp(sb.buf,"t"); 444 445read_state_file(&sb, state,"sign",1); 446 state->signoff = !strcmp(sb.buf,"t"); 447 448read_state_file(&sb, state,"utf8",1); 449 state->utf8 = !strcmp(sb.buf,"t"); 450 451read_state_file(&sb, state,"keep",1); 452if(!strcmp(sb.buf,"t")) 453 state->keep = KEEP_TRUE; 454else if(!strcmp(sb.buf,"b")) 455 state->keep = KEEP_NON_PATCH; 456else 457 state->keep = KEEP_FALSE; 458 459read_state_file(&sb, state,"messageid",1); 460 state->message_id = !strcmp(sb.buf,"t"); 461 462read_state_file(&sb, state,"scissors",1); 463if(!strcmp(sb.buf,"t")) 464 state->scissors = SCISSORS_TRUE; 465else if(!strcmp(sb.buf,"f")) 466 state->scissors = SCISSORS_FALSE; 467else 468 state->scissors = SCISSORS_UNSET; 469 470read_state_file(&sb, state,"apply-opt",1); 471argv_array_clear(&state->git_apply_opts); 472if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 473die(_("could not parse%s"),am_path(state,"apply-opt")); 474 475 state->rebasing = !!file_exists(am_path(state,"rebasing")); 476 477strbuf_release(&sb); 478} 479 480/** 481 * Removes the am_state directory, forcefully terminating the current am 482 * session. 483 */ 484static voidam_destroy(const struct am_state *state) 485{ 486struct strbuf sb = STRBUF_INIT; 487 488strbuf_addstr(&sb, state->dir); 489remove_dir_recursively(&sb,0); 490strbuf_release(&sb); 491} 492 493/** 494 * Runs applypatch-msg hook. Returns its exit code. 495 */ 496static intrun_applypatch_msg_hook(struct am_state *state) 497{ 498int ret; 499 500assert(state->msg); 501 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 502 503if(!ret) { 504free(state->msg); 505 state->msg = NULL; 506if(read_commit_msg(state) <0) 507die(_("'%s' was deleted by the applypatch-msg hook"), 508am_path(state,"final-commit")); 509} 510 511return ret; 512} 513 514/** 515 * Runs post-rewrite hook. Returns it exit code. 516 */ 517static intrun_post_rewrite_hook(const struct am_state *state) 518{ 519struct child_process cp = CHILD_PROCESS_INIT; 520const char*hook =find_hook("post-rewrite"); 521int ret; 522 523if(!hook) 524return0; 525 526argv_array_push(&cp.args, hook); 527argv_array_push(&cp.args,"rebase"); 528 529 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 530 cp.stdout_to_stderr =1; 531 532 ret =run_command(&cp); 533 534close(cp.in); 535return ret; 536} 537 538/** 539 * Reads the state directory's "rewritten" file, and copies notes from the old 540 * commits listed in the file to their rewritten commits. 541 * 542 * Returns 0 on success, -1 on failure. 543 */ 544static intcopy_notes_for_rebase(const struct am_state *state) 545{ 546struct notes_rewrite_cfg *c; 547struct strbuf sb = STRBUF_INIT; 548const char*invalid_line =_("Malformed input line: '%s'."); 549const char*msg ="Notes added by 'git rebase'"; 550FILE*fp; 551int ret =0; 552 553assert(state->rebasing); 554 555 c =init_copy_notes_for_rewrite("rebase"); 556if(!c) 557return0; 558 559 fp =xfopen(am_path(state,"rewritten"),"r"); 560 561while(!strbuf_getline_lf(&sb, fp)) { 562unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 563 564if(sb.len != GIT_SHA1_HEXSZ *2+1) { 565 ret =error(invalid_line, sb.buf); 566goto finish; 567} 568 569if(get_sha1_hex(sb.buf, from_obj)) { 570 ret =error(invalid_line, sb.buf); 571goto finish; 572} 573 574if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 575 ret =error(invalid_line, sb.buf); 576goto finish; 577} 578 579if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 580 ret =error(invalid_line, sb.buf); 581goto finish; 582} 583 584if(copy_note_for_rewrite(c, from_obj, to_obj)) 585 ret =error(_("Failed to copy notes from '%s' to '%s'"), 586sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 587} 588 589finish: 590finish_copy_notes_for_rewrite(c, msg); 591fclose(fp); 592strbuf_release(&sb); 593return ret; 594} 595 596/** 597 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 598 * non-indented lines and checking if they look like they begin with valid 599 * header field names. 600 * 601 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 602 */ 603static intis_mail(FILE*fp) 604{ 605const char*header_regex ="^[!-9;-~]+:"; 606struct strbuf sb = STRBUF_INIT; 607 regex_t regex; 608int ret =1; 609 610if(fseek(fp,0L, SEEK_SET)) 611die_errno(_("fseek failed")); 612 613if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 614die("invalid pattern:%s", header_regex); 615 616while(!strbuf_getline(&sb, fp)) { 617if(!sb.len) 618break;/* End of header */ 619 620/* Ignore indented folded lines */ 621if(*sb.buf =='\t'|| *sb.buf ==' ') 622continue; 623 624/* It's a header if it matches header_regex */ 625if(regexec(®ex, sb.buf,0, NULL,0)) { 626 ret =0; 627goto done; 628} 629} 630 631done: 632regfree(®ex); 633strbuf_release(&sb); 634return ret; 635} 636 637/** 638 * Attempts to detect the patch_format of the patches contained in `paths`, 639 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 640 * detection fails. 641 */ 642static intdetect_patch_format(const char**paths) 643{ 644enum patch_format ret = PATCH_FORMAT_UNKNOWN; 645struct strbuf l1 = STRBUF_INIT; 646struct strbuf l2 = STRBUF_INIT; 647struct strbuf l3 = STRBUF_INIT; 648FILE*fp; 649 650/* 651 * We default to mbox format if input is from stdin and for directories 652 */ 653if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 654return PATCH_FORMAT_MBOX; 655 656/* 657 * Otherwise, check the first few lines of the first patch, starting 658 * from the first non-blank line, to try to detect its format. 659 */ 660 661 fp =xfopen(*paths,"r"); 662 663while(!strbuf_getline(&l1, fp)) { 664if(l1.len) 665break; 666} 667 668if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 669 ret = PATCH_FORMAT_MBOX; 670goto done; 671} 672 673if(starts_with(l1.buf,"# This series applies on GIT commit")) { 674 ret = PATCH_FORMAT_STGIT_SERIES; 675goto done; 676} 677 678if(!strcmp(l1.buf,"# HG changeset patch")) { 679 ret = PATCH_FORMAT_HG; 680goto done; 681} 682 683strbuf_reset(&l2); 684strbuf_getline(&l2, fp); 685strbuf_reset(&l3); 686strbuf_getline(&l3, fp); 687 688/* 689 * If the second line is empty and the third is a From, Author or Date 690 * entry, this is likely an StGit patch. 691 */ 692if(l1.len && !l2.len && 693(starts_with(l3.buf,"From:") || 694starts_with(l3.buf,"Author:") || 695starts_with(l3.buf,"Date:"))) { 696 ret = PATCH_FORMAT_STGIT; 697goto done; 698} 699 700if(l1.len &&is_mail(fp)) { 701 ret = PATCH_FORMAT_MBOX; 702goto done; 703} 704 705done: 706fclose(fp); 707strbuf_release(&l1); 708return ret; 709} 710 711/** 712 * Splits out individual email patches from `paths`, where each path is either 713 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 714 */ 715static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 716{ 717struct child_process cp = CHILD_PROCESS_INIT; 718struct strbuf last = STRBUF_INIT; 719 720 cp.git_cmd =1; 721argv_array_push(&cp.args,"mailsplit"); 722argv_array_pushf(&cp.args,"-d%d", state->prec); 723argv_array_pushf(&cp.args,"-o%s", state->dir); 724argv_array_push(&cp.args,"-b"); 725if(keep_cr) 726argv_array_push(&cp.args,"--keep-cr"); 727argv_array_push(&cp.args,"--"); 728argv_array_pushv(&cp.args, paths); 729 730if(capture_command(&cp, &last,8)) 731return-1; 732 733 state->cur =1; 734 state->last =strtol(last.buf, NULL,10); 735 736return0; 737} 738 739/** 740 * Callback signature for split_mail_conv(). The foreign patch should be 741 * read from `in`, and the converted patch (in RFC2822 mail format) should be 742 * written to `out`. Return 0 on success, or -1 on failure. 743 */ 744typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 745 746/** 747 * Calls `fn` for each file in `paths` to convert the foreign patch to the 748 * RFC2822 mail format suitable for parsing with git-mailinfo. 749 * 750 * Returns 0 on success, -1 on failure. 751 */ 752static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 753const char**paths,int keep_cr) 754{ 755static const char*stdin_only[] = {"-", NULL}; 756int i; 757 758if(!*paths) 759 paths = stdin_only; 760 761for(i =0; *paths; paths++, i++) { 762FILE*in, *out; 763const char*mail; 764int ret; 765 766if(!strcmp(*paths,"-")) 767 in = stdin; 768else 769 in =fopen(*paths,"r"); 770 771if(!in) 772returnerror_errno(_("could not open '%s' for reading"), 773*paths); 774 775 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 776 777 out =fopen(mail,"w"); 778if(!out) 779returnerror_errno(_("could not open '%s' for writing"), 780 mail); 781 782 ret =fn(out, in, keep_cr); 783 784fclose(out); 785fclose(in); 786 787if(ret) 788returnerror(_("could not parse patch '%s'"), *paths); 789} 790 791 state->cur =1; 792 state->last = i; 793return0; 794} 795 796/** 797 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 798 * message suitable for parsing with git-mailinfo. 799 */ 800static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 801{ 802struct strbuf sb = STRBUF_INIT; 803int subject_printed =0; 804 805while(!strbuf_getline_lf(&sb, in)) { 806const char*str; 807 808if(str_isspace(sb.buf)) 809continue; 810else if(skip_prefix(sb.buf,"Author:", &str)) 811fprintf(out,"From:%s\n", str); 812else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 813fprintf(out,"%s\n", sb.buf); 814else if(!subject_printed) { 815fprintf(out,"Subject:%s\n", sb.buf); 816 subject_printed =1; 817}else{ 818fprintf(out,"\n%s\n", sb.buf); 819break; 820} 821} 822 823strbuf_reset(&sb); 824while(strbuf_fread(&sb,8192, in) >0) { 825fwrite(sb.buf,1, sb.len, out); 826strbuf_reset(&sb); 827} 828 829strbuf_release(&sb); 830return0; 831} 832 833/** 834 * This function only supports a single StGit series file in `paths`. 835 * 836 * Given an StGit series file, converts the StGit patches in the series into 837 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 838 * the state directory. 839 * 840 * Returns 0 on success, -1 on failure. 841 */ 842static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 843int keep_cr) 844{ 845const char*series_dir; 846char*series_dir_buf; 847FILE*fp; 848struct argv_array patches = ARGV_ARRAY_INIT; 849struct strbuf sb = STRBUF_INIT; 850int ret; 851 852if(!paths[0] || paths[1]) 853returnerror(_("Only one StGIT patch series can be applied at once")); 854 855 series_dir_buf =xstrdup(*paths); 856 series_dir =dirname(series_dir_buf); 857 858 fp =fopen(*paths,"r"); 859if(!fp) 860returnerror_errno(_("could not open '%s' for reading"), *paths); 861 862while(!strbuf_getline_lf(&sb, fp)) { 863if(*sb.buf =='#') 864continue;/* skip comment lines */ 865 866argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 867} 868 869fclose(fp); 870strbuf_release(&sb); 871free(series_dir_buf); 872 873 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 874 875argv_array_clear(&patches); 876return ret; 877} 878 879/** 880 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 881 * message suitable for parsing with git-mailinfo. 882 */ 883static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 884{ 885struct strbuf sb = STRBUF_INIT; 886 887while(!strbuf_getline_lf(&sb, in)) { 888const char*str; 889 890if(skip_prefix(sb.buf,"# User ", &str)) 891fprintf(out,"From:%s\n", str); 892else if(skip_prefix(sb.buf,"# Date ", &str)) { 893unsigned long timestamp; 894long tz, tz2; 895char*end; 896 897 errno =0; 898 timestamp =strtoul(str, &end,10); 899if(errno) 900returnerror(_("invalid timestamp")); 901 902if(!skip_prefix(end," ", &str)) 903returnerror(_("invalid Date line")); 904 905 errno =0; 906 tz =strtol(str, &end,10); 907if(errno) 908returnerror(_("invalid timezone offset")); 909 910if(*end) 911returnerror(_("invalid Date line")); 912 913/* 914 * mercurial's timezone is in seconds west of UTC, 915 * however git's timezone is in hours + minutes east of 916 * UTC. Convert it. 917 */ 918 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 919if(tz >0) 920 tz2 = -tz2; 921 922fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 923}else if(starts_with(sb.buf,"# ")) { 924continue; 925}else{ 926fprintf(out,"\n%s\n", sb.buf); 927break; 928} 929} 930 931strbuf_reset(&sb); 932while(strbuf_fread(&sb,8192, in) >0) { 933fwrite(sb.buf,1, sb.len, out); 934strbuf_reset(&sb); 935} 936 937strbuf_release(&sb); 938return0; 939} 940 941/** 942 * Splits a list of files/directories into individual email patches. Each path 943 * in `paths` must be a file/directory that is formatted according to 944 * `patch_format`. 945 * 946 * Once split out, the individual email patches will be stored in the state 947 * directory, with each patch's filename being its index, padded to state->prec 948 * digits. 949 * 950 * state->cur will be set to the index of the first mail, and state->last will 951 * be set to the index of the last mail. 952 * 953 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 954 * to disable this behavior, -1 to use the default configured setting. 955 * 956 * Returns 0 on success, -1 on failure. 957 */ 958static intsplit_mail(struct am_state *state,enum patch_format patch_format, 959const char**paths,int keep_cr) 960{ 961if(keep_cr <0) { 962 keep_cr =0; 963git_config_get_bool("am.keepcr", &keep_cr); 964} 965 966switch(patch_format) { 967case PATCH_FORMAT_MBOX: 968returnsplit_mail_mbox(state, paths, keep_cr); 969case PATCH_FORMAT_STGIT: 970returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 971case PATCH_FORMAT_STGIT_SERIES: 972returnsplit_mail_stgit_series(state, paths, keep_cr); 973case PATCH_FORMAT_HG: 974returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 975default: 976die("BUG: invalid patch_format"); 977} 978return-1; 979} 980 981/** 982 * Setup a new am session for applying patches 983 */ 984static voidam_setup(struct am_state *state,enum patch_format patch_format, 985const char**paths,int keep_cr) 986{ 987unsigned char curr_head[GIT_SHA1_RAWSZ]; 988const char*str; 989struct strbuf sb = STRBUF_INIT; 990 991if(!patch_format) 992 patch_format =detect_patch_format(paths); 993 994if(!patch_format) { 995fprintf_ln(stderr,_("Patch format detection failed.")); 996exit(128); 997} 998 999if(mkdir(state->dir,0777) <0&& errno != EEXIST)1000die_errno(_("failed to create directory '%s'"), state->dir);10011002if(split_mail(state, patch_format, paths, keep_cr) <0) {1003am_destroy(state);1004die(_("Failed to split patches."));1005}10061007if(state->rebasing)1008 state->threeway =1;10091010write_state_bool(state,"threeway", state->threeway);1011write_state_bool(state,"quiet", state->quiet);1012write_state_bool(state,"sign", state->signoff);1013write_state_bool(state,"utf8", state->utf8);10141015switch(state->keep) {1016case KEEP_FALSE:1017 str ="f";1018break;1019case KEEP_TRUE:1020 str ="t";1021break;1022case KEEP_NON_PATCH:1023 str ="b";1024break;1025default:1026die("BUG: invalid value for state->keep");1027}10281029write_state_text(state,"keep", str);1030write_state_bool(state,"messageid", state->message_id);10311032switch(state->scissors) {1033case SCISSORS_UNSET:1034 str ="";1035break;1036case SCISSORS_FALSE:1037 str ="f";1038break;1039case SCISSORS_TRUE:1040 str ="t";1041break;1042default:1043die("BUG: invalid value for state->scissors");1044}1045write_state_text(state,"scissors", str);10461047sq_quote_argv(&sb, state->git_apply_opts.argv,0);1048write_state_text(state,"apply-opt", sb.buf);10491050if(state->rebasing)1051write_state_text(state,"rebasing","");1052else1053write_state_text(state,"applying","");10541055if(!get_sha1("HEAD", curr_head)) {1056write_state_text(state,"abort-safety",sha1_to_hex(curr_head));1057if(!state->rebasing)1058update_ref("am","ORIG_HEAD", curr_head, NULL,0,1059 UPDATE_REFS_DIE_ON_ERR);1060}else{1061write_state_text(state,"abort-safety","");1062if(!state->rebasing)1063delete_ref("ORIG_HEAD", NULL,0);1064}10651066/*1067 * NOTE: Since the "next" and "last" files determine if an am_state1068 * session is in progress, they should be written last.1069 */10701071write_state_count(state,"next", state->cur);1072write_state_count(state,"last", state->last);10731074strbuf_release(&sb);1075}10761077/**1078 * Increments the patch pointer, and cleans am_state for the application of the1079 * next patch.1080 */1081static voidam_next(struct am_state *state)1082{1083unsigned char head[GIT_SHA1_RAWSZ];10841085free(state->author_name);1086 state->author_name = NULL;10871088free(state->author_email);1089 state->author_email = NULL;10901091free(state->author_date);1092 state->author_date = NULL;10931094free(state->msg);1095 state->msg = NULL;1096 state->msg_len =0;10971098unlink(am_path(state,"author-script"));1099unlink(am_path(state,"final-commit"));11001101hashclr(state->orig_commit);1102unlink(am_path(state,"original-commit"));11031104if(!get_sha1("HEAD", head))1105write_state_text(state,"abort-safety",sha1_to_hex(head));1106else1107write_state_text(state,"abort-safety","");11081109 state->cur++;1110write_state_count(state,"next", state->cur);1111}11121113/**1114 * Returns the filename of the current patch email.1115 */1116static const char*msgnum(const struct am_state *state)1117{1118static struct strbuf sb = STRBUF_INIT;11191120strbuf_reset(&sb);1121strbuf_addf(&sb,"%0*d", state->prec, state->cur);11221123return sb.buf;1124}11251126/**1127 * Refresh and write index.1128 */1129static voidrefresh_and_write_cache(void)1130{1131struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11321133hold_locked_index(lock_file,1);1134refresh_cache(REFRESH_QUIET);1135if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1136die(_("unable to write index file"));1137}11381139/**1140 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1141 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1142 * strbuf is provided, the space-separated list of files that differ will be1143 * appended to it.1144 */1145static intindex_has_changes(struct strbuf *sb)1146{1147unsigned char head[GIT_SHA1_RAWSZ];1148int i;11491150if(!get_sha1_tree("HEAD", head)) {1151struct diff_options opt;11521153diff_setup(&opt);1154DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1155if(!sb)1156DIFF_OPT_SET(&opt, QUICK);1157do_diff_cache(head, &opt);1158diffcore_std(&opt);1159for(i =0; sb && i < diff_queued_diff.nr; i++) {1160if(i)1161strbuf_addch(sb,' ');1162strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1163}1164diff_flush(&opt);1165returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1166}else{1167for(i =0; sb && i < active_nr; i++) {1168if(i)1169strbuf_addch(sb,' ');1170strbuf_addstr(sb, active_cache[i]->name);1171}1172return!!active_nr;1173}1174}11751176/**1177 * Dies with a user-friendly message on how to proceed after resolving the1178 * problem. This message can be overridden with state->resolvemsg.1179 */1180static void NORETURN die_user_resolve(const struct am_state *state)1181{1182if(state->resolvemsg) {1183printf_ln("%s", state->resolvemsg);1184}else{1185const char*cmdline = state->interactive ?"git am -i":"git am";11861187printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1188printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1189printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1190}11911192exit(128);1193}11941195static voidam_signoff(struct strbuf *sb)1196{1197char*cp;1198struct strbuf mine = STRBUF_INIT;11991200/* Does it end with our own sign-off? */1201strbuf_addf(&mine,"\n%s%s\n",1202 sign_off_header,1203fmt_name(getenv("GIT_COMMITTER_NAME"),1204getenv("GIT_COMMITTER_EMAIL")));1205if(mine.len < sb->len &&1206!strcmp(mine.buf, sb->buf + sb->len - mine.len))1207goto exit;/* no need to duplicate */12081209/* Does it have any Signed-off-by: in the text */1210for(cp = sb->buf;1211 cp && *cp && (cp =strstr(cp, sign_off_header)) != NULL;1212 cp =strchr(cp,'\n')) {1213if(sb->buf == cp || cp[-1] =='\n')1214break;1215}12161217strbuf_addstr(sb, mine.buf + !!cp);1218exit:1219strbuf_release(&mine);1220}12211222/**1223 * Appends signoff to the "msg" field of the am_state.1224 */1225static voidam_append_signoff(struct am_state *state)1226{1227struct strbuf sb = STRBUF_INIT;12281229strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1230am_signoff(&sb);1231 state->msg =strbuf_detach(&sb, &state->msg_len);1232}12331234/**1235 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1236 * state->msg will be set to the patch message. state->author_name,1237 * state->author_email and state->author_date will be set to the patch author's1238 * name, email and date respectively. The patch body will be written to the1239 * state directory's "patch" file.1240 *1241 * Returns 1 if the patch should be skipped, 0 otherwise.1242 */1243static intparse_mail(struct am_state *state,const char*mail)1244{1245FILE*fp;1246struct strbuf sb = STRBUF_INIT;1247struct strbuf msg = STRBUF_INIT;1248struct strbuf author_name = STRBUF_INIT;1249struct strbuf author_date = STRBUF_INIT;1250struct strbuf author_email = STRBUF_INIT;1251int ret =0;1252struct mailinfo mi;12531254setup_mailinfo(&mi);12551256if(state->utf8)1257 mi.metainfo_charset =get_commit_output_encoding();1258else1259 mi.metainfo_charset = NULL;12601261switch(state->keep) {1262case KEEP_FALSE:1263break;1264case KEEP_TRUE:1265 mi.keep_subject =1;1266break;1267case KEEP_NON_PATCH:1268 mi.keep_non_patch_brackets_in_subject =1;1269break;1270default:1271die("BUG: invalid value for state->keep");1272}12731274if(state->message_id)1275 mi.add_message_id =1;12761277switch(state->scissors) {1278case SCISSORS_UNSET:1279break;1280case SCISSORS_FALSE:1281 mi.use_scissors =0;1282break;1283case SCISSORS_TRUE:1284 mi.use_scissors =1;1285break;1286default:1287die("BUG: invalid value for state->scissors");1288}12891290 mi.input =fopen(mail,"r");1291if(!mi.input)1292die("could not open input");1293 mi.output =fopen(am_path(state,"info"),"w");1294if(!mi.output)1295die("could not open output 'info'");1296if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1297die("could not parse patch");12981299fclose(mi.input);1300fclose(mi.output);13011302/* Extract message and author information */1303 fp =xfopen(am_path(state,"info"),"r");1304while(!strbuf_getline_lf(&sb, fp)) {1305const char*x;13061307if(skip_prefix(sb.buf,"Subject: ", &x)) {1308if(msg.len)1309strbuf_addch(&msg,'\n');1310strbuf_addstr(&msg, x);1311}else if(skip_prefix(sb.buf,"Author: ", &x))1312strbuf_addstr(&author_name, x);1313else if(skip_prefix(sb.buf,"Email: ", &x))1314strbuf_addstr(&author_email, x);1315else if(skip_prefix(sb.buf,"Date: ", &x))1316strbuf_addstr(&author_date, x);1317}1318fclose(fp);13191320/* Skip pine's internal folder data */1321if(!strcmp(author_name.buf,"Mail System Internal Data")) {1322 ret =1;1323goto finish;1324}13251326if(is_empty_file(am_path(state,"patch"))) {1327printf_ln(_("Patch is empty. Was it split wrong?"));1328die_user_resolve(state);1329}13301331strbuf_addstr(&msg,"\n\n");1332strbuf_addbuf(&msg, &mi.log_message);1333strbuf_stripspace(&msg,0);13341335if(state->signoff)1336am_signoff(&msg);13371338assert(!state->author_name);1339 state->author_name =strbuf_detach(&author_name, NULL);13401341assert(!state->author_email);1342 state->author_email =strbuf_detach(&author_email, NULL);13431344assert(!state->author_date);1345 state->author_date =strbuf_detach(&author_date, NULL);13461347assert(!state->msg);1348 state->msg =strbuf_detach(&msg, &state->msg_len);13491350finish:1351strbuf_release(&msg);1352strbuf_release(&author_date);1353strbuf_release(&author_email);1354strbuf_release(&author_name);1355strbuf_release(&sb);1356clear_mailinfo(&mi);1357return ret;1358}13591360/**1361 * Sets commit_id to the commit hash where the mail was generated from.1362 * Returns 0 on success, -1 on failure.1363 */1364static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1365{1366struct strbuf sb = STRBUF_INIT;1367FILE*fp =xfopen(mail,"r");1368const char*x;13691370if(strbuf_getline_lf(&sb, fp))1371return-1;13721373if(!skip_prefix(sb.buf,"From ", &x))1374return-1;13751376if(get_sha1_hex(x, commit_id) <0)1377return-1;13781379strbuf_release(&sb);1380fclose(fp);1381return0;1382}13831384/**1385 * Sets state->msg, state->author_name, state->author_email, state->author_date1386 * to the commit's respective info.1387 */1388static voidget_commit_info(struct am_state *state,struct commit *commit)1389{1390const char*buffer, *ident_line, *author_date, *msg;1391size_t ident_len;1392struct ident_split ident_split;1393struct strbuf sb = STRBUF_INIT;13941395 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13961397 ident_line =find_commit_header(buffer,"author", &ident_len);13981399if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1400strbuf_add(&sb, ident_line, ident_len);1401die(_("invalid ident line:%s"), sb.buf);1402}14031404assert(!state->author_name);1405if(ident_split.name_begin) {1406strbuf_add(&sb, ident_split.name_begin,1407 ident_split.name_end - ident_split.name_begin);1408 state->author_name =strbuf_detach(&sb, NULL);1409}else1410 state->author_name =xstrdup("");14111412assert(!state->author_email);1413if(ident_split.mail_begin) {1414strbuf_add(&sb, ident_split.mail_begin,1415 ident_split.mail_end - ident_split.mail_begin);1416 state->author_email =strbuf_detach(&sb, NULL);1417}else1418 state->author_email =xstrdup("");14191420 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1421strbuf_addstr(&sb, author_date);1422assert(!state->author_date);1423 state->author_date =strbuf_detach(&sb, NULL);14241425assert(!state->msg);1426 msg =strstr(buffer,"\n\n");1427if(!msg)1428die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1429 state->msg =xstrdup(msg +2);1430 state->msg_len =strlen(state->msg);1431}14321433/**1434 * Writes `commit` as a patch to the state directory's "patch" file.1435 */1436static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1437{1438struct rev_info rev_info;1439FILE*fp;14401441 fp =xfopen(am_path(state,"patch"),"w");1442init_revisions(&rev_info, NULL);1443 rev_info.diff =1;1444 rev_info.abbrev =0;1445 rev_info.disable_stdin =1;1446 rev_info.show_root_diff =1;1447 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1448 rev_info.no_commit_id =1;1449DIFF_OPT_SET(&rev_info.diffopt, BINARY);1450DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1451 rev_info.diffopt.use_color =0;1452 rev_info.diffopt.file = fp;1453 rev_info.diffopt.close_file =1;1454add_pending_object(&rev_info, &commit->object,"");1455diff_setup_done(&rev_info.diffopt);1456log_tree_commit(&rev_info, commit);1457}14581459/**1460 * Writes the diff of the index against HEAD as a patch to the state1461 * directory's "patch" file.1462 */1463static voidwrite_index_patch(const struct am_state *state)1464{1465struct tree *tree;1466unsigned char head[GIT_SHA1_RAWSZ];1467struct rev_info rev_info;1468FILE*fp;14691470if(!get_sha1_tree("HEAD", head))1471 tree =lookup_tree(head);1472else1473 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14741475 fp =xfopen(am_path(state,"patch"),"w");1476init_revisions(&rev_info, NULL);1477 rev_info.diff =1;1478 rev_info.disable_stdin =1;1479 rev_info.no_commit_id =1;1480 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1481 rev_info.diffopt.use_color =0;1482 rev_info.diffopt.file = fp;1483 rev_info.diffopt.close_file =1;1484add_pending_object(&rev_info, &tree->object,"");1485diff_setup_done(&rev_info.diffopt);1486run_diff_index(&rev_info,1);1487}14881489/**1490 * Like parse_mail(), but parses the mail by looking up its commit ID1491 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1492 * of patches.1493 *1494 * state->orig_commit will be set to the original commit ID.1495 *1496 * Will always return 0 as the patch should never be skipped.1497 */1498static intparse_mail_rebase(struct am_state *state,const char*mail)1499{1500struct commit *commit;1501unsigned char commit_sha1[GIT_SHA1_RAWSZ];15021503if(get_mail_commit_sha1(commit_sha1, mail) <0)1504die(_("could not parse%s"), mail);15051506 commit =lookup_commit_or_die(commit_sha1, mail);15071508get_commit_info(state, commit);15091510write_commit_patch(state, commit);15111512hashcpy(state->orig_commit, commit_sha1);1513write_state_text(state,"original-commit",sha1_to_hex(commit_sha1));15141515return0;1516}15171518/**1519 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1520 * `index_file` is not NULL, the patch will be applied to that index.1521 */1522static intrun_apply(const struct am_state *state,const char*index_file)1523{1524struct child_process cp = CHILD_PROCESS_INIT;15251526 cp.git_cmd =1;15271528if(index_file)1529argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);15301531/*1532 * If we are allowed to fall back on 3-way merge, don't give false1533 * errors during the initial attempt.1534 */1535if(state->threeway && !index_file) {1536 cp.no_stdout =1;1537 cp.no_stderr =1;1538}15391540argv_array_push(&cp.args,"apply");15411542argv_array_pushv(&cp.args, state->git_apply_opts.argv);15431544if(index_file)1545argv_array_push(&cp.args,"--cached");1546else1547argv_array_push(&cp.args,"--index");15481549argv_array_push(&cp.args,am_path(state,"patch"));15501551if(run_command(&cp))1552return-1;15531554/* Reload index as git-apply will have modified it. */1555discard_cache();1556read_cache_from(index_file ? index_file :get_index_file());15571558return0;1559}15601561/**1562 * Builds an index that contains just the blobs needed for a 3way merge.1563 */1564static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1565{1566struct child_process cp = CHILD_PROCESS_INIT;15671568 cp.git_cmd =1;1569argv_array_push(&cp.args,"apply");1570argv_array_pushv(&cp.args, state->git_apply_opts.argv);1571argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1572argv_array_push(&cp.args,am_path(state,"patch"));15731574if(run_command(&cp))1575return-1;15761577return0;1578}15791580/**1581 * Do the three-way merge using fake ancestor, their tree constructed1582 * from the fake ancestor and the postimage of the patch, and our1583 * state.1584 */1585static intrun_fallback_merge_recursive(const struct am_state *state,1586unsigned char*orig_tree,1587unsigned char*our_tree,1588unsigned char*their_tree)1589{1590struct child_process cp = CHILD_PROCESS_INIT;1591int status;15921593 cp.git_cmd =1;15941595argv_array_pushf(&cp.env_array,"GITHEAD_%s=%.*s",1596sha1_to_hex(their_tree),linelen(state->msg), state->msg);1597if(state->quiet)1598argv_array_push(&cp.env_array,"GIT_MERGE_VERBOSITY=0");15991600argv_array_push(&cp.args,"merge-recursive");1601argv_array_push(&cp.args,sha1_to_hex(orig_tree));1602argv_array_push(&cp.args,"--");1603argv_array_push(&cp.args,sha1_to_hex(our_tree));1604argv_array_push(&cp.args,sha1_to_hex(their_tree));16051606 status =run_command(&cp) ? (-1) :0;1607discard_cache();1608read_cache();1609return status;1610}16111612/**1613 * Attempt a threeway merge, using index_path as the temporary index.1614 */1615static intfall_back_threeway(const struct am_state *state,const char*index_path)1616{1617unsigned char orig_tree[GIT_SHA1_RAWSZ], their_tree[GIT_SHA1_RAWSZ],1618 our_tree[GIT_SHA1_RAWSZ];16191620if(get_sha1("HEAD", our_tree) <0)1621hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);16221623if(build_fake_ancestor(state, index_path))1624returnerror("could not build fake ancestor");16251626discard_cache();1627read_cache_from(index_path);16281629if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1630returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));16311632say(state, stdout,_("Using index info to reconstruct a base tree..."));16331634if(!state->quiet) {1635/*1636 * List paths that needed 3-way fallback, so that the user can1637 * review them with extra care to spot mismerges.1638 */1639struct rev_info rev_info;1640const char*diff_filter_str ="--diff-filter=AM";16411642init_revisions(&rev_info, NULL);1643 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1644diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1645add_pending_sha1(&rev_info,"HEAD", our_tree,0);1646diff_setup_done(&rev_info.diffopt);1647run_diff_index(&rev_info,1);1648}16491650if(run_apply(state, index_path))1651returnerror(_("Did you hand edit your patch?\n"1652"It does not apply to blobs recorded in its index."));16531654if(write_index_as_tree(their_tree, &the_index, index_path,0, NULL))1655returnerror("could not write tree");16561657say(state, stdout,_("Falling back to patching base and 3-way merge..."));16581659discard_cache();1660read_cache();16611662/*1663 * This is not so wrong. Depending on which base we picked, orig_tree1664 * may be wildly different from ours, but their_tree has the same set of1665 * wildly different changes in parts the patch did not touch, so1666 * recursive ends up canceling them, saying that we reverted all those1667 * changes.1668 */16691670if(run_fallback_merge_recursive(state, orig_tree, our_tree, their_tree)) {1671rerere(state->allow_rerere_autoupdate);1672returnerror(_("Failed to merge in the changes."));1673}16741675return0;1676}16771678/**1679 * Commits the current index with state->msg as the commit message and1680 * state->author_name, state->author_email and state->author_date as the author1681 * information.1682 */1683static voiddo_commit(const struct am_state *state)1684{1685unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1686 commit[GIT_SHA1_RAWSZ];1687unsigned char*ptr;1688struct commit_list *parents = NULL;1689const char*reflog_msg, *author;1690struct strbuf sb = STRBUF_INIT;16911692if(run_hook_le(NULL,"pre-applypatch", NULL))1693exit(1);16941695if(write_cache_as_tree(tree,0, NULL))1696die(_("git write-tree failed to write a tree"));16971698if(!get_sha1_commit("HEAD", parent)) {1699 ptr = parent;1700commit_list_insert(lookup_commit(parent), &parents);1701}else{1702 ptr = NULL;1703say(state, stderr,_("applying to an empty history"));1704}17051706 author =fmt_ident(state->author_name, state->author_email,1707 state->ignore_date ? NULL : state->author_date,1708 IDENT_STRICT);17091710if(state->committer_date_is_author_date)1711setenv("GIT_COMMITTER_DATE",1712 state->ignore_date ?"": state->author_date,1);17131714if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1715 author, state->sign_commit))1716die(_("failed to write commit object"));17171718 reflog_msg =getenv("GIT_REFLOG_ACTION");1719if(!reflog_msg)1720 reflog_msg ="am";17211722strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1723 state->msg);17241725update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);17261727if(state->rebasing) {1728FILE*fp =xfopen(am_path(state,"rewritten"),"a");17291730assert(!is_null_sha1(state->orig_commit));1731fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1732fprintf(fp,"%s\n",sha1_to_hex(commit));1733fclose(fp);1734}17351736run_hook_le(NULL,"post-applypatch", NULL);17371738strbuf_release(&sb);1739}17401741/**1742 * Validates the am_state for resuming -- the "msg" and authorship fields must1743 * be filled up.1744 */1745static voidvalidate_resume_state(const struct am_state *state)1746{1747if(!state->msg)1748die(_("cannot resume:%sdoes not exist."),1749am_path(state,"final-commit"));17501751if(!state->author_name || !state->author_email || !state->author_date)1752die(_("cannot resume:%sdoes not exist."),1753am_path(state,"author-script"));1754}17551756/**1757 * Interactively prompt the user on whether the current patch should be1758 * applied.1759 *1760 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1761 * skip it.1762 */1763static intdo_interactive(struct am_state *state)1764{1765assert(state->msg);17661767if(!isatty(0))1768die(_("cannot be interactive without stdin connected to a terminal."));17691770for(;;) {1771const char*reply;17721773puts(_("Commit Body is:"));1774puts("--------------------------");1775printf("%s", state->msg);1776puts("--------------------------");17771778/*1779 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1780 * in your translation. The program will only accept English1781 * input at this point.1782 */1783 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17841785if(!reply) {1786continue;1787}else if(*reply =='y'|| *reply =='Y') {1788return0;1789}else if(*reply =='a'|| *reply =='A') {1790 state->interactive =0;1791return0;1792}else if(*reply =='n'|| *reply =='N') {1793return1;1794}else if(*reply =='e'|| *reply =='E') {1795struct strbuf msg = STRBUF_INIT;17961797if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1798free(state->msg);1799 state->msg =strbuf_detach(&msg, &state->msg_len);1800}1801strbuf_release(&msg);1802}else if(*reply =='v'|| *reply =='V') {1803const char*pager =git_pager(1);1804struct child_process cp = CHILD_PROCESS_INIT;18051806if(!pager)1807 pager ="cat";1808prepare_pager_args(&cp, pager);1809argv_array_push(&cp.args,am_path(state,"patch"));1810run_command(&cp);1811}1812}1813}18141815/**1816 * Applies all queued mail.1817 *1818 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1819 * well as the state directory's "patch" file is used as-is for applying the1820 * patch and committing it.1821 */1822static voidam_run(struct am_state *state,int resume)1823{1824const char*argv_gc_auto[] = {"gc","--auto", NULL};1825struct strbuf sb = STRBUF_INIT;18261827unlink(am_path(state,"dirtyindex"));18281829refresh_and_write_cache();18301831if(index_has_changes(&sb)) {1832write_state_bool(state,"dirtyindex",1);1833die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1834}18351836strbuf_release(&sb);18371838while(state->cur <= state->last) {1839const char*mail =am_path(state,msgnum(state));1840int apply_status;18411842if(!file_exists(mail))1843goto next;18441845if(resume) {1846validate_resume_state(state);1847}else{1848int skip;18491850if(state->rebasing)1851 skip =parse_mail_rebase(state, mail);1852else1853 skip =parse_mail(state, mail);18541855if(skip)1856goto next;/* mail should be skipped */18571858write_author_script(state);1859write_commit_msg(state);1860}18611862if(state->interactive &&do_interactive(state))1863goto next;18641865if(run_applypatch_msg_hook(state))1866exit(1);18671868say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18691870 apply_status =run_apply(state, NULL);18711872if(apply_status && state->threeway) {1873struct strbuf sb = STRBUF_INIT;18741875strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1876 apply_status =fall_back_threeway(state, sb.buf);1877strbuf_release(&sb);18781879/*1880 * Applying the patch to an earlier tree and merging1881 * the result may have produced the same tree as ours.1882 */1883if(!apply_status && !index_has_changes(NULL)) {1884say(state, stdout,_("No changes -- Patch already applied."));1885goto next;1886}1887}18881889if(apply_status) {1890int advice_amworkdir =1;18911892printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1893linelen(state->msg), state->msg);18941895git_config_get_bool("advice.amworkdir", &advice_amworkdir);18961897if(advice_amworkdir)1898printf_ln(_("The copy of the patch that failed is found in:%s"),1899am_path(state,"patch"));19001901die_user_resolve(state);1902}19031904do_commit(state);19051906next:1907am_next(state);19081909if(resume)1910am_load(state);1911 resume =0;1912}19131914if(!is_empty_file(am_path(state,"rewritten"))) {1915assert(state->rebasing);1916copy_notes_for_rebase(state);1917run_post_rewrite_hook(state);1918}19191920/*1921 * In rebasing mode, it's up to the caller to take care of1922 * housekeeping.1923 */1924if(!state->rebasing) {1925am_destroy(state);1926close_all_packs();1927run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1928}1929}19301931/**1932 * Resume the current am session after patch application failure. The user did1933 * all the hard work, and we do not have to do any patch application. Just1934 * trust and commit what the user has in the index and working tree.1935 */1936static voidam_resolve(struct am_state *state)1937{1938validate_resume_state(state);19391940say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);19411942if(!index_has_changes(NULL)) {1943printf_ln(_("No changes - did you forget to use 'git add'?\n"1944"If there is nothing left to stage, chances are that something else\n"1945"already introduced the same changes; you might want to skip this patch."));1946die_user_resolve(state);1947}19481949if(unmerged_cache()) {1950printf_ln(_("You still have unmerged paths in your index.\n"1951"Did you forget to use 'git add'?"));1952die_user_resolve(state);1953}19541955if(state->interactive) {1956write_index_patch(state);1957if(do_interactive(state))1958goto next;1959}19601961rerere(0);19621963do_commit(state);19641965next:1966am_next(state);1967am_load(state);1968am_run(state,0);1969}19701971/**1972 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1973 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1974 * failure.1975 */1976static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1977{1978struct lock_file *lock_file;1979struct unpack_trees_options opts;1980struct tree_desc t[2];19811982if(parse_tree(head) ||parse_tree(remote))1983return-1;19841985 lock_file =xcalloc(1,sizeof(struct lock_file));1986hold_locked_index(lock_file,1);19871988refresh_cache(REFRESH_QUIET);19891990memset(&opts,0,sizeof(opts));1991 opts.head_idx =1;1992 opts.src_index = &the_index;1993 opts.dst_index = &the_index;1994 opts.update =1;1995 opts.merge =1;1996 opts.reset = reset;1997 opts.fn = twoway_merge;1998init_tree_desc(&t[0], head->buffer, head->size);1999init_tree_desc(&t[1], remote->buffer, remote->size);20002001if(unpack_trees(2, t, &opts)) {2002rollback_lock_file(lock_file);2003return-1;2004}20052006if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2007die(_("unable to write new index file"));20082009return0;2010}20112012/**2013 * Merges a tree into the index. The index's stat info will take precedence2014 * over the merged tree's. Returns 0 on success, -1 on failure.2015 */2016static intmerge_tree(struct tree *tree)2017{2018struct lock_file *lock_file;2019struct unpack_trees_options opts;2020struct tree_desc t[1];20212022if(parse_tree(tree))2023return-1;20242025 lock_file =xcalloc(1,sizeof(struct lock_file));2026hold_locked_index(lock_file,1);20272028memset(&opts,0,sizeof(opts));2029 opts.head_idx =1;2030 opts.src_index = &the_index;2031 opts.dst_index = &the_index;2032 opts.merge =1;2033 opts.fn = oneway_merge;2034init_tree_desc(&t[0], tree->buffer, tree->size);20352036if(unpack_trees(1, t, &opts)) {2037rollback_lock_file(lock_file);2038return-1;2039}20402041if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2042die(_("unable to write new index file"));20432044return0;2045}20462047/**2048 * Clean the index without touching entries that are not modified between2049 * `head` and `remote`.2050 */2051static intclean_index(const unsigned char*head,const unsigned char*remote)2052{2053struct tree *head_tree, *remote_tree, *index_tree;2054unsigned char index[GIT_SHA1_RAWSZ];20552056 head_tree =parse_tree_indirect(head);2057if(!head_tree)2058returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));20592060 remote_tree =parse_tree_indirect(remote);2061if(!remote_tree)2062returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));20632064read_cache_unmerged();20652066if(fast_forward_to(head_tree, head_tree,1))2067return-1;20682069if(write_cache_as_tree(index,0, NULL))2070return-1;20712072 index_tree =parse_tree_indirect(index);2073if(!index_tree)2074returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));20752076if(fast_forward_to(index_tree, remote_tree,0))2077return-1;20782079if(merge_tree(remote_tree))2080return-1;20812082remove_branch_state();20832084return0;2085}20862087/**2088 * Resets rerere's merge resolution metadata.2089 */2090static voidam_rerere_clear(void)2091{2092struct string_list merge_rr = STRING_LIST_INIT_DUP;2093rerere_clear(&merge_rr);2094string_list_clear(&merge_rr,1);2095}20962097/**2098 * Resume the current am session by skipping the current patch.2099 */2100static voidam_skip(struct am_state *state)2101{2102unsigned char head[GIT_SHA1_RAWSZ];21032104am_rerere_clear();21052106if(get_sha1("HEAD", head))2107hashcpy(head, EMPTY_TREE_SHA1_BIN);21082109if(clean_index(head, head))2110die(_("failed to clean index"));21112112am_next(state);2113am_load(state);2114am_run(state,0);2115}21162117/**2118 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2119 *2120 * It is not safe to reset HEAD when:2121 * 1. git-am previously failed because the index was dirty.2122 * 2. HEAD has moved since git-am previously failed.2123 */2124static intsafe_to_abort(const struct am_state *state)2125{2126struct strbuf sb = STRBUF_INIT;2127unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];21282129if(file_exists(am_path(state,"dirtyindex")))2130return0;21312132if(read_state_file(&sb, state,"abort-safety",1) >0) {2133if(get_sha1_hex(sb.buf, abort_safety))2134die(_("could not parse%s"),am_path(state,"abort_safety"));2135}else2136hashclr(abort_safety);21372138if(get_sha1("HEAD", head))2139hashclr(head);21402141if(!hashcmp(head, abort_safety))2142return1;21432144error(_("You seem to have moved HEAD since the last 'am' failure.\n"2145"Not rewinding to ORIG_HEAD"));21462147return0;2148}21492150/**2151 * Aborts the current am session if it is safe to do so.2152 */2153static voidam_abort(struct am_state *state)2154{2155unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2156int has_curr_head, has_orig_head;2157char*curr_branch;21582159if(!safe_to_abort(state)) {2160am_destroy(state);2161return;2162}21632164am_rerere_clear();21652166 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2167 has_curr_head = !is_null_sha1(curr_head);2168if(!has_curr_head)2169hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);21702171 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2172if(!has_orig_head)2173hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);21742175clean_index(curr_head, orig_head);21762177if(has_orig_head)2178update_ref("am --abort","HEAD", orig_head,2179 has_curr_head ? curr_head : NULL,0,2180 UPDATE_REFS_DIE_ON_ERR);2181else if(curr_branch)2182delete_ref(curr_branch, NULL, REF_NODEREF);21832184free(curr_branch);2185am_destroy(state);2186}21872188/**2189 * parse_options() callback that validates and sets opt->value to the2190 * PATCH_FORMAT_* enum value corresponding to `arg`.2191 */2192static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2193{2194int*opt_value = opt->value;21952196if(!strcmp(arg,"mbox"))2197*opt_value = PATCH_FORMAT_MBOX;2198else if(!strcmp(arg,"stgit"))2199*opt_value = PATCH_FORMAT_STGIT;2200else if(!strcmp(arg,"stgit-series"))2201*opt_value = PATCH_FORMAT_STGIT_SERIES;2202else if(!strcmp(arg,"hg"))2203*opt_value = PATCH_FORMAT_HG;2204else2205returnerror(_("Invalid value for --patch-format:%s"), arg);2206return0;2207}22082209enum resume_mode {2210 RESUME_FALSE =0,2211 RESUME_APPLY,2212 RESUME_RESOLVED,2213 RESUME_SKIP,2214 RESUME_ABORT2215};22162217static intgit_am_config(const char*k,const char*v,void*cb)2218{2219int status;22202221 status =git_gpg_config(k, v, NULL);2222if(status)2223return status;22242225returngit_default_config(k, v, NULL);2226}22272228intcmd_am(int argc,const char**argv,const char*prefix)2229{2230struct am_state state;2231int binary = -1;2232int keep_cr = -1;2233int patch_format = PATCH_FORMAT_UNKNOWN;2234enum resume_mode resume = RESUME_FALSE;2235int in_progress;22362237const char*const usage[] = {2238N_("git am [<options>] [(<mbox>|<Maildir>)...]"),2239N_("git am [<options>] (--continue | --skip | --abort)"),2240 NULL2241};22422243struct option options[] = {2244OPT_BOOL('i',"interactive", &state.interactive,2245N_("run interactively")),2246OPT_HIDDEN_BOOL('b',"binary", &binary,2247N_("historical option -- no-op")),2248OPT_BOOL('3',"3way", &state.threeway,2249N_("allow fall back on 3way merging if needed")),2250OPT__QUIET(&state.quiet,N_("be quiet")),2251OPT_SET_INT('s',"signoff", &state.signoff,2252N_("add a Signed-off-by line to the commit message"),2253 SIGNOFF_EXPLICIT),2254OPT_BOOL('u',"utf8", &state.utf8,2255N_("recode into utf8 (default)")),2256OPT_SET_INT('k',"keep", &state.keep,2257N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2258OPT_SET_INT(0,"keep-non-patch", &state.keep,2259N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2260OPT_BOOL('m',"message-id", &state.message_id,2261N_("pass -m flag to git-mailinfo")),2262{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2263N_("pass --keep-cr flag to git-mailsplit for mbox format"),2264 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2265{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2266N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2267 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2268OPT_BOOL('c',"scissors", &state.scissors,2269N_("strip everything before a scissors line")),2270OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2271N_("pass it through git-apply"),22720),2273OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2274N_("pass it through git-apply"),2275 PARSE_OPT_NOARG),2276OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2277N_("pass it through git-apply"),2278 PARSE_OPT_NOARG),2279OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2280N_("pass it through git-apply"),22810),2282OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2283N_("pass it through git-apply"),22840),2285OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2286N_("pass it through git-apply"),22870),2288OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2289N_("pass it through git-apply"),22900),2291OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2292N_("pass it through git-apply"),22930),2294OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2295N_("format the patch(es) are in"),2296 parse_opt_patchformat),2297OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2298N_("pass it through git-apply"),2299 PARSE_OPT_NOARG),2300OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2301N_("override error message when patch failure occurs")),2302OPT_CMDMODE(0,"continue", &resume,2303N_("continue applying patches after resolving a conflict"),2304 RESUME_RESOLVED),2305OPT_CMDMODE('r',"resolved", &resume,2306N_("synonyms for --continue"),2307 RESUME_RESOLVED),2308OPT_CMDMODE(0,"skip", &resume,2309N_("skip the current patch"),2310 RESUME_SKIP),2311OPT_CMDMODE(0,"abort", &resume,2312N_("restore the original branch and abort the patching operation."),2313 RESUME_ABORT),2314OPT_BOOL(0,"committer-date-is-author-date",2315&state.committer_date_is_author_date,2316N_("lie about committer date")),2317OPT_BOOL(0,"ignore-date", &state.ignore_date,2318N_("use current timestamp for author date")),2319OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2320{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2321N_("GPG-sign commits"),2322 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2323OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2324N_("(internal use for git-rebase)")),2325OPT_END()2326};23272328git_config(git_am_config, NULL);23292330am_state_init(&state,git_path("rebase-apply"));23312332 in_progress =am_in_progress(&state);2333if(in_progress)2334am_load(&state);23352336 argc =parse_options(argc, argv, prefix, options, usage,0);23372338if(binary >=0)2339fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2340"it will be removed. Please do not use it anymore."));23412342/* Ensure a valid committer ident can be constructed */2343git_committer_info(IDENT_STRICT);23442345if(read_index_preload(&the_index, NULL) <0)2346die(_("failed to read the index"));23472348if(in_progress) {2349/*2350 * Catch user error to feed us patches when there is a session2351 * in progress:2352 *2353 * 1. mbox path(s) are provided on the command-line.2354 * 2. stdin is not a tty: the user is trying to feed us a patch2355 * from standard input. This is somewhat unreliable -- stdin2356 * could be /dev/null for example and the caller did not2357 * intend to feed us a patch but wanted to continue2358 * unattended.2359 */2360if(argc || (resume == RESUME_FALSE && !isatty(0)))2361die(_("previous rebase directory%sstill exists but mbox given."),2362 state.dir);23632364if(resume == RESUME_FALSE)2365 resume = RESUME_APPLY;23662367if(state.signoff == SIGNOFF_EXPLICIT)2368am_append_signoff(&state);2369}else{2370struct argv_array paths = ARGV_ARRAY_INIT;2371int i;23722373/*2374 * Handle stray state directory in the independent-run case. In2375 * the --rebasing case, it is up to the caller to take care of2376 * stray directories.2377 */2378if(file_exists(state.dir) && !state.rebasing) {2379if(resume == RESUME_ABORT) {2380am_destroy(&state);2381am_state_release(&state);2382return0;2383}23842385die(_("Stray%sdirectory found.\n"2386"Use\"git am --abort\"to remove it."),2387 state.dir);2388}23892390if(resume)2391die(_("Resolve operation not in progress, we are not resuming."));23922393for(i =0; i < argc; i++) {2394if(is_absolute_path(argv[i]) || !prefix)2395argv_array_push(&paths, argv[i]);2396else2397argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2398}23992400am_setup(&state, patch_format, paths.argv, keep_cr);24012402argv_array_clear(&paths);2403}24042405switch(resume) {2406case RESUME_FALSE:2407am_run(&state,0);2408break;2409case RESUME_APPLY:2410am_run(&state,1);2411break;2412case RESUME_RESOLVED:2413am_resolve(&state);2414break;2415case RESUME_SKIP:2416am_skip(&state);2417break;2418case RESUME_ABORT:2419am_abort(&state);2420break;2421default:2422die("BUG: invalid resume value");2423}24242425am_state_release(&state);24262427return0;2428}