1/* 2 * Builtin "git am" 3 * 4 * Based on git-am.sh by Junio C Hamano. 5 */ 6#include"cache.h" 7#include"config.h" 8#include"builtin.h" 9#include"exec-cmd.h" 10#include"parse-options.h" 11#include"dir.h" 12#include"run-command.h" 13#include"quote.h" 14#include"tempfile.h" 15#include"lockfile.h" 16#include"cache-tree.h" 17#include"refs.h" 18#include"commit.h" 19#include"diff.h" 20#include"diffcore.h" 21#include"unpack-trees.h" 22#include"branch.h" 23#include"sequencer.h" 24#include"revision.h" 25#include"merge-recursive.h" 26#include"revision.h" 27#include"log-tree.h" 28#include"notes-utils.h" 29#include"rerere.h" 30#include"prompt.h" 31#include"mailinfo.h" 32#include"apply.h" 33#include"string-list.h" 34#include"packfile.h" 35#include"repository.h" 36 37/** 38 * Returns 1 if the file is empty or does not exist, 0 otherwise. 39 */ 40static intis_empty_file(const char*filename) 41{ 42struct stat st; 43 44if(stat(filename, &st) <0) { 45if(errno == ENOENT) 46return1; 47die_errno(_("could not stat%s"), filename); 48} 49 50return!st.st_size; 51} 52 53/** 54 * Returns the length of the first line of msg. 55 */ 56static intlinelen(const char*msg) 57{ 58returnstrchrnul(msg,'\n') - msg; 59} 60 61/** 62 * Returns true if `str` consists of only whitespace, false otherwise. 63 */ 64static intstr_isspace(const char*str) 65{ 66for(; *str; str++) 67if(!isspace(*str)) 68return0; 69 70return1; 71} 72 73enum patch_format { 74 PATCH_FORMAT_UNKNOWN =0, 75 PATCH_FORMAT_MBOX, 76 PATCH_FORMAT_STGIT, 77 PATCH_FORMAT_STGIT_SERIES, 78 PATCH_FORMAT_HG, 79 PATCH_FORMAT_MBOXRD 80}; 81 82enum keep_type { 83 KEEP_FALSE =0, 84 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 85 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 86}; 87 88enum scissors_type { 89 SCISSORS_UNSET = -1, 90 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 91 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 92}; 93 94enum signoff_type { 95 SIGNOFF_FALSE =0, 96 SIGNOFF_TRUE =1, 97 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 98}; 99 100struct am_state { 101/* state directory path */ 102char*dir; 103 104/* current and last patch numbers, 1-indexed */ 105int cur; 106int last; 107 108/* commit metadata and message */ 109char*author_name; 110char*author_email; 111char*author_date; 112char*msg; 113size_t msg_len; 114 115/* when --rebasing, records the original commit the patch came from */ 116struct object_id orig_commit; 117 118/* number of digits in patch filename */ 119int prec; 120 121/* various operating modes and command line options */ 122int interactive; 123int threeway; 124int quiet; 125int signoff;/* enum signoff_type */ 126int utf8; 127int keep;/* enum keep_type */ 128int message_id; 129int scissors;/* enum scissors_type */ 130struct argv_array git_apply_opts; 131const char*resolvemsg; 132int committer_date_is_author_date; 133int ignore_date; 134int allow_rerere_autoupdate; 135const char*sign_commit; 136int rebasing; 137}; 138 139/** 140 * Initializes am_state with the default values. 141 */ 142static voidam_state_init(struct am_state *state) 143{ 144int gpgsign; 145 146memset(state,0,sizeof(*state)); 147 148 state->dir =git_pathdup("rebase-apply"); 149 150 state->prec =4; 151 152git_config_get_bool("am.threeway", &state->threeway); 153 154 state->utf8 =1; 155 156git_config_get_bool("am.messageid", &state->message_id); 157 158 state->scissors = SCISSORS_UNSET; 159 160argv_array_init(&state->git_apply_opts); 161 162if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 163 state->sign_commit = gpgsign ?"": NULL; 164} 165 166/** 167 * Releases memory allocated by an am_state. 168 */ 169static voidam_state_release(struct am_state *state) 170{ 171free(state->dir); 172free(state->author_name); 173free(state->author_email); 174free(state->author_date); 175free(state->msg); 176argv_array_clear(&state->git_apply_opts); 177} 178 179/** 180 * Returns path relative to the am_state directory. 181 */ 182staticinlineconst char*am_path(const struct am_state *state,const char*path) 183{ 184returnmkpath("%s/%s", state->dir, path); 185} 186 187/** 188 * For convenience to call write_file() 189 */ 190static voidwrite_state_text(const struct am_state *state, 191const char*name,const char*string) 192{ 193write_file(am_path(state, name),"%s", string); 194} 195 196static voidwrite_state_count(const struct am_state *state, 197const char*name,int value) 198{ 199write_file(am_path(state, name),"%d", value); 200} 201 202static voidwrite_state_bool(const struct am_state *state, 203const char*name,int value) 204{ 205write_state_text(state, name, value ?"t":"f"); 206} 207 208/** 209 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 210 * at the end. 211 */ 212static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 213{ 214va_list ap; 215 216va_start(ap, fmt); 217if(!state->quiet) { 218vfprintf(fp, fmt, ap); 219putc('\n', fp); 220} 221va_end(ap); 222} 223 224/** 225 * Returns 1 if there is an am session in progress, 0 otherwise. 226 */ 227static intam_in_progress(const struct am_state *state) 228{ 229struct stat st; 230 231if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 232return0; 233if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 234return0; 235if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 236return0; 237return1; 238} 239 240/** 241 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 242 * number of bytes read on success, -1 if the file does not exist. If `trim` is 243 * set, trailing whitespace will be removed. 244 */ 245static intread_state_file(struct strbuf *sb,const struct am_state *state, 246const char*file,int trim) 247{ 248strbuf_reset(sb); 249 250if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 251if(trim) 252strbuf_trim(sb); 253 254return sb->len; 255} 256 257if(errno == ENOENT) 258return-1; 259 260die_errno(_("could not read '%s'"),am_path(state, file)); 261} 262 263/** 264 * Take a series of KEY='VALUE' lines where VALUE part is 265 * sq-quoted, and append <KEY, VALUE> at the end of the string list 266 */ 267static intparse_key_value_squoted(char*buf,struct string_list *list) 268{ 269while(*buf) { 270struct string_list_item *item; 271char*np; 272char*cp =strchr(buf,'='); 273if(!cp) { 274 np =strchrnul(buf,'\n'); 275returnerror(_("unable to parse '%.*s'"), 276(int) (np - buf), buf); 277} 278 np =strchrnul(cp,'\n'); 279*cp++ ='\0'; 280 item =string_list_append(list, buf); 281 282 buf = np + (*np =='\n'); 283*np ='\0'; 284 cp =sq_dequote(cp); 285if(!cp) 286returnerror(_("unable to dequote value of '%s'"), 287 item->string); 288 item->util =xstrdup(cp); 289} 290return0; 291} 292 293/** 294 * Reads and parses the state directory's "author-script" file, and sets 295 * state->author_name, state->author_email and state->author_date accordingly. 296 * Returns 0 on success, -1 if the file could not be parsed. 297 * 298 * The author script is of the format: 299 * 300 * GIT_AUTHOR_NAME='$author_name' 301 * GIT_AUTHOR_EMAIL='$author_email' 302 * GIT_AUTHOR_DATE='$author_date' 303 * 304 * where $author_name, $author_email and $author_date are quoted. We are strict 305 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 306 * script, and thus if the file differs from what this function expects, it is 307 * better to bail out than to do something that the user does not expect. 308 */ 309static intread_author_script(struct am_state *state) 310{ 311const char*filename =am_path(state,"author-script"); 312struct strbuf buf = STRBUF_INIT; 313struct string_list kv = STRING_LIST_INIT_DUP; 314int retval = -1;/* assume failure */ 315int i, name_i = -2, email_i = -2, date_i = -2, err =0; 316int fd; 317 318assert(!state->author_name); 319assert(!state->author_email); 320assert(!state->author_date); 321 322 fd =open(filename, O_RDONLY); 323if(fd <0) { 324if(errno == ENOENT) 325return0; 326returnerror_errno(_("could not open '%s' for reading"), 327 filename); 328} 329strbuf_read(&buf, fd,0); 330close(fd); 331if(parse_key_value_squoted(buf.buf, &kv)) 332goto finish; 333 334for(i =0; i < kv.nr; i++) { 335if(!strcmp(kv.items[i].string,"GIT_AUTHOR_NAME")) { 336if(name_i != -2) 337 name_i =error(_("'GIT_AUTHOR_NAME' already given")); 338else 339 name_i = i; 340}else if(!strcmp(kv.items[i].string,"GIT_AUTHOR_EMAIL")) { 341if(email_i != -2) 342 email_i =error(_("'GIT_AUTHOR_EMAIL' already given")); 343else 344 email_i = i; 345}else if(!strcmp(kv.items[i].string,"GIT_AUTHOR_DATE")) { 346if(date_i != -2) 347 date_i =error(_("'GIT_AUTHOR_DATE' already given")); 348else 349 date_i = i; 350}else{ 351 err =error(_("unknown variable '%s'"), 352 kv.items[i].string); 353} 354} 355if(name_i == -2) 356error(_("missing 'GIT_AUTHOR_NAME'")); 357if(email_i == -2) 358error(_("missing 'GIT_AUTHOR_EMAIL'")); 359if(date_i == -2) 360error(_("missing 'GIT_AUTHOR_DATE'")); 361if(date_i <0|| email_i <0|| date_i <0|| err) 362goto finish; 363 state->author_name = kv.items[name_i].util; 364 state->author_email = kv.items[email_i].util; 365 state->author_date = kv.items[date_i].util; 366 retval =0; 367finish: 368string_list_clear(&kv, !!retval); 369strbuf_release(&buf); 370return retval; 371} 372 373/** 374 * Saves state->author_name, state->author_email and state->author_date in the 375 * state directory's "author-script" file. 376 */ 377static voidwrite_author_script(const struct am_state *state) 378{ 379struct strbuf sb = STRBUF_INIT; 380 381strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 382sq_quote_buf(&sb, state->author_name); 383strbuf_addch(&sb,'\n'); 384 385strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 386sq_quote_buf(&sb, state->author_email); 387strbuf_addch(&sb,'\n'); 388 389strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 390sq_quote_buf(&sb, state->author_date); 391strbuf_addch(&sb,'\n'); 392 393write_state_text(state,"author-script", sb.buf); 394 395strbuf_release(&sb); 396} 397 398/** 399 * Reads the commit message from the state directory's "final-commit" file, 400 * setting state->msg to its contents and state->msg_len to the length of its 401 * contents in bytes. 402 * 403 * Returns 0 on success, -1 if the file does not exist. 404 */ 405static intread_commit_msg(struct am_state *state) 406{ 407struct strbuf sb = STRBUF_INIT; 408 409assert(!state->msg); 410 411if(read_state_file(&sb, state,"final-commit",0) <0) { 412strbuf_release(&sb); 413return-1; 414} 415 416 state->msg =strbuf_detach(&sb, &state->msg_len); 417return0; 418} 419 420/** 421 * Saves state->msg in the state directory's "final-commit" file. 422 */ 423static voidwrite_commit_msg(const struct am_state *state) 424{ 425const char*filename =am_path(state,"final-commit"); 426write_file_buf(filename, state->msg, state->msg_len); 427} 428 429/** 430 * Loads state from disk. 431 */ 432static voidam_load(struct am_state *state) 433{ 434struct strbuf sb = STRBUF_INIT; 435 436if(read_state_file(&sb, state,"next",1) <0) 437BUG("state file 'next' does not exist"); 438 state->cur =strtol(sb.buf, NULL,10); 439 440if(read_state_file(&sb, state,"last",1) <0) 441BUG("state file 'last' does not exist"); 442 state->last =strtol(sb.buf, NULL,10); 443 444if(read_author_script(state) <0) 445die(_("could not parse author script")); 446 447read_commit_msg(state); 448 449if(read_state_file(&sb, state,"original-commit",1) <0) 450oidclr(&state->orig_commit); 451else if(get_oid_hex(sb.buf, &state->orig_commit) <0) 452die(_("could not parse%s"),am_path(state,"original-commit")); 453 454read_state_file(&sb, state,"threeway",1); 455 state->threeway = !strcmp(sb.buf,"t"); 456 457read_state_file(&sb, state,"quiet",1); 458 state->quiet = !strcmp(sb.buf,"t"); 459 460read_state_file(&sb, state,"sign",1); 461 state->signoff = !strcmp(sb.buf,"t"); 462 463read_state_file(&sb, state,"utf8",1); 464 state->utf8 = !strcmp(sb.buf,"t"); 465 466if(file_exists(am_path(state,"rerere-autoupdate"))) { 467read_state_file(&sb, state,"rerere-autoupdate",1); 468 state->allow_rerere_autoupdate =strcmp(sb.buf,"t") ? 469 RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE; 470}else{ 471 state->allow_rerere_autoupdate =0; 472} 473 474read_state_file(&sb, state,"keep",1); 475if(!strcmp(sb.buf,"t")) 476 state->keep = KEEP_TRUE; 477else if(!strcmp(sb.buf,"b")) 478 state->keep = KEEP_NON_PATCH; 479else 480 state->keep = KEEP_FALSE; 481 482read_state_file(&sb, state,"messageid",1); 483 state->message_id = !strcmp(sb.buf,"t"); 484 485read_state_file(&sb, state,"scissors",1); 486if(!strcmp(sb.buf,"t")) 487 state->scissors = SCISSORS_TRUE; 488else if(!strcmp(sb.buf,"f")) 489 state->scissors = SCISSORS_FALSE; 490else 491 state->scissors = SCISSORS_UNSET; 492 493read_state_file(&sb, state,"apply-opt",1); 494argv_array_clear(&state->git_apply_opts); 495if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 496die(_("could not parse%s"),am_path(state,"apply-opt")); 497 498 state->rebasing = !!file_exists(am_path(state,"rebasing")); 499 500strbuf_release(&sb); 501} 502 503/** 504 * Removes the am_state directory, forcefully terminating the current am 505 * session. 506 */ 507static voidam_destroy(const struct am_state *state) 508{ 509struct strbuf sb = STRBUF_INIT; 510 511strbuf_addstr(&sb, state->dir); 512remove_dir_recursively(&sb,0); 513strbuf_release(&sb); 514} 515 516/** 517 * Runs applypatch-msg hook. Returns its exit code. 518 */ 519static intrun_applypatch_msg_hook(struct am_state *state) 520{ 521int ret; 522 523assert(state->msg); 524 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 525 526if(!ret) { 527FREE_AND_NULL(state->msg); 528if(read_commit_msg(state) <0) 529die(_("'%s' was deleted by the applypatch-msg hook"), 530am_path(state,"final-commit")); 531} 532 533return ret; 534} 535 536/** 537 * Runs post-rewrite hook. Returns it exit code. 538 */ 539static intrun_post_rewrite_hook(const struct am_state *state) 540{ 541struct child_process cp = CHILD_PROCESS_INIT; 542const char*hook =find_hook("post-rewrite"); 543int ret; 544 545if(!hook) 546return0; 547 548argv_array_push(&cp.args, hook); 549argv_array_push(&cp.args,"rebase"); 550 551 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 552 cp.stdout_to_stderr =1; 553 554 ret =run_command(&cp); 555 556close(cp.in); 557return ret; 558} 559 560/** 561 * Reads the state directory's "rewritten" file, and copies notes from the old 562 * commits listed in the file to their rewritten commits. 563 * 564 * Returns 0 on success, -1 on failure. 565 */ 566static intcopy_notes_for_rebase(const struct am_state *state) 567{ 568struct notes_rewrite_cfg *c; 569struct strbuf sb = STRBUF_INIT; 570const char*invalid_line =_("Malformed input line: '%s'."); 571const char*msg ="Notes added by 'git rebase'"; 572FILE*fp; 573int ret =0; 574 575assert(state->rebasing); 576 577 c =init_copy_notes_for_rewrite("rebase"); 578if(!c) 579return0; 580 581 fp =xfopen(am_path(state,"rewritten"),"r"); 582 583while(!strbuf_getline_lf(&sb, fp)) { 584struct object_id from_obj, to_obj; 585 586if(sb.len != GIT_SHA1_HEXSZ *2+1) { 587 ret =error(invalid_line, sb.buf); 588goto finish; 589} 590 591if(get_oid_hex(sb.buf, &from_obj)) { 592 ret =error(invalid_line, sb.buf); 593goto finish; 594} 595 596if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 597 ret =error(invalid_line, sb.buf); 598goto finish; 599} 600 601if(get_oid_hex(sb.buf + GIT_SHA1_HEXSZ +1, &to_obj)) { 602 ret =error(invalid_line, sb.buf); 603goto finish; 604} 605 606if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 607 ret =error(_("Failed to copy notes from '%s' to '%s'"), 608oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 609} 610 611finish: 612finish_copy_notes_for_rewrite(c, msg); 613fclose(fp); 614strbuf_release(&sb); 615return ret; 616} 617 618/** 619 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 620 * non-indented lines and checking if they look like they begin with valid 621 * header field names. 622 * 623 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 624 */ 625static intis_mail(FILE*fp) 626{ 627const char*header_regex ="^[!-9;-~]+:"; 628struct strbuf sb = STRBUF_INIT; 629 regex_t regex; 630int ret =1; 631 632if(fseek(fp,0L, SEEK_SET)) 633die_errno(_("fseek failed")); 634 635if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 636die("invalid pattern:%s", header_regex); 637 638while(!strbuf_getline(&sb, fp)) { 639if(!sb.len) 640break;/* End of header */ 641 642/* Ignore indented folded lines */ 643if(*sb.buf =='\t'|| *sb.buf ==' ') 644continue; 645 646/* It's a header if it matches header_regex */ 647if(regexec(®ex, sb.buf,0, NULL,0)) { 648 ret =0; 649goto done; 650} 651} 652 653done: 654regfree(®ex); 655strbuf_release(&sb); 656return ret; 657} 658 659/** 660 * Attempts to detect the patch_format of the patches contained in `paths`, 661 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 662 * detection fails. 663 */ 664static intdetect_patch_format(const char**paths) 665{ 666enum patch_format ret = PATCH_FORMAT_UNKNOWN; 667struct strbuf l1 = STRBUF_INIT; 668struct strbuf l2 = STRBUF_INIT; 669struct strbuf l3 = STRBUF_INIT; 670FILE*fp; 671 672/* 673 * We default to mbox format if input is from stdin and for directories 674 */ 675if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 676return PATCH_FORMAT_MBOX; 677 678/* 679 * Otherwise, check the first few lines of the first patch, starting 680 * from the first non-blank line, to try to detect its format. 681 */ 682 683 fp =xfopen(*paths,"r"); 684 685while(!strbuf_getline(&l1, fp)) { 686if(l1.len) 687break; 688} 689 690if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 691 ret = PATCH_FORMAT_MBOX; 692goto done; 693} 694 695if(starts_with(l1.buf,"# This series applies on GIT commit")) { 696 ret = PATCH_FORMAT_STGIT_SERIES; 697goto done; 698} 699 700if(!strcmp(l1.buf,"# HG changeset patch")) { 701 ret = PATCH_FORMAT_HG; 702goto done; 703} 704 705strbuf_getline(&l2, fp); 706strbuf_getline(&l3, fp); 707 708/* 709 * If the second line is empty and the third is a From, Author or Date 710 * entry, this is likely an StGit patch. 711 */ 712if(l1.len && !l2.len && 713(starts_with(l3.buf,"From:") || 714starts_with(l3.buf,"Author:") || 715starts_with(l3.buf,"Date:"))) { 716 ret = PATCH_FORMAT_STGIT; 717goto done; 718} 719 720if(l1.len &&is_mail(fp)) { 721 ret = PATCH_FORMAT_MBOX; 722goto done; 723} 724 725done: 726fclose(fp); 727strbuf_release(&l1); 728strbuf_release(&l2); 729strbuf_release(&l3); 730return ret; 731} 732 733/** 734 * Splits out individual email patches from `paths`, where each path is either 735 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 736 */ 737static intsplit_mail_mbox(struct am_state *state,const char**paths, 738int keep_cr,int mboxrd) 739{ 740struct child_process cp = CHILD_PROCESS_INIT; 741struct strbuf last = STRBUF_INIT; 742int ret; 743 744 cp.git_cmd =1; 745argv_array_push(&cp.args,"mailsplit"); 746argv_array_pushf(&cp.args,"-d%d", state->prec); 747argv_array_pushf(&cp.args,"-o%s", state->dir); 748argv_array_push(&cp.args,"-b"); 749if(keep_cr) 750argv_array_push(&cp.args,"--keep-cr"); 751if(mboxrd) 752argv_array_push(&cp.args,"--mboxrd"); 753argv_array_push(&cp.args,"--"); 754argv_array_pushv(&cp.args, paths); 755 756 ret =capture_command(&cp, &last,8); 757if(ret) 758goto exit; 759 760 state->cur =1; 761 state->last =strtol(last.buf, NULL,10); 762 763exit: 764strbuf_release(&last); 765return ret ? -1:0; 766} 767 768/** 769 * Callback signature for split_mail_conv(). The foreign patch should be 770 * read from `in`, and the converted patch (in RFC2822 mail format) should be 771 * written to `out`. Return 0 on success, or -1 on failure. 772 */ 773typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 774 775/** 776 * Calls `fn` for each file in `paths` to convert the foreign patch to the 777 * RFC2822 mail format suitable for parsing with git-mailinfo. 778 * 779 * Returns 0 on success, -1 on failure. 780 */ 781static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 782const char**paths,int keep_cr) 783{ 784static const char*stdin_only[] = {"-", NULL}; 785int i; 786 787if(!*paths) 788 paths = stdin_only; 789 790for(i =0; *paths; paths++, i++) { 791FILE*in, *out; 792const char*mail; 793int ret; 794 795if(!strcmp(*paths,"-")) 796 in = stdin; 797else 798 in =fopen(*paths,"r"); 799 800if(!in) 801returnerror_errno(_("could not open '%s' for reading"), 802*paths); 803 804 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 805 806 out =fopen(mail,"w"); 807if(!out) { 808if(in != stdin) 809fclose(in); 810returnerror_errno(_("could not open '%s' for writing"), 811 mail); 812} 813 814 ret =fn(out, in, keep_cr); 815 816fclose(out); 817if(in != stdin) 818fclose(in); 819 820if(ret) 821returnerror(_("could not parse patch '%s'"), *paths); 822} 823 824 state->cur =1; 825 state->last = i; 826return0; 827} 828 829/** 830 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 831 * message suitable for parsing with git-mailinfo. 832 */ 833static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 834{ 835struct strbuf sb = STRBUF_INIT; 836int subject_printed =0; 837 838while(!strbuf_getline_lf(&sb, in)) { 839const char*str; 840 841if(str_isspace(sb.buf)) 842continue; 843else if(skip_prefix(sb.buf,"Author:", &str)) 844fprintf(out,"From:%s\n", str); 845else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 846fprintf(out,"%s\n", sb.buf); 847else if(!subject_printed) { 848fprintf(out,"Subject:%s\n", sb.buf); 849 subject_printed =1; 850}else{ 851fprintf(out,"\n%s\n", sb.buf); 852break; 853} 854} 855 856strbuf_reset(&sb); 857while(strbuf_fread(&sb,8192, in) >0) { 858fwrite(sb.buf,1, sb.len, out); 859strbuf_reset(&sb); 860} 861 862strbuf_release(&sb); 863return0; 864} 865 866/** 867 * This function only supports a single StGit series file in `paths`. 868 * 869 * Given an StGit series file, converts the StGit patches in the series into 870 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 871 * the state directory. 872 * 873 * Returns 0 on success, -1 on failure. 874 */ 875static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 876int keep_cr) 877{ 878const char*series_dir; 879char*series_dir_buf; 880FILE*fp; 881struct argv_array patches = ARGV_ARRAY_INIT; 882struct strbuf sb = STRBUF_INIT; 883int ret; 884 885if(!paths[0] || paths[1]) 886returnerror(_("Only one StGIT patch series can be applied at once")); 887 888 series_dir_buf =xstrdup(*paths); 889 series_dir =dirname(series_dir_buf); 890 891 fp =fopen(*paths,"r"); 892if(!fp) 893returnerror_errno(_("could not open '%s' for reading"), *paths); 894 895while(!strbuf_getline_lf(&sb, fp)) { 896if(*sb.buf =='#') 897continue;/* skip comment lines */ 898 899argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 900} 901 902fclose(fp); 903strbuf_release(&sb); 904free(series_dir_buf); 905 906 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 907 908argv_array_clear(&patches); 909return ret; 910} 911 912/** 913 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 914 * message suitable for parsing with git-mailinfo. 915 */ 916static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 917{ 918struct strbuf sb = STRBUF_INIT; 919int rc =0; 920 921while(!strbuf_getline_lf(&sb, in)) { 922const char*str; 923 924if(skip_prefix(sb.buf,"# User ", &str)) 925fprintf(out,"From:%s\n", str); 926else if(skip_prefix(sb.buf,"# Date ", &str)) { 927 timestamp_t timestamp; 928long tz, tz2; 929char*end; 930 931 errno =0; 932 timestamp =parse_timestamp(str, &end,10); 933if(errno) { 934 rc =error(_("invalid timestamp")); 935goto exit; 936} 937 938if(!skip_prefix(end," ", &str)) { 939 rc =error(_("invalid Date line")); 940goto exit; 941} 942 943 errno =0; 944 tz =strtol(str, &end,10); 945if(errno) { 946 rc =error(_("invalid timezone offset")); 947goto exit; 948} 949 950if(*end) { 951 rc =error(_("invalid Date line")); 952goto exit; 953} 954 955/* 956 * mercurial's timezone is in seconds west of UTC, 957 * however git's timezone is in hours + minutes east of 958 * UTC. Convert it. 959 */ 960 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 961if(tz >0) 962 tz2 = -tz2; 963 964fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 965}else if(starts_with(sb.buf,"# ")) { 966continue; 967}else{ 968fprintf(out,"\n%s\n", sb.buf); 969break; 970} 971} 972 973strbuf_reset(&sb); 974while(strbuf_fread(&sb,8192, in) >0) { 975fwrite(sb.buf,1, sb.len, out); 976strbuf_reset(&sb); 977} 978exit: 979strbuf_release(&sb); 980return rc; 981} 982 983/** 984 * Splits a list of files/directories into individual email patches. Each path 985 * in `paths` must be a file/directory that is formatted according to 986 * `patch_format`. 987 * 988 * Once split out, the individual email patches will be stored in the state 989 * directory, with each patch's filename being its index, padded to state->prec 990 * digits. 991 * 992 * state->cur will be set to the index of the first mail, and state->last will 993 * be set to the index of the last mail. 994 * 995 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 996 * to disable this behavior, -1 to use the default configured setting. 997 * 998 * Returns 0 on success, -1 on failure. 999 */1000static intsplit_mail(struct am_state *state,enum patch_format patch_format,1001const char**paths,int keep_cr)1002{1003if(keep_cr <0) {1004 keep_cr =0;1005git_config_get_bool("am.keepcr", &keep_cr);1006}10071008switch(patch_format) {1009case PATCH_FORMAT_MBOX:1010returnsplit_mail_mbox(state, paths, keep_cr,0);1011case PATCH_FORMAT_STGIT:1012returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);1013case PATCH_FORMAT_STGIT_SERIES:1014returnsplit_mail_stgit_series(state, paths, keep_cr);1015case PATCH_FORMAT_HG:1016returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr);1017case PATCH_FORMAT_MBOXRD:1018returnsplit_mail_mbox(state, paths, keep_cr,1);1019default:1020BUG("invalid patch_format");1021}1022return-1;1023}10241025/**1026 * Setup a new am session for applying patches1027 */1028static voidam_setup(struct am_state *state,enum patch_format patch_format,1029const char**paths,int keep_cr)1030{1031struct object_id curr_head;1032const char*str;1033struct strbuf sb = STRBUF_INIT;10341035if(!patch_format)1036 patch_format =detect_patch_format(paths);10371038if(!patch_format) {1039fprintf_ln(stderr,_("Patch format detection failed."));1040exit(128);1041}10421043if(mkdir(state->dir,0777) <0&& errno != EEXIST)1044die_errno(_("failed to create directory '%s'"), state->dir);1045delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10461047if(split_mail(state, patch_format, paths, keep_cr) <0) {1048am_destroy(state);1049die(_("Failed to split patches."));1050}10511052if(state->rebasing)1053 state->threeway =1;10541055write_state_bool(state,"threeway", state->threeway);1056write_state_bool(state,"quiet", state->quiet);1057write_state_bool(state,"sign", state->signoff);1058write_state_bool(state,"utf8", state->utf8);10591060if(state->allow_rerere_autoupdate)1061write_state_bool(state,"rerere-autoupdate",1062 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE);10631064switch(state->keep) {1065case KEEP_FALSE:1066 str ="f";1067break;1068case KEEP_TRUE:1069 str ="t";1070break;1071case KEEP_NON_PATCH:1072 str ="b";1073break;1074default:1075BUG("invalid value for state->keep");1076}10771078write_state_text(state,"keep", str);1079write_state_bool(state,"messageid", state->message_id);10801081switch(state->scissors) {1082case SCISSORS_UNSET:1083 str ="";1084break;1085case SCISSORS_FALSE:1086 str ="f";1087break;1088case SCISSORS_TRUE:1089 str ="t";1090break;1091default:1092BUG("invalid value for state->scissors");1093}1094write_state_text(state,"scissors", str);10951096sq_quote_argv(&sb, state->git_apply_opts.argv);1097write_state_text(state,"apply-opt", sb.buf);10981099if(state->rebasing)1100write_state_text(state,"rebasing","");1101else1102write_state_text(state,"applying","");11031104if(!get_oid("HEAD", &curr_head)) {1105write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1106if(!state->rebasing)1107update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1108 UPDATE_REFS_DIE_ON_ERR);1109}else{1110write_state_text(state,"abort-safety","");1111if(!state->rebasing)1112delete_ref(NULL,"ORIG_HEAD", NULL,0);1113}11141115/*1116 * NOTE: Since the "next" and "last" files determine if an am_state1117 * session is in progress, they should be written last.1118 */11191120write_state_count(state,"next", state->cur);1121write_state_count(state,"last", state->last);11221123strbuf_release(&sb);1124}11251126/**1127 * Increments the patch pointer, and cleans am_state for the application of the1128 * next patch.1129 */1130static voidam_next(struct am_state *state)1131{1132struct object_id head;11331134FREE_AND_NULL(state->author_name);1135FREE_AND_NULL(state->author_email);1136FREE_AND_NULL(state->author_date);1137FREE_AND_NULL(state->msg);1138 state->msg_len =0;11391140unlink(am_path(state,"author-script"));1141unlink(am_path(state,"final-commit"));11421143oidclr(&state->orig_commit);1144unlink(am_path(state,"original-commit"));1145delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);11461147if(!get_oid("HEAD", &head))1148write_state_text(state,"abort-safety",oid_to_hex(&head));1149else1150write_state_text(state,"abort-safety","");11511152 state->cur++;1153write_state_count(state,"next", state->cur);1154}11551156/**1157 * Returns the filename of the current patch email.1158 */1159static const char*msgnum(const struct am_state *state)1160{1161static struct strbuf sb = STRBUF_INIT;11621163strbuf_reset(&sb);1164strbuf_addf(&sb,"%0*d", state->prec, state->cur);11651166return sb.buf;1167}11681169/**1170 * Refresh and write index.1171 */1172static voidrefresh_and_write_cache(void)1173{1174struct lock_file lock_file = LOCK_INIT;11751176hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1177refresh_cache(REFRESH_QUIET);1178if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1179die(_("unable to write index file"));1180}11811182/**1183 * Dies with a user-friendly message on how to proceed after resolving the1184 * problem. This message can be overridden with state->resolvemsg.1185 */1186static void NORETURN die_user_resolve(const struct am_state *state)1187{1188if(state->resolvemsg) {1189printf_ln("%s", state->resolvemsg);1190}else{1191const char*cmdline = state->interactive ?"git am -i":"git am";11921193printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1194printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1195printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1196}11971198exit(128);1199}12001201/**1202 * Appends signoff to the "msg" field of the am_state.1203 */1204static voidam_append_signoff(struct am_state *state)1205{1206struct strbuf sb = STRBUF_INIT;12071208strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1209append_signoff(&sb,0,0);1210 state->msg =strbuf_detach(&sb, &state->msg_len);1211}12121213/**1214 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1215 * state->msg will be set to the patch message. state->author_name,1216 * state->author_email and state->author_date will be set to the patch author's1217 * name, email and date respectively. The patch body will be written to the1218 * state directory's "patch" file.1219 *1220 * Returns 1 if the patch should be skipped, 0 otherwise.1221 */1222static intparse_mail(struct am_state *state,const char*mail)1223{1224FILE*fp;1225struct strbuf sb = STRBUF_INIT;1226struct strbuf msg = STRBUF_INIT;1227struct strbuf author_name = STRBUF_INIT;1228struct strbuf author_date = STRBUF_INIT;1229struct strbuf author_email = STRBUF_INIT;1230int ret =0;1231struct mailinfo mi;12321233setup_mailinfo(&mi);12341235if(state->utf8)1236 mi.metainfo_charset =get_commit_output_encoding();1237else1238 mi.metainfo_charset = NULL;12391240switch(state->keep) {1241case KEEP_FALSE:1242break;1243case KEEP_TRUE:1244 mi.keep_subject =1;1245break;1246case KEEP_NON_PATCH:1247 mi.keep_non_patch_brackets_in_subject =1;1248break;1249default:1250BUG("invalid value for state->keep");1251}12521253if(state->message_id)1254 mi.add_message_id =1;12551256switch(state->scissors) {1257case SCISSORS_UNSET:1258break;1259case SCISSORS_FALSE:1260 mi.use_scissors =0;1261break;1262case SCISSORS_TRUE:1263 mi.use_scissors =1;1264break;1265default:1266BUG("invalid value for state->scissors");1267}12681269 mi.input =xfopen(mail,"r");1270 mi.output =xfopen(am_path(state,"info"),"w");1271if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1272die("could not parse patch");12731274fclose(mi.input);1275fclose(mi.output);12761277if(mi.format_flowed)1278warning(_("Patch sent with format=flowed; "1279"space at the end of lines might be lost."));12801281/* Extract message and author information */1282 fp =xfopen(am_path(state,"info"),"r");1283while(!strbuf_getline_lf(&sb, fp)) {1284const char*x;12851286if(skip_prefix(sb.buf,"Subject: ", &x)) {1287if(msg.len)1288strbuf_addch(&msg,'\n');1289strbuf_addstr(&msg, x);1290}else if(skip_prefix(sb.buf,"Author: ", &x))1291strbuf_addstr(&author_name, x);1292else if(skip_prefix(sb.buf,"Email: ", &x))1293strbuf_addstr(&author_email, x);1294else if(skip_prefix(sb.buf,"Date: ", &x))1295strbuf_addstr(&author_date, x);1296}1297fclose(fp);12981299/* Skip pine's internal folder data */1300if(!strcmp(author_name.buf,"Mail System Internal Data")) {1301 ret =1;1302goto finish;1303}13041305if(is_empty_file(am_path(state,"patch"))) {1306printf_ln(_("Patch is empty."));1307die_user_resolve(state);1308}13091310strbuf_addstr(&msg,"\n\n");1311strbuf_addbuf(&msg, &mi.log_message);1312strbuf_stripspace(&msg,0);13131314assert(!state->author_name);1315 state->author_name =strbuf_detach(&author_name, NULL);13161317assert(!state->author_email);1318 state->author_email =strbuf_detach(&author_email, NULL);13191320assert(!state->author_date);1321 state->author_date =strbuf_detach(&author_date, NULL);13221323assert(!state->msg);1324 state->msg =strbuf_detach(&msg, &state->msg_len);13251326finish:1327strbuf_release(&msg);1328strbuf_release(&author_date);1329strbuf_release(&author_email);1330strbuf_release(&author_name);1331strbuf_release(&sb);1332clear_mailinfo(&mi);1333return ret;1334}13351336/**1337 * Sets commit_id to the commit hash where the mail was generated from.1338 * Returns 0 on success, -1 on failure.1339 */1340static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1341{1342struct strbuf sb = STRBUF_INIT;1343FILE*fp =xfopen(mail,"r");1344const char*x;1345int ret =0;13461347if(strbuf_getline_lf(&sb, fp) ||1348!skip_prefix(sb.buf,"From ", &x) ||1349get_oid_hex(x, commit_id) <0)1350 ret = -1;13511352strbuf_release(&sb);1353fclose(fp);1354return ret;1355}13561357/**1358 * Sets state->msg, state->author_name, state->author_email, state->author_date1359 * to the commit's respective info.1360 */1361static voidget_commit_info(struct am_state *state,struct commit *commit)1362{1363const char*buffer, *ident_line, *msg;1364size_t ident_len;1365struct ident_split id;13661367 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13681369 ident_line =find_commit_header(buffer,"author", &ident_len);13701371if(split_ident_line(&id, ident_line, ident_len) <0)1372die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);13731374assert(!state->author_name);1375if(id.name_begin)1376 state->author_name =1377xmemdupz(id.name_begin, id.name_end - id.name_begin);1378else1379 state->author_name =xstrdup("");13801381assert(!state->author_email);1382if(id.mail_begin)1383 state->author_email =1384xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1385else1386 state->author_email =xstrdup("");13871388assert(!state->author_date);1389 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));13901391assert(!state->msg);1392 msg =strstr(buffer,"\n\n");1393if(!msg)1394die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1395 state->msg =xstrdup(msg +2);1396 state->msg_len =strlen(state->msg);1397unuse_commit_buffer(commit, buffer);1398}13991400/**1401 * Writes `commit` as a patch to the state directory's "patch" file.1402 */1403static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1404{1405struct rev_info rev_info;1406FILE*fp;14071408 fp =xfopen(am_path(state,"patch"),"w");1409init_revisions(&rev_info, NULL);1410 rev_info.diff =1;1411 rev_info.abbrev =0;1412 rev_info.disable_stdin =1;1413 rev_info.show_root_diff =1;1414 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1415 rev_info.no_commit_id =1;1416 rev_info.diffopt.flags.binary =1;1417 rev_info.diffopt.flags.full_index =1;1418 rev_info.diffopt.use_color =0;1419 rev_info.diffopt.file = fp;1420 rev_info.diffopt.close_file =1;1421add_pending_object(&rev_info, &commit->object,"");1422diff_setup_done(&rev_info.diffopt);1423log_tree_commit(&rev_info, commit);1424}14251426/**1427 * Writes the diff of the index against HEAD as a patch to the state1428 * directory's "patch" file.1429 */1430static voidwrite_index_patch(const struct am_state *state)1431{1432struct tree *tree;1433struct object_id head;1434struct rev_info rev_info;1435FILE*fp;14361437if(!get_oid_tree("HEAD", &head))1438 tree =lookup_tree(the_repository, &head);1439else1440 tree =lookup_tree(the_repository,1441 the_repository->hash_algo->empty_tree);14421443 fp =xfopen(am_path(state,"patch"),"w");1444init_revisions(&rev_info, NULL);1445 rev_info.diff =1;1446 rev_info.disable_stdin =1;1447 rev_info.no_commit_id =1;1448 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1449 rev_info.diffopt.use_color =0;1450 rev_info.diffopt.file = fp;1451 rev_info.diffopt.close_file =1;1452add_pending_object(&rev_info, &tree->object,"");1453diff_setup_done(&rev_info.diffopt);1454run_diff_index(&rev_info,1);1455}14561457/**1458 * Like parse_mail(), but parses the mail by looking up its commit ID1459 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1460 * of patches.1461 *1462 * state->orig_commit will be set to the original commit ID.1463 *1464 * Will always return 0 as the patch should never be skipped.1465 */1466static intparse_mail_rebase(struct am_state *state,const char*mail)1467{1468struct commit *commit;1469struct object_id commit_oid;14701471if(get_mail_commit_oid(&commit_oid, mail) <0)1472die(_("could not parse%s"), mail);14731474 commit =lookup_commit_or_die(&commit_oid, mail);14751476get_commit_info(state, commit);14771478write_commit_patch(state, commit);14791480oidcpy(&state->orig_commit, &commit_oid);1481write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1482update_ref("am","REBASE_HEAD", &commit_oid,1483 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);14841485return0;1486}14871488/**1489 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1490 * `index_file` is not NULL, the patch will be applied to that index.1491 */1492static intrun_apply(const struct am_state *state,const char*index_file)1493{1494struct argv_array apply_paths = ARGV_ARRAY_INIT;1495struct argv_array apply_opts = ARGV_ARRAY_INIT;1496struct apply_state apply_state;1497int res, opts_left;1498int force_apply =0;1499int options =0;15001501if(init_apply_state(&apply_state, the_repository, NULL))1502BUG("init_apply_state() failed");15031504argv_array_push(&apply_opts,"apply");1505argv_array_pushv(&apply_opts, state->git_apply_opts.argv);15061507 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1508&apply_state, &force_apply, &options,1509 NULL);15101511if(opts_left !=0)1512die("unknown option passed through to git apply");15131514if(index_file) {1515 apply_state.index_file = index_file;1516 apply_state.cached =1;1517}else1518 apply_state.check_index =1;15191520/*1521 * If we are allowed to fall back on 3-way merge, don't give false1522 * errors during the initial attempt.1523 */1524if(state->threeway && !index_file)1525 apply_state.apply_verbosity = verbosity_silent;15261527if(check_apply_state(&apply_state, force_apply))1528BUG("check_apply_state() failed");15291530argv_array_push(&apply_paths,am_path(state,"patch"));15311532 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);15331534argv_array_clear(&apply_paths);1535argv_array_clear(&apply_opts);1536clear_apply_state(&apply_state);15371538if(res)1539return res;15401541if(index_file) {1542/* Reload index as apply_all_patches() will have modified it. */1543discard_cache();1544read_cache_from(index_file);1545}15461547return0;1548}15491550/**1551 * Builds an index that contains just the blobs needed for a 3way merge.1552 */1553static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1554{1555struct child_process cp = CHILD_PROCESS_INIT;15561557 cp.git_cmd =1;1558argv_array_push(&cp.args,"apply");1559argv_array_pushv(&cp.args, state->git_apply_opts.argv);1560argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1561argv_array_push(&cp.args,am_path(state,"patch"));15621563if(run_command(&cp))1564return-1;15651566return0;1567}15681569/**1570 * Attempt a threeway merge, using index_path as the temporary index.1571 */1572static intfall_back_threeway(const struct am_state *state,const char*index_path)1573{1574struct object_id orig_tree, their_tree, our_tree;1575const struct object_id *bases[1] = { &orig_tree };1576struct merge_options o;1577struct commit *result;1578char*their_tree_name;15791580if(get_oid("HEAD", &our_tree) <0)1581oidcpy(&our_tree, the_hash_algo->empty_tree);15821583if(build_fake_ancestor(state, index_path))1584returnerror("could not build fake ancestor");15851586discard_cache();1587read_cache_from(index_path);15881589if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1590returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15911592say(state, stdout,_("Using index info to reconstruct a base tree..."));15931594if(!state->quiet) {1595/*1596 * List paths that needed 3-way fallback, so that the user can1597 * review them with extra care to spot mismerges.1598 */1599struct rev_info rev_info;1600const char*diff_filter_str ="--diff-filter=AM";16011602init_revisions(&rev_info, NULL);1603 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1604diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1605add_pending_oid(&rev_info,"HEAD", &our_tree,0);1606diff_setup_done(&rev_info.diffopt);1607run_diff_index(&rev_info,1);1608}16091610if(run_apply(state, index_path))1611returnerror(_("Did you hand edit your patch?\n"1612"It does not apply to blobs recorded in its index."));16131614if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1615returnerror("could not write tree");16161617say(state, stdout,_("Falling back to patching base and 3-way merge..."));16181619discard_cache();1620read_cache();16211622/*1623 * This is not so wrong. Depending on which base we picked, orig_tree1624 * may be wildly different from ours, but their_tree has the same set of1625 * wildly different changes in parts the patch did not touch, so1626 * recursive ends up canceling them, saying that we reverted all those1627 * changes.1628 */16291630init_merge_options(&o);16311632 o.branch1 ="HEAD";1633 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1634 o.branch2 = their_tree_name;1635 o.detect_directory_renames =0;16361637if(state->quiet)1638 o.verbosity =0;16391640if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1641rerere(state->allow_rerere_autoupdate);1642free(their_tree_name);1643returnerror(_("Failed to merge in the changes."));1644}16451646free(their_tree_name);1647return0;1648}16491650/**1651 * Commits the current index with state->msg as the commit message and1652 * state->author_name, state->author_email and state->author_date as the author1653 * information.1654 */1655static voiddo_commit(const struct am_state *state)1656{1657struct object_id tree, parent, commit;1658const struct object_id *old_oid;1659struct commit_list *parents = NULL;1660const char*reflog_msg, *author;1661struct strbuf sb = STRBUF_INIT;16621663if(run_hook_le(NULL,"pre-applypatch", NULL))1664exit(1);16651666if(write_cache_as_tree(&tree,0, NULL))1667die(_("git write-tree failed to write a tree"));16681669if(!get_oid_commit("HEAD", &parent)) {1670 old_oid = &parent;1671commit_list_insert(lookup_commit(the_repository, &parent),1672&parents);1673}else{1674 old_oid = NULL;1675say(state, stderr,_("applying to an empty history"));1676}16771678 author =fmt_ident(state->author_name, state->author_email,1679 state->ignore_date ? NULL : state->author_date,1680 IDENT_STRICT);16811682if(state->committer_date_is_author_date)1683setenv("GIT_COMMITTER_DATE",1684 state->ignore_date ?"": state->author_date,1);16851686if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1687 author, state->sign_commit))1688die(_("failed to write commit object"));16891690 reflog_msg =getenv("GIT_REFLOG_ACTION");1691if(!reflog_msg)1692 reflog_msg ="am";16931694strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1695 state->msg);16961697update_ref(sb.buf,"HEAD", &commit, old_oid,0,1698 UPDATE_REFS_DIE_ON_ERR);16991700if(state->rebasing) {1701FILE*fp =xfopen(am_path(state,"rewritten"),"a");17021703assert(!is_null_oid(&state->orig_commit));1704fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1705fprintf(fp,"%s\n",oid_to_hex(&commit));1706fclose(fp);1707}17081709run_hook_le(NULL,"post-applypatch", NULL);17101711strbuf_release(&sb);1712}17131714/**1715 * Validates the am_state for resuming -- the "msg" and authorship fields must1716 * be filled up.1717 */1718static voidvalidate_resume_state(const struct am_state *state)1719{1720if(!state->msg)1721die(_("cannot resume:%sdoes not exist."),1722am_path(state,"final-commit"));17231724if(!state->author_name || !state->author_email || !state->author_date)1725die(_("cannot resume:%sdoes not exist."),1726am_path(state,"author-script"));1727}17281729/**1730 * Interactively prompt the user on whether the current patch should be1731 * applied.1732 *1733 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1734 * skip it.1735 */1736static intdo_interactive(struct am_state *state)1737{1738assert(state->msg);17391740if(!isatty(0))1741die(_("cannot be interactive without stdin connected to a terminal."));17421743for(;;) {1744const char*reply;17451746puts(_("Commit Body is:"));1747puts("--------------------------");1748printf("%s", state->msg);1749puts("--------------------------");17501751/*1752 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1753 * in your translation. The program will only accept English1754 * input at this point.1755 */1756 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17571758if(!reply) {1759continue;1760}else if(*reply =='y'|| *reply =='Y') {1761return0;1762}else if(*reply =='a'|| *reply =='A') {1763 state->interactive =0;1764return0;1765}else if(*reply =='n'|| *reply =='N') {1766return1;1767}else if(*reply =='e'|| *reply =='E') {1768struct strbuf msg = STRBUF_INIT;17691770if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1771free(state->msg);1772 state->msg =strbuf_detach(&msg, &state->msg_len);1773}1774strbuf_release(&msg);1775}else if(*reply =='v'|| *reply =='V') {1776const char*pager =git_pager(1);1777struct child_process cp = CHILD_PROCESS_INIT;17781779if(!pager)1780 pager ="cat";1781prepare_pager_args(&cp, pager);1782argv_array_push(&cp.args,am_path(state,"patch"));1783run_command(&cp);1784}1785}1786}17871788/**1789 * Applies all queued mail.1790 *1791 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1792 * well as the state directory's "patch" file is used as-is for applying the1793 * patch and committing it.1794 */1795static voidam_run(struct am_state *state,int resume)1796{1797const char*argv_gc_auto[] = {"gc","--auto", NULL};1798struct strbuf sb = STRBUF_INIT;17991800unlink(am_path(state,"dirtyindex"));18011802refresh_and_write_cache();18031804if(index_has_changes(&the_index, NULL, &sb)) {1805write_state_bool(state,"dirtyindex",1);1806die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1807}18081809strbuf_release(&sb);18101811while(state->cur <= state->last) {1812const char*mail =am_path(state,msgnum(state));1813int apply_status;18141815reset_ident_date();18161817if(!file_exists(mail))1818goto next;18191820if(resume) {1821validate_resume_state(state);1822}else{1823int skip;18241825if(state->rebasing)1826 skip =parse_mail_rebase(state, mail);1827else1828 skip =parse_mail(state, mail);18291830if(skip)1831goto next;/* mail should be skipped */18321833if(state->signoff)1834am_append_signoff(state);18351836write_author_script(state);1837write_commit_msg(state);1838}18391840if(state->interactive &&do_interactive(state))1841goto next;18421843if(run_applypatch_msg_hook(state))1844exit(1);18451846say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18471848 apply_status =run_apply(state, NULL);18491850if(apply_status && state->threeway) {1851struct strbuf sb = STRBUF_INIT;18521853strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1854 apply_status =fall_back_threeway(state, sb.buf);1855strbuf_release(&sb);18561857/*1858 * Applying the patch to an earlier tree and merging1859 * the result may have produced the same tree as ours.1860 */1861if(!apply_status &&1862!index_has_changes(&the_index, NULL, NULL)) {1863say(state, stdout,_("No changes -- Patch already applied."));1864goto next;1865}1866}18671868if(apply_status) {1869printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1870linelen(state->msg), state->msg);18711872if(advice_amworkdir)1873advise(_("Use 'git am --show-current-patch' to see the failed patch"));18741875die_user_resolve(state);1876}18771878do_commit(state);18791880next:1881am_next(state);18821883if(resume)1884am_load(state);1885 resume =0;1886}18871888if(!is_empty_file(am_path(state,"rewritten"))) {1889assert(state->rebasing);1890copy_notes_for_rebase(state);1891run_post_rewrite_hook(state);1892}18931894/*1895 * In rebasing mode, it's up to the caller to take care of1896 * housekeeping.1897 */1898if(!state->rebasing) {1899am_destroy(state);1900close_all_packs(the_repository->objects);1901run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1902}1903}19041905/**1906 * Resume the current am session after patch application failure. The user did1907 * all the hard work, and we do not have to do any patch application. Just1908 * trust and commit what the user has in the index and working tree.1909 */1910static voidam_resolve(struct am_state *state)1911{1912validate_resume_state(state);19131914say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);19151916if(!index_has_changes(&the_index, NULL, NULL)) {1917printf_ln(_("No changes - did you forget to use 'git add'?\n"1918"If there is nothing left to stage, chances are that something else\n"1919"already introduced the same changes; you might want to skip this patch."));1920die_user_resolve(state);1921}19221923if(unmerged_cache()) {1924printf_ln(_("You still have unmerged paths in your index.\n"1925"You should 'git add' each file with resolved conflicts to mark them as such.\n"1926"You might run `git rm` on a file to accept\"deleted by them\"for it."));1927die_user_resolve(state);1928}19291930if(state->interactive) {1931write_index_patch(state);1932if(do_interactive(state))1933goto next;1934}19351936rerere(0);19371938do_commit(state);19391940next:1941am_next(state);1942am_load(state);1943am_run(state,0);1944}19451946/**1947 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1948 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1949 * failure.1950 */1951static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1952{1953struct lock_file lock_file = LOCK_INIT;1954struct unpack_trees_options opts;1955struct tree_desc t[2];19561957if(parse_tree(head) ||parse_tree(remote))1958return-1;19591960hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19611962refresh_cache(REFRESH_QUIET);19631964memset(&opts,0,sizeof(opts));1965 opts.head_idx =1;1966 opts.src_index = &the_index;1967 opts.dst_index = &the_index;1968 opts.update =1;1969 opts.merge =1;1970 opts.reset = reset;1971 opts.fn = twoway_merge;1972init_tree_desc(&t[0], head->buffer, head->size);1973init_tree_desc(&t[1], remote->buffer, remote->size);19741975if(unpack_trees(2, t, &opts)) {1976rollback_lock_file(&lock_file);1977return-1;1978}19791980if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1981die(_("unable to write new index file"));19821983return0;1984}19851986/**1987 * Merges a tree into the index. The index's stat info will take precedence1988 * over the merged tree's. Returns 0 on success, -1 on failure.1989 */1990static intmerge_tree(struct tree *tree)1991{1992struct lock_file lock_file = LOCK_INIT;1993struct unpack_trees_options opts;1994struct tree_desc t[1];19951996if(parse_tree(tree))1997return-1;19981999hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);20002001memset(&opts,0,sizeof(opts));2002 opts.head_idx =1;2003 opts.src_index = &the_index;2004 opts.dst_index = &the_index;2005 opts.merge =1;2006 opts.fn = oneway_merge;2007init_tree_desc(&t[0], tree->buffer, tree->size);20082009if(unpack_trees(1, t, &opts)) {2010rollback_lock_file(&lock_file);2011return-1;2012}20132014if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))2015die(_("unable to write new index file"));20162017return0;2018}20192020/**2021 * Clean the index without touching entries that are not modified between2022 * `head` and `remote`.2023 */2024static intclean_index(const struct object_id *head,const struct object_id *remote)2025{2026struct tree *head_tree, *remote_tree, *index_tree;2027struct object_id index;20282029 head_tree =parse_tree_indirect(head);2030if(!head_tree)2031returnerror(_("Could not parse object '%s'."),oid_to_hex(head));20322033 remote_tree =parse_tree_indirect(remote);2034if(!remote_tree)2035returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));20362037read_cache_unmerged();20382039if(fast_forward_to(head_tree, head_tree,1))2040return-1;20412042if(write_cache_as_tree(&index,0, NULL))2043return-1;20442045 index_tree =parse_tree_indirect(&index);2046if(!index_tree)2047returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));20482049if(fast_forward_to(index_tree, remote_tree,0))2050return-1;20512052if(merge_tree(remote_tree))2053return-1;20542055remove_branch_state();20562057return0;2058}20592060/**2061 * Resets rerere's merge resolution metadata.2062 */2063static voidam_rerere_clear(void)2064{2065struct string_list merge_rr = STRING_LIST_INIT_DUP;2066rerere_clear(&merge_rr);2067string_list_clear(&merge_rr,1);2068}20692070/**2071 * Resume the current am session by skipping the current patch.2072 */2073static voidam_skip(struct am_state *state)2074{2075struct object_id head;20762077am_rerere_clear();20782079if(get_oid("HEAD", &head))2080oidcpy(&head, the_hash_algo->empty_tree);20812082if(clean_index(&head, &head))2083die(_("failed to clean index"));20842085am_next(state);2086am_load(state);2087am_run(state,0);2088}20892090/**2091 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2092 *2093 * It is not safe to reset HEAD when:2094 * 1. git-am previously failed because the index was dirty.2095 * 2. HEAD has moved since git-am previously failed.2096 */2097static intsafe_to_abort(const struct am_state *state)2098{2099struct strbuf sb = STRBUF_INIT;2100struct object_id abort_safety, head;21012102if(file_exists(am_path(state,"dirtyindex")))2103return0;21042105if(read_state_file(&sb, state,"abort-safety",1) >0) {2106if(get_oid_hex(sb.buf, &abort_safety))2107die(_("could not parse%s"),am_path(state,"abort-safety"));2108}else2109oidclr(&abort_safety);2110strbuf_release(&sb);21112112if(get_oid("HEAD", &head))2113oidclr(&head);21142115if(oideq(&head, &abort_safety))2116return1;21172118warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2119"Not rewinding to ORIG_HEAD"));21202121return0;2122}21232124/**2125 * Aborts the current am session if it is safe to do so.2126 */2127static voidam_abort(struct am_state *state)2128{2129struct object_id curr_head, orig_head;2130int has_curr_head, has_orig_head;2131char*curr_branch;21322133if(!safe_to_abort(state)) {2134am_destroy(state);2135return;2136}21372138am_rerere_clear();21392140 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2141 has_curr_head = curr_branch && !is_null_oid(&curr_head);2142if(!has_curr_head)2143oidcpy(&curr_head, the_hash_algo->empty_tree);21442145 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2146if(!has_orig_head)2147oidcpy(&orig_head, the_hash_algo->empty_tree);21482149clean_index(&curr_head, &orig_head);21502151if(has_orig_head)2152update_ref("am --abort","HEAD", &orig_head,2153 has_curr_head ? &curr_head : NULL,0,2154 UPDATE_REFS_DIE_ON_ERR);2155else if(curr_branch)2156delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);21572158free(curr_branch);2159am_destroy(state);2160}21612162static intshow_patch(struct am_state *state)2163{2164struct strbuf sb = STRBUF_INIT;2165const char*patch_path;2166int len;21672168if(!is_null_oid(&state->orig_commit)) {2169const char*av[4] = {"show", NULL,"--", NULL };2170char*new_oid_str;2171int ret;21722173 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2174 ret =run_command_v_opt(av, RUN_GIT_CMD);2175free(new_oid_str);2176return ret;2177}21782179 patch_path =am_path(state,msgnum(state));2180 len =strbuf_read_file(&sb, patch_path,0);2181if(len <0)2182die_errno(_("failed to read '%s'"), patch_path);21832184setup_pager();2185write_in_full(1, sb.buf, sb.len);2186strbuf_release(&sb);2187return0;2188}21892190/**2191 * parse_options() callback that validates and sets opt->value to the2192 * PATCH_FORMAT_* enum value corresponding to `arg`.2193 */2194static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2195{2196int*opt_value = opt->value;21972198if(!strcmp(arg,"mbox"))2199*opt_value = PATCH_FORMAT_MBOX;2200else if(!strcmp(arg,"stgit"))2201*opt_value = PATCH_FORMAT_STGIT;2202else if(!strcmp(arg,"stgit-series"))2203*opt_value = PATCH_FORMAT_STGIT_SERIES;2204else if(!strcmp(arg,"hg"))2205*opt_value = PATCH_FORMAT_HG;2206else if(!strcmp(arg,"mboxrd"))2207*opt_value = PATCH_FORMAT_MBOXRD;2208else2209returnerror(_("Invalid value for --patch-format:%s"), arg);2210return0;2211}22122213enum resume_mode {2214 RESUME_FALSE =0,2215 RESUME_APPLY,2216 RESUME_RESOLVED,2217 RESUME_SKIP,2218 RESUME_ABORT,2219 RESUME_QUIT,2220 RESUME_SHOW_PATCH2221};22222223static intgit_am_config(const char*k,const char*v,void*cb)2224{2225int status;22262227 status =git_gpg_config(k, v, NULL);2228if(status)2229return status;22302231returngit_default_config(k, v, NULL);2232}22332234intcmd_am(int argc,const char**argv,const char*prefix)2235{2236struct am_state state;2237int binary = -1;2238int keep_cr = -1;2239int patch_format = PATCH_FORMAT_UNKNOWN;2240enum resume_mode resume = RESUME_FALSE;2241int in_progress;2242int ret =0;22432244const char*const usage[] = {2245N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2246N_("git am [<options>] (--continue | --skip | --abort)"),2247 NULL2248};22492250struct option options[] = {2251OPT_BOOL('i',"interactive", &state.interactive,2252N_("run interactively")),2253OPT_HIDDEN_BOOL('b',"binary", &binary,2254N_("historical option -- no-op")),2255OPT_BOOL('3',"3way", &state.threeway,2256N_("allow fall back on 3way merging if needed")),2257OPT__QUIET(&state.quiet,N_("be quiet")),2258OPT_SET_INT('s',"signoff", &state.signoff,2259N_("add a Signed-off-by line to the commit message"),2260 SIGNOFF_EXPLICIT),2261OPT_BOOL('u',"utf8", &state.utf8,2262N_("recode into utf8 (default)")),2263OPT_SET_INT('k',"keep", &state.keep,2264N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2265OPT_SET_INT(0,"keep-non-patch", &state.keep,2266N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2267OPT_BOOL('m',"message-id", &state.message_id,2268N_("pass -m flag to git-mailinfo")),2269OPT_SET_INT_F(0,"keep-cr", &keep_cr,2270N_("pass --keep-cr flag to git-mailsplit for mbox format"),22711, PARSE_OPT_NONEG),2272OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2273N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),22740, PARSE_OPT_NONEG),2275OPT_BOOL('c',"scissors", &state.scissors,2276N_("strip everything before a scissors line")),2277OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2278N_("pass it through git-apply"),22790),2280OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2281N_("pass it through git-apply"),2282 PARSE_OPT_NOARG),2283OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2284N_("pass it through git-apply"),2285 PARSE_OPT_NOARG),2286OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2287N_("pass it through git-apply"),22880),2289OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2290N_("pass it through git-apply"),22910),2292OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2293N_("pass it through git-apply"),22940),2295OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2296N_("pass it through git-apply"),22970),2298OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2299N_("pass it through git-apply"),23000),2301OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2302N_("format the patch(es) are in"),2303 parse_opt_patchformat),2304OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2305N_("pass it through git-apply"),2306 PARSE_OPT_NOARG),2307OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2308N_("override error message when patch failure occurs")),2309OPT_CMDMODE(0,"continue", &resume,2310N_("continue applying patches after resolving a conflict"),2311 RESUME_RESOLVED),2312OPT_CMDMODE('r',"resolved", &resume,2313N_("synonyms for --continue"),2314 RESUME_RESOLVED),2315OPT_CMDMODE(0,"skip", &resume,2316N_("skip the current patch"),2317 RESUME_SKIP),2318OPT_CMDMODE(0,"abort", &resume,2319N_("restore the original branch and abort the patching operation."),2320 RESUME_ABORT),2321OPT_CMDMODE(0,"quit", &resume,2322N_("abort the patching operation but keep HEAD where it is."),2323 RESUME_QUIT),2324OPT_CMDMODE(0,"show-current-patch", &resume,2325N_("show the patch being applied."),2326 RESUME_SHOW_PATCH),2327OPT_BOOL(0,"committer-date-is-author-date",2328&state.committer_date_is_author_date,2329N_("lie about committer date")),2330OPT_BOOL(0,"ignore-date", &state.ignore_date,2331N_("use current timestamp for author date")),2332OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2333{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2334N_("GPG-sign commits"),2335 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2336OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2337N_("(internal use for git-rebase)")),2338OPT_END()2339};23402341if(argc ==2&& !strcmp(argv[1],"-h"))2342usage_with_options(usage, options);23432344git_config(git_am_config, NULL);23452346am_state_init(&state);23472348 in_progress =am_in_progress(&state);2349if(in_progress)2350am_load(&state);23512352 argc =parse_options(argc, argv, prefix, options, usage,0);23532354if(binary >=0)2355fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2356"it will be removed. Please do not use it anymore."));23572358/* Ensure a valid committer ident can be constructed */2359git_committer_info(IDENT_STRICT);23602361if(read_index_preload(&the_index, NULL) <0)2362die(_("failed to read the index"));23632364if(in_progress) {2365/*2366 * Catch user error to feed us patches when there is a session2367 * in progress:2368 *2369 * 1. mbox path(s) are provided on the command-line.2370 * 2. stdin is not a tty: the user is trying to feed us a patch2371 * from standard input. This is somewhat unreliable -- stdin2372 * could be /dev/null for example and the caller did not2373 * intend to feed us a patch but wanted to continue2374 * unattended.2375 */2376if(argc || (resume == RESUME_FALSE && !isatty(0)))2377die(_("previous rebase directory%sstill exists but mbox given."),2378 state.dir);23792380if(resume == RESUME_FALSE)2381 resume = RESUME_APPLY;23822383if(state.signoff == SIGNOFF_EXPLICIT)2384am_append_signoff(&state);2385}else{2386struct argv_array paths = ARGV_ARRAY_INIT;2387int i;23882389/*2390 * Handle stray state directory in the independent-run case. In2391 * the --rebasing case, it is up to the caller to take care of2392 * stray directories.2393 */2394if(file_exists(state.dir) && !state.rebasing) {2395if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2396am_destroy(&state);2397am_state_release(&state);2398return0;2399}24002401die(_("Stray%sdirectory found.\n"2402"Use\"git am --abort\"to remove it."),2403 state.dir);2404}24052406if(resume)2407die(_("Resolve operation not in progress, we are not resuming."));24082409for(i =0; i < argc; i++) {2410if(is_absolute_path(argv[i]) || !prefix)2411argv_array_push(&paths, argv[i]);2412else2413argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2414}24152416am_setup(&state, patch_format, paths.argv, keep_cr);24172418argv_array_clear(&paths);2419}24202421switch(resume) {2422case RESUME_FALSE:2423am_run(&state,0);2424break;2425case RESUME_APPLY:2426am_run(&state,1);2427break;2428case RESUME_RESOLVED:2429am_resolve(&state);2430break;2431case RESUME_SKIP:2432am_skip(&state);2433break;2434case RESUME_ABORT:2435am_abort(&state);2436break;2437case RESUME_QUIT:2438am_rerere_clear();2439am_destroy(&state);2440break;2441case RESUME_SHOW_PATCH:2442 ret =show_patch(&state);2443break;2444default:2445BUG("invalid resume value");2446}24472448am_state_release(&state);24492450return ret;2451}