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 31/** 32 * Returns 1 if the file is empty or does not exist, 0 otherwise. 33 */ 34static intis_empty_file(const char*filename) 35{ 36struct stat st; 37 38if(stat(filename, &st) <0) { 39if(errno == ENOENT) 40return1; 41die_errno(_("could not stat%s"), filename); 42} 43 44return!st.st_size; 45} 46 47/** 48 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. 49 */ 50static intstrbuf_getline_crlf(struct strbuf *sb,FILE*fp) 51{ 52if(strbuf_getwholeline(sb, fp,'\n')) 53return EOF; 54if(sb->buf[sb->len -1] =='\n') { 55strbuf_setlen(sb, sb->len -1); 56if(sb->len >0&& sb->buf[sb->len -1] =='\r') 57strbuf_setlen(sb, sb->len -1); 58} 59return0; 60} 61 62/** 63 * Returns the length of the first line of msg. 64 */ 65static intlinelen(const char*msg) 66{ 67returnstrchrnul(msg,'\n') - msg; 68} 69 70/** 71 * Returns true if `str` consists of only whitespace, false otherwise. 72 */ 73static intstr_isspace(const char*str) 74{ 75for(; *str; str++) 76if(!isspace(*str)) 77return0; 78 79return1; 80} 81 82enum patch_format { 83 PATCH_FORMAT_UNKNOWN =0, 84 PATCH_FORMAT_MBOX, 85 PATCH_FORMAT_STGIT, 86 PATCH_FORMAT_STGIT_SERIES, 87 PATCH_FORMAT_HG 88}; 89 90enum keep_type { 91 KEEP_FALSE =0, 92 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 93 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 94}; 95 96enum scissors_type { 97 SCISSORS_UNSET = -1, 98 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 99 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 100}; 101 102enum signoff_type { 103 SIGNOFF_FALSE =0, 104 SIGNOFF_TRUE =1, 105 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 106}; 107 108struct am_state { 109/* state directory path */ 110char*dir; 111 112/* current and last patch numbers, 1-indexed */ 113int cur; 114int last; 115 116/* commit metadata and message */ 117char*author_name; 118char*author_email; 119char*author_date; 120char*msg; 121size_t msg_len; 122 123/* when --rebasing, records the original commit the patch came from */ 124unsigned char orig_commit[GIT_SHA1_RAWSZ]; 125 126/* number of digits in patch filename */ 127int prec; 128 129/* various operating modes and command line options */ 130int interactive; 131int threeway; 132int quiet; 133int signoff;/* enum signoff_type */ 134int utf8; 135int keep;/* enum keep_type */ 136int message_id; 137int scissors;/* enum scissors_type */ 138struct argv_array git_apply_opts; 139const char*resolvemsg; 140int committer_date_is_author_date; 141int ignore_date; 142int allow_rerere_autoupdate; 143const char*sign_commit; 144int rebasing; 145}; 146 147/** 148 * Initializes am_state with the default values. The state directory is set to 149 * dir. 150 */ 151static voidam_state_init(struct am_state *state,const char*dir) 152{ 153int gpgsign; 154 155memset(state,0,sizeof(*state)); 156 157assert(dir); 158 state->dir =xstrdup(dir); 159 160 state->prec =4; 161 162git_config_get_bool("am.threeway", &state->threeway); 163 164 state->utf8 =1; 165 166git_config_get_bool("am.messageid", &state->message_id); 167 168 state->scissors = SCISSORS_UNSET; 169 170argv_array_init(&state->git_apply_opts); 171 172if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 173 state->sign_commit = gpgsign ?"": NULL; 174} 175 176/** 177 * Releases memory allocated by an am_state. 178 */ 179static voidam_state_release(struct am_state *state) 180{ 181free(state->dir); 182free(state->author_name); 183free(state->author_email); 184free(state->author_date); 185free(state->msg); 186argv_array_clear(&state->git_apply_opts); 187} 188 189/** 190 * Returns path relative to the am_state directory. 191 */ 192staticinlineconst char*am_path(const struct am_state *state,const char*path) 193{ 194returnmkpath("%s/%s", state->dir, path); 195} 196 197/** 198 * For convenience to call write_file() 199 */ 200static intwrite_state_text(const struct am_state *state, 201const char*name,const char*string) 202{ 203returnwrite_file(am_path(state, name),"%s", string); 204} 205 206static intwrite_state_count(const struct am_state *state, 207const char*name,int value) 208{ 209returnwrite_file(am_path(state, name),"%d", value); 210} 211 212static intwrite_state_bool(const struct am_state *state, 213const char*name,int value) 214{ 215returnwrite_state_text(state, name, value ?"t":"f"); 216} 217 218/** 219 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 220 * at the end. 221 */ 222static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 223{ 224va_list ap; 225 226va_start(ap, fmt); 227if(!state->quiet) { 228vfprintf(fp, fmt, ap); 229putc('\n', fp); 230} 231va_end(ap); 232} 233 234/** 235 * Returns 1 if there is an am session in progress, 0 otherwise. 236 */ 237static intam_in_progress(const struct am_state *state) 238{ 239struct stat st; 240 241if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 242return0; 243if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 244return0; 245if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 246return0; 247return1; 248} 249 250/** 251 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 252 * number of bytes read on success, -1 if the file does not exist. If `trim` is 253 * set, trailing whitespace will be removed. 254 */ 255static intread_state_file(struct strbuf *sb,const struct am_state *state, 256const char*file,int trim) 257{ 258strbuf_reset(sb); 259 260if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 261if(trim) 262strbuf_trim(sb); 263 264return sb->len; 265} 266 267if(errno == ENOENT) 268return-1; 269 270die_errno(_("could not read '%s'"),am_path(state, file)); 271} 272 273/** 274 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 275 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 276 * match `key`. Returns NULL on failure. 277 * 278 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 279 * the author-script. 280 */ 281static char*read_shell_var(FILE*fp,const char*key) 282{ 283struct strbuf sb = STRBUF_INIT; 284const char*str; 285 286if(strbuf_getline(&sb, fp,'\n')) 287goto fail; 288 289if(!skip_prefix(sb.buf, key, &str)) 290goto fail; 291 292if(!skip_prefix(str,"=", &str)) 293goto fail; 294 295strbuf_remove(&sb,0, str - sb.buf); 296 297 str =sq_dequote(sb.buf); 298if(!str) 299goto fail; 300 301returnstrbuf_detach(&sb, NULL); 302 303fail: 304strbuf_release(&sb); 305return NULL; 306} 307 308/** 309 * Reads and parses the state directory's "author-script" file, and sets 310 * state->author_name, state->author_email and state->author_date accordingly. 311 * Returns 0 on success, -1 if the file could not be parsed. 312 * 313 * The author script is of the format: 314 * 315 * GIT_AUTHOR_NAME='$author_name' 316 * GIT_AUTHOR_EMAIL='$author_email' 317 * GIT_AUTHOR_DATE='$author_date' 318 * 319 * where $author_name, $author_email and $author_date are quoted. We are strict 320 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 321 * script, and thus if the file differs from what this function expects, it is 322 * better to bail out than to do something that the user does not expect. 323 */ 324static intread_author_script(struct am_state *state) 325{ 326const char*filename =am_path(state,"author-script"); 327FILE*fp; 328 329assert(!state->author_name); 330assert(!state->author_email); 331assert(!state->author_date); 332 333 fp =fopen(filename,"r"); 334if(!fp) { 335if(errno == ENOENT) 336return0; 337die_errno(_("could not open '%s' for reading"), filename); 338} 339 340 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 341if(!state->author_name) { 342fclose(fp); 343return-1; 344} 345 346 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 347if(!state->author_email) { 348fclose(fp); 349return-1; 350} 351 352 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 353if(!state->author_date) { 354fclose(fp); 355return-1; 356} 357 358if(fgetc(fp) != EOF) { 359fclose(fp); 360return-1; 361} 362 363fclose(fp); 364return0; 365} 366 367/** 368 * Saves state->author_name, state->author_email and state->author_date in the 369 * state directory's "author-script" file. 370 */ 371static voidwrite_author_script(const struct am_state *state) 372{ 373struct strbuf sb = STRBUF_INIT; 374 375strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 376sq_quote_buf(&sb, state->author_name); 377strbuf_addch(&sb,'\n'); 378 379strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 380sq_quote_buf(&sb, state->author_email); 381strbuf_addch(&sb,'\n'); 382 383strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 384sq_quote_buf(&sb, state->author_date); 385strbuf_addch(&sb,'\n'); 386 387write_state_text(state,"author-script", sb.buf); 388 389strbuf_release(&sb); 390} 391 392/** 393 * Reads the commit message from the state directory's "final-commit" file, 394 * setting state->msg to its contents and state->msg_len to the length of its 395 * contents in bytes. 396 * 397 * Returns 0 on success, -1 if the file does not exist. 398 */ 399static intread_commit_msg(struct am_state *state) 400{ 401struct strbuf sb = STRBUF_INIT; 402 403assert(!state->msg); 404 405if(read_state_file(&sb, state,"final-commit",0) <0) { 406strbuf_release(&sb); 407return-1; 408} 409 410 state->msg =strbuf_detach(&sb, &state->msg_len); 411return0; 412} 413 414/** 415 * Saves state->msg in the state directory's "final-commit" file. 416 */ 417static voidwrite_commit_msg(const struct am_state *state) 418{ 419int fd; 420const char*filename =am_path(state,"final-commit"); 421 422 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 423if(write_in_full(fd, state->msg, state->msg_len) <0) 424die_errno(_("could not write to%s"), filename); 425close(fd); 426} 427 428/** 429 * Loads state from disk. 430 */ 431static voidam_load(struct am_state *state) 432{ 433struct strbuf sb = STRBUF_INIT; 434 435if(read_state_file(&sb, state,"next",1) <0) 436die("BUG: state file 'next' does not exist"); 437 state->cur =strtol(sb.buf, NULL,10); 438 439if(read_state_file(&sb, state,"last",1) <0) 440die("BUG: state file 'last' does not exist"); 441 state->last =strtol(sb.buf, NULL,10); 442 443if(read_author_script(state) <0) 444die(_("could not parse author script")); 445 446read_commit_msg(state); 447 448if(read_state_file(&sb, state,"original-commit",1) <0) 449hashclr(state->orig_commit); 450else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 451die(_("could not parse%s"),am_path(state,"original-commit")); 452 453read_state_file(&sb, state,"threeway",1); 454 state->threeway = !strcmp(sb.buf,"t"); 455 456read_state_file(&sb, state,"quiet",1); 457 state->quiet = !strcmp(sb.buf,"t"); 458 459read_state_file(&sb, state,"sign",1); 460 state->signoff = !strcmp(sb.buf,"t"); 461 462read_state_file(&sb, state,"utf8",1); 463 state->utf8 = !strcmp(sb.buf,"t"); 464 465read_state_file(&sb, state,"keep",1); 466if(!strcmp(sb.buf,"t")) 467 state->keep = KEEP_TRUE; 468else if(!strcmp(sb.buf,"b")) 469 state->keep = KEEP_NON_PATCH; 470else 471 state->keep = KEEP_FALSE; 472 473read_state_file(&sb, state,"messageid",1); 474 state->message_id = !strcmp(sb.buf,"t"); 475 476read_state_file(&sb, state,"scissors",1); 477if(!strcmp(sb.buf,"t")) 478 state->scissors = SCISSORS_TRUE; 479else if(!strcmp(sb.buf,"f")) 480 state->scissors = SCISSORS_FALSE; 481else 482 state->scissors = SCISSORS_UNSET; 483 484read_state_file(&sb, state,"apply-opt",1); 485argv_array_clear(&state->git_apply_opts); 486if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 487die(_("could not parse%s"),am_path(state,"apply-opt")); 488 489 state->rebasing = !!file_exists(am_path(state,"rebasing")); 490 491strbuf_release(&sb); 492} 493 494/** 495 * Removes the am_state directory, forcefully terminating the current am 496 * session. 497 */ 498static voidam_destroy(const struct am_state *state) 499{ 500struct strbuf sb = STRBUF_INIT; 501 502strbuf_addstr(&sb, state->dir); 503remove_dir_recursively(&sb,0); 504strbuf_release(&sb); 505} 506 507/** 508 * Runs applypatch-msg hook. Returns its exit code. 509 */ 510static intrun_applypatch_msg_hook(struct am_state *state) 511{ 512int ret; 513 514assert(state->msg); 515 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 516 517if(!ret) { 518free(state->msg); 519 state->msg = NULL; 520if(read_commit_msg(state) <0) 521die(_("'%s' was deleted by the applypatch-msg hook"), 522am_path(state,"final-commit")); 523} 524 525return ret; 526} 527 528/** 529 * Runs post-rewrite hook. Returns it exit code. 530 */ 531static intrun_post_rewrite_hook(const struct am_state *state) 532{ 533struct child_process cp = CHILD_PROCESS_INIT; 534const char*hook =find_hook("post-rewrite"); 535int ret; 536 537if(!hook) 538return0; 539 540argv_array_push(&cp.args, hook); 541argv_array_push(&cp.args,"rebase"); 542 543 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 544 cp.stdout_to_stderr =1; 545 546 ret =run_command(&cp); 547 548close(cp.in); 549return ret; 550} 551 552/** 553 * Reads the state directory's "rewritten" file, and copies notes from the old 554 * commits listed in the file to their rewritten commits. 555 * 556 * Returns 0 on success, -1 on failure. 557 */ 558static intcopy_notes_for_rebase(const struct am_state *state) 559{ 560struct notes_rewrite_cfg *c; 561struct strbuf sb = STRBUF_INIT; 562const char*invalid_line =_("Malformed input line: '%s'."); 563const char*msg ="Notes added by 'git rebase'"; 564FILE*fp; 565int ret =0; 566 567assert(state->rebasing); 568 569 c =init_copy_notes_for_rewrite("rebase"); 570if(!c) 571return0; 572 573 fp =xfopen(am_path(state,"rewritten"),"r"); 574 575while(!strbuf_getline(&sb, fp,'\n')) { 576unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 577 578if(sb.len != GIT_SHA1_HEXSZ *2+1) { 579 ret =error(invalid_line, sb.buf); 580goto finish; 581} 582 583if(get_sha1_hex(sb.buf, from_obj)) { 584 ret =error(invalid_line, sb.buf); 585goto finish; 586} 587 588if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 589 ret =error(invalid_line, sb.buf); 590goto finish; 591} 592 593if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 594 ret =error(invalid_line, sb.buf); 595goto finish; 596} 597 598if(copy_note_for_rewrite(c, from_obj, to_obj)) 599 ret =error(_("Failed to copy notes from '%s' to '%s'"), 600sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 601} 602 603finish: 604finish_copy_notes_for_rewrite(c, msg); 605fclose(fp); 606strbuf_release(&sb); 607return ret; 608} 609 610/** 611 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 612 * non-indented lines and checking if they look like they begin with valid 613 * header field names. 614 * 615 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 616 */ 617static intis_mail(FILE*fp) 618{ 619const char*header_regex ="^[!-9;-~]+:"; 620struct strbuf sb = STRBUF_INIT; 621 regex_t regex; 622int ret =1; 623 624if(fseek(fp,0L, SEEK_SET)) 625die_errno(_("fseek failed")); 626 627if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 628die("invalid pattern:%s", header_regex); 629 630while(!strbuf_getline_crlf(&sb, fp)) { 631if(!sb.len) 632break;/* End of header */ 633 634/* Ignore indented folded lines */ 635if(*sb.buf =='\t'|| *sb.buf ==' ') 636continue; 637 638/* It's a header if it matches header_regex */ 639if(regexec(®ex, sb.buf,0, NULL,0)) { 640 ret =0; 641goto done; 642} 643} 644 645done: 646regfree(®ex); 647strbuf_release(&sb); 648return ret; 649} 650 651/** 652 * Attempts to detect the patch_format of the patches contained in `paths`, 653 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 654 * detection fails. 655 */ 656static intdetect_patch_format(const char**paths) 657{ 658enum patch_format ret = PATCH_FORMAT_UNKNOWN; 659struct strbuf l1 = STRBUF_INIT; 660struct strbuf l2 = STRBUF_INIT; 661struct strbuf l3 = STRBUF_INIT; 662FILE*fp; 663 664/* 665 * We default to mbox format if input is from stdin and for directories 666 */ 667if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 668return PATCH_FORMAT_MBOX; 669 670/* 671 * Otherwise, check the first few lines of the first patch, starting 672 * from the first non-blank line, to try to detect its format. 673 */ 674 675 fp =xfopen(*paths,"r"); 676 677while(!strbuf_getline_crlf(&l1, fp)) { 678if(l1.len) 679break; 680} 681 682if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 683 ret = PATCH_FORMAT_MBOX; 684goto done; 685} 686 687if(starts_with(l1.buf,"# This series applies on GIT commit")) { 688 ret = PATCH_FORMAT_STGIT_SERIES; 689goto done; 690} 691 692if(!strcmp(l1.buf,"# HG changeset patch")) { 693 ret = PATCH_FORMAT_HG; 694goto done; 695} 696 697strbuf_reset(&l2); 698strbuf_getline_crlf(&l2, fp); 699strbuf_reset(&l3); 700strbuf_getline_crlf(&l3, fp); 701 702/* 703 * If the second line is empty and the third is a From, Author or Date 704 * entry, this is likely an StGit patch. 705 */ 706if(l1.len && !l2.len && 707(starts_with(l3.buf,"From:") || 708starts_with(l3.buf,"Author:") || 709starts_with(l3.buf,"Date:"))) { 710 ret = PATCH_FORMAT_STGIT; 711goto done; 712} 713 714if(l1.len &&is_mail(fp)) { 715 ret = PATCH_FORMAT_MBOX; 716goto done; 717} 718 719done: 720fclose(fp); 721strbuf_release(&l1); 722return ret; 723} 724 725/** 726 * Splits out individual email patches from `paths`, where each path is either 727 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 728 */ 729static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 730{ 731struct child_process cp = CHILD_PROCESS_INIT; 732struct strbuf last = STRBUF_INIT; 733 734 cp.git_cmd =1; 735argv_array_push(&cp.args,"mailsplit"); 736argv_array_pushf(&cp.args,"-d%d", state->prec); 737argv_array_pushf(&cp.args,"-o%s", state->dir); 738argv_array_push(&cp.args,"-b"); 739if(keep_cr) 740argv_array_push(&cp.args,"--keep-cr"); 741argv_array_push(&cp.args,"--"); 742argv_array_pushv(&cp.args, paths); 743 744if(capture_command(&cp, &last,8)) 745return-1; 746 747 state->cur =1; 748 state->last =strtol(last.buf, NULL,10); 749 750return0; 751} 752 753/** 754 * Callback signature for split_mail_conv(). The foreign patch should be 755 * read from `in`, and the converted patch (in RFC2822 mail format) should be 756 * written to `out`. Return 0 on success, or -1 on failure. 757 */ 758typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 759 760/** 761 * Calls `fn` for each file in `paths` to convert the foreign patch to the 762 * RFC2822 mail format suitable for parsing with git-mailinfo. 763 * 764 * Returns 0 on success, -1 on failure. 765 */ 766static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 767const char**paths,int keep_cr) 768{ 769static const char*stdin_only[] = {"-", NULL}; 770int i; 771 772if(!*paths) 773 paths = stdin_only; 774 775for(i =0; *paths; paths++, i++) { 776FILE*in, *out; 777const char*mail; 778int ret; 779 780if(!strcmp(*paths,"-")) 781 in = stdin; 782else 783 in =fopen(*paths,"r"); 784 785if(!in) 786returnerror(_("could not open '%s' for reading:%s"), 787*paths,strerror(errno)); 788 789 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 790 791 out =fopen(mail,"w"); 792if(!out) 793returnerror(_("could not open '%s' for writing:%s"), 794 mail,strerror(errno)); 795 796 ret =fn(out, in, keep_cr); 797 798fclose(out); 799fclose(in); 800 801if(ret) 802returnerror(_("could not parse patch '%s'"), *paths); 803} 804 805 state->cur =1; 806 state->last = i; 807return0; 808} 809 810/** 811 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 812 * message suitable for parsing with git-mailinfo. 813 */ 814static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 815{ 816struct strbuf sb = STRBUF_INIT; 817int subject_printed =0; 818 819while(!strbuf_getline(&sb, in,'\n')) { 820const char*str; 821 822if(str_isspace(sb.buf)) 823continue; 824else if(skip_prefix(sb.buf,"Author:", &str)) 825fprintf(out,"From:%s\n", str); 826else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 827fprintf(out,"%s\n", sb.buf); 828else if(!subject_printed) { 829fprintf(out,"Subject:%s\n", sb.buf); 830 subject_printed =1; 831}else{ 832fprintf(out,"\n%s\n", sb.buf); 833break; 834} 835} 836 837strbuf_reset(&sb); 838while(strbuf_fread(&sb,8192, in) >0) { 839fwrite(sb.buf,1, sb.len, out); 840strbuf_reset(&sb); 841} 842 843strbuf_release(&sb); 844return0; 845} 846 847/** 848 * This function only supports a single StGit series file in `paths`. 849 * 850 * Given an StGit series file, converts the StGit patches in the series into 851 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 852 * the state directory. 853 * 854 * Returns 0 on success, -1 on failure. 855 */ 856static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 857int keep_cr) 858{ 859const char*series_dir; 860char*series_dir_buf; 861FILE*fp; 862struct argv_array patches = ARGV_ARRAY_INIT; 863struct strbuf sb = STRBUF_INIT; 864int ret; 865 866if(!paths[0] || paths[1]) 867returnerror(_("Only one StGIT patch series can be applied at once")); 868 869 series_dir_buf =xstrdup(*paths); 870 series_dir =dirname(series_dir_buf); 871 872 fp =fopen(*paths,"r"); 873if(!fp) 874returnerror(_("could not open '%s' for reading:%s"), *paths, 875strerror(errno)); 876 877while(!strbuf_getline(&sb, fp,'\n')) { 878if(*sb.buf =='#') 879continue;/* skip comment lines */ 880 881argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 882} 883 884fclose(fp); 885strbuf_release(&sb); 886free(series_dir_buf); 887 888 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 889 890argv_array_clear(&patches); 891return ret; 892} 893 894/** 895 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 896 * message suitable for parsing with git-mailinfo. 897 */ 898static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 899{ 900struct strbuf sb = STRBUF_INIT; 901 902while(!strbuf_getline(&sb, in,'\n')) { 903const char*str; 904 905if(skip_prefix(sb.buf,"# User ", &str)) 906fprintf(out,"From:%s\n", str); 907else if(skip_prefix(sb.buf,"# Date ", &str)) { 908unsigned long timestamp; 909long tz, tz2; 910char*end; 911 912 errno =0; 913 timestamp =strtoul(str, &end,10); 914if(errno) 915returnerror(_("invalid timestamp")); 916 917if(!skip_prefix(end," ", &str)) 918returnerror(_("invalid Date line")); 919 920 errno =0; 921 tz =strtol(str, &end,10); 922if(errno) 923returnerror(_("invalid timezone offset")); 924 925if(*end) 926returnerror(_("invalid Date line")); 927 928/* 929 * mercurial's timezone is in seconds west of UTC, 930 * however git's timezone is in hours + minutes east of 931 * UTC. Convert it. 932 */ 933 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 934if(tz >0) 935 tz2 = -tz2; 936 937fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 938}else if(starts_with(sb.buf,"# ")) { 939continue; 940}else{ 941fprintf(out,"\n%s\n", sb.buf); 942break; 943} 944} 945 946strbuf_reset(&sb); 947while(strbuf_fread(&sb,8192, in) >0) { 948fwrite(sb.buf,1, sb.len, out); 949strbuf_reset(&sb); 950} 951 952strbuf_release(&sb); 953return0; 954} 955 956/** 957 * Splits a list of files/directories into individual email patches. Each path 958 * in `paths` must be a file/directory that is formatted according to 959 * `patch_format`. 960 * 961 * Once split out, the individual email patches will be stored in the state 962 * directory, with each patch's filename being its index, padded to state->prec 963 * digits. 964 * 965 * state->cur will be set to the index of the first mail, and state->last will 966 * be set to the index of the last mail. 967 * 968 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 969 * to disable this behavior, -1 to use the default configured setting. 970 * 971 * Returns 0 on success, -1 on failure. 972 */ 973static intsplit_mail(struct am_state *state,enum patch_format patch_format, 974const char**paths,int keep_cr) 975{ 976if(keep_cr <0) { 977 keep_cr =0; 978git_config_get_bool("am.keepcr", &keep_cr); 979} 980 981switch(patch_format) { 982case PATCH_FORMAT_MBOX: 983returnsplit_mail_mbox(state, paths, keep_cr); 984case PATCH_FORMAT_STGIT: 985returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 986case PATCH_FORMAT_STGIT_SERIES: 987returnsplit_mail_stgit_series(state, paths, keep_cr); 988case PATCH_FORMAT_HG: 989returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 990default: 991die("BUG: invalid patch_format"); 992} 993return-1; 994} 995 996/** 997 * Setup a new am session for applying patches 998 */ 999static voidam_setup(struct am_state *state,enum patch_format patch_format,1000const char**paths,int keep_cr)1001{1002unsigned char curr_head[GIT_SHA1_RAWSZ];1003const char*str;1004struct strbuf sb = STRBUF_INIT;10051006if(!patch_format)1007 patch_format =detect_patch_format(paths);10081009if(!patch_format) {1010fprintf_ln(stderr,_("Patch format detection failed."));1011exit(128);1012}10131014if(mkdir(state->dir,0777) <0&& errno != EEXIST)1015die_errno(_("failed to create directory '%s'"), state->dir);10161017if(split_mail(state, patch_format, paths, keep_cr) <0) {1018am_destroy(state);1019die(_("Failed to split patches."));1020}10211022if(state->rebasing)1023 state->threeway =1;10241025write_state_bool(state,"threeway", state->threeway);1026write_state_bool(state,"quiet", state->quiet);1027write_state_bool(state,"sign", state->signoff);1028write_state_bool(state,"utf8", state->utf8);10291030switch(state->keep) {1031case KEEP_FALSE:1032 str ="f";1033break;1034case KEEP_TRUE:1035 str ="t";1036break;1037case KEEP_NON_PATCH:1038 str ="b";1039break;1040default:1041die("BUG: invalid value for state->keep");1042}10431044write_state_text(state,"keep", str);1045write_state_bool(state,"messageid", state->message_id);10461047switch(state->scissors) {1048case SCISSORS_UNSET:1049 str ="";1050break;1051case SCISSORS_FALSE:1052 str ="f";1053break;1054case SCISSORS_TRUE:1055 str ="t";1056break;1057default:1058die("BUG: invalid value for state->scissors");1059}1060write_state_text(state,"scissors", str);10611062sq_quote_argv(&sb, state->git_apply_opts.argv,0);1063write_state_text(state,"apply-opt", sb.buf);10641065if(state->rebasing)1066write_state_text(state,"rebasing","");1067else1068write_state_text(state,"applying","");10691070if(!get_sha1("HEAD", curr_head)) {1071write_state_text(state,"abort-safety",sha1_to_hex(curr_head));1072if(!state->rebasing)1073update_ref("am","ORIG_HEAD", curr_head, NULL,0,1074 UPDATE_REFS_DIE_ON_ERR);1075}else{1076write_state_text(state,"abort-safety","");1077if(!state->rebasing)1078delete_ref("ORIG_HEAD", NULL,0);1079}10801081/*1082 * NOTE: Since the "next" and "last" files determine if an am_state1083 * session is in progress, they should be written last.1084 */10851086write_state_count(state,"next", state->cur);1087write_state_count(state,"last", state->last);10881089strbuf_release(&sb);1090}10911092/**1093 * Increments the patch pointer, and cleans am_state for the application of the1094 * next patch.1095 */1096static voidam_next(struct am_state *state)1097{1098unsigned char head[GIT_SHA1_RAWSZ];10991100free(state->author_name);1101 state->author_name = NULL;11021103free(state->author_email);1104 state->author_email = NULL;11051106free(state->author_date);1107 state->author_date = NULL;11081109free(state->msg);1110 state->msg = NULL;1111 state->msg_len =0;11121113unlink(am_path(state,"author-script"));1114unlink(am_path(state,"final-commit"));11151116hashclr(state->orig_commit);1117unlink(am_path(state,"original-commit"));11181119if(!get_sha1("HEAD", head))1120write_state_text(state,"abort-safety",sha1_to_hex(head));1121else1122write_state_text(state,"abort-safety","");11231124 state->cur++;1125write_state_count(state,"next", state->cur);1126}11271128/**1129 * Returns the filename of the current patch email.1130 */1131static const char*msgnum(const struct am_state *state)1132{1133static struct strbuf sb = STRBUF_INIT;11341135strbuf_reset(&sb);1136strbuf_addf(&sb,"%0*d", state->prec, state->cur);11371138return sb.buf;1139}11401141/**1142 * Refresh and write index.1143 */1144static voidrefresh_and_write_cache(void)1145{1146struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11471148hold_locked_index(lock_file,1);1149refresh_cache(REFRESH_QUIET);1150if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1151die(_("unable to write index file"));1152}11531154/**1155 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1156 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1157 * strbuf is provided, the space-separated list of files that differ will be1158 * appended to it.1159 */1160static intindex_has_changes(struct strbuf *sb)1161{1162unsigned char head[GIT_SHA1_RAWSZ];1163int i;11641165if(!get_sha1_tree("HEAD", head)) {1166struct diff_options opt;11671168diff_setup(&opt);1169DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1170if(!sb)1171DIFF_OPT_SET(&opt, QUICK);1172do_diff_cache(head, &opt);1173diffcore_std(&opt);1174for(i =0; sb && i < diff_queued_diff.nr; i++) {1175if(i)1176strbuf_addch(sb,' ');1177strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1178}1179diff_flush(&opt);1180returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1181}else{1182for(i =0; sb && i < active_nr; i++) {1183if(i)1184strbuf_addch(sb,' ');1185strbuf_addstr(sb, active_cache[i]->name);1186}1187return!!active_nr;1188}1189}11901191/**1192 * Dies with a user-friendly message on how to proceed after resolving the1193 * problem. This message can be overridden with state->resolvemsg.1194 */1195static void NORETURN die_user_resolve(const struct am_state *state)1196{1197if(state->resolvemsg) {1198printf_ln("%s", state->resolvemsg);1199}else{1200const char*cmdline = state->interactive ?"git am -i":"git am";12011202printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1203printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1204printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1205}12061207exit(128);1208}12091210static voidam_signoff(struct strbuf *sb)1211{1212char*cp;1213struct strbuf mine = STRBUF_INIT;12141215/* Does it end with our own sign-off? */1216strbuf_addf(&mine,"\n%s%s\n",1217 sign_off_header,1218fmt_name(getenv("GIT_COMMITTER_NAME"),1219getenv("GIT_COMMITTER_EMAIL")));1220if(mine.len < sb->len &&1221!strcmp(mine.buf, sb->buf + sb->len - mine.len))1222goto exit;/* no need to duplicate */12231224/* Does it have any Signed-off-by: in the text */1225for(cp = sb->buf;1226 cp && *cp && (cp =strstr(cp, sign_off_header)) != NULL;1227 cp =strchr(cp,'\n')) {1228if(sb->buf == cp || cp[-1] =='\n')1229break;1230}12311232strbuf_addstr(sb, mine.buf + !!cp);1233exit:1234strbuf_release(&mine);1235}12361237/**1238 * Appends signoff to the "msg" field of the am_state.1239 */1240static voidam_append_signoff(struct am_state *state)1241{1242struct strbuf sb = STRBUF_INIT;12431244strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1245am_signoff(&sb);1246 state->msg =strbuf_detach(&sb, &state->msg_len);1247}12481249/**1250 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1251 * state->msg will be set to the patch message. state->author_name,1252 * state->author_email and state->author_date will be set to the patch author's1253 * name, email and date respectively. The patch body will be written to the1254 * state directory's "patch" file.1255 *1256 * Returns 1 if the patch should be skipped, 0 otherwise.1257 */1258static intparse_mail(struct am_state *state,const char*mail)1259{1260FILE*fp;1261struct child_process cp = CHILD_PROCESS_INIT;1262struct strbuf sb = STRBUF_INIT;1263struct strbuf msg = STRBUF_INIT;1264struct strbuf author_name = STRBUF_INIT;1265struct strbuf author_date = STRBUF_INIT;1266struct strbuf author_email = STRBUF_INIT;1267int ret =0;12681269 cp.git_cmd =1;1270 cp.in =xopen(mail, O_RDONLY,0);1271 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777);12721273argv_array_push(&cp.args,"mailinfo");1274argv_array_push(&cp.args, state->utf8 ?"-u":"-n");12751276switch(state->keep) {1277case KEEP_FALSE:1278break;1279case KEEP_TRUE:1280argv_array_push(&cp.args,"-k");1281break;1282case KEEP_NON_PATCH:1283argv_array_push(&cp.args,"-b");1284break;1285default:1286die("BUG: invalid value for state->keep");1287}12881289if(state->message_id)1290argv_array_push(&cp.args,"-m");12911292switch(state->scissors) {1293case SCISSORS_UNSET:1294break;1295case SCISSORS_FALSE:1296argv_array_push(&cp.args,"--no-scissors");1297break;1298case SCISSORS_TRUE:1299argv_array_push(&cp.args,"--scissors");1300break;1301default:1302die("BUG: invalid value for state->scissors");1303}13041305argv_array_push(&cp.args,am_path(state,"msg"));1306argv_array_push(&cp.args,am_path(state,"patch"));13071308if(run_command(&cp) <0)1309die("could not parse patch");13101311close(cp.in);1312close(cp.out);13131314/* Extract message and author information */1315 fp =xfopen(am_path(state,"info"),"r");1316while(!strbuf_getline(&sb, fp,'\n')) {1317const char*x;13181319if(skip_prefix(sb.buf,"Subject: ", &x)) {1320if(msg.len)1321strbuf_addch(&msg,'\n');1322strbuf_addstr(&msg, x);1323}else if(skip_prefix(sb.buf,"Author: ", &x))1324strbuf_addstr(&author_name, x);1325else if(skip_prefix(sb.buf,"Email: ", &x))1326strbuf_addstr(&author_email, x);1327else if(skip_prefix(sb.buf,"Date: ", &x))1328strbuf_addstr(&author_date, x);1329}1330fclose(fp);13311332/* Skip pine's internal folder data */1333if(!strcmp(author_name.buf,"Mail System Internal Data")) {1334 ret =1;1335goto finish;1336}13371338if(is_empty_file(am_path(state,"patch"))) {1339printf_ln(_("Patch is empty. Was it split wrong?"));1340die_user_resolve(state);1341}13421343strbuf_addstr(&msg,"\n\n");1344if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0)1345die_errno(_("could not read '%s'"),am_path(state,"msg"));1346strbuf_stripspace(&msg,0);13471348if(state->signoff)1349am_signoff(&msg);13501351assert(!state->author_name);1352 state->author_name =strbuf_detach(&author_name, NULL);13531354assert(!state->author_email);1355 state->author_email =strbuf_detach(&author_email, NULL);13561357assert(!state->author_date);1358 state->author_date =strbuf_detach(&author_date, NULL);13591360assert(!state->msg);1361 state->msg =strbuf_detach(&msg, &state->msg_len);13621363finish:1364strbuf_release(&msg);1365strbuf_release(&author_date);1366strbuf_release(&author_email);1367strbuf_release(&author_name);1368strbuf_release(&sb);1369return ret;1370}13711372/**1373 * Sets commit_id to the commit hash where the mail was generated from.1374 * Returns 0 on success, -1 on failure.1375 */1376static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1377{1378struct strbuf sb = STRBUF_INIT;1379FILE*fp =xfopen(mail,"r");1380const char*x;13811382if(strbuf_getline(&sb, fp,'\n'))1383return-1;13841385if(!skip_prefix(sb.buf,"From ", &x))1386return-1;13871388if(get_sha1_hex(x, commit_id) <0)1389return-1;13901391strbuf_release(&sb);1392fclose(fp);1393return0;1394}13951396/**1397 * Sets state->msg, state->author_name, state->author_email, state->author_date1398 * to the commit's respective info.1399 */1400static voidget_commit_info(struct am_state *state,struct commit *commit)1401{1402const char*buffer, *ident_line, *author_date, *msg;1403size_t ident_len;1404struct ident_split ident_split;1405struct strbuf sb = STRBUF_INIT;14061407 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());14081409 ident_line =find_commit_header(buffer,"author", &ident_len);14101411if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1412strbuf_add(&sb, ident_line, ident_len);1413die(_("invalid ident line:%s"), sb.buf);1414}14151416assert(!state->author_name);1417if(ident_split.name_begin) {1418strbuf_add(&sb, ident_split.name_begin,1419 ident_split.name_end - ident_split.name_begin);1420 state->author_name =strbuf_detach(&sb, NULL);1421}else1422 state->author_name =xstrdup("");14231424assert(!state->author_email);1425if(ident_split.mail_begin) {1426strbuf_add(&sb, ident_split.mail_begin,1427 ident_split.mail_end - ident_split.mail_begin);1428 state->author_email =strbuf_detach(&sb, NULL);1429}else1430 state->author_email =xstrdup("");14311432 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1433strbuf_addstr(&sb, author_date);1434assert(!state->author_date);1435 state->author_date =strbuf_detach(&sb, NULL);14361437assert(!state->msg);1438 msg =strstr(buffer,"\n\n");1439if(!msg)1440die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1441 state->msg =xstrdup(msg +2);1442 state->msg_len =strlen(state->msg);1443}14441445/**1446 * Writes `commit` as a patch to the state directory's "patch" file.1447 */1448static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1449{1450struct rev_info rev_info;1451FILE*fp;14521453 fp =xfopen(am_path(state,"patch"),"w");1454init_revisions(&rev_info, NULL);1455 rev_info.diff =1;1456 rev_info.abbrev =0;1457 rev_info.disable_stdin =1;1458 rev_info.show_root_diff =1;1459 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1460 rev_info.no_commit_id =1;1461DIFF_OPT_SET(&rev_info.diffopt, BINARY);1462DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1463 rev_info.diffopt.use_color =0;1464 rev_info.diffopt.file = fp;1465 rev_info.diffopt.close_file =1;1466add_pending_object(&rev_info, &commit->object,"");1467diff_setup_done(&rev_info.diffopt);1468log_tree_commit(&rev_info, commit);1469}14701471/**1472 * Writes the diff of the index against HEAD as a patch to the state1473 * directory's "patch" file.1474 */1475static voidwrite_index_patch(const struct am_state *state)1476{1477struct tree *tree;1478unsigned char head[GIT_SHA1_RAWSZ];1479struct rev_info rev_info;1480FILE*fp;14811482if(!get_sha1_tree("HEAD", head))1483 tree =lookup_tree(head);1484else1485 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14861487 fp =xfopen(am_path(state,"patch"),"w");1488init_revisions(&rev_info, NULL);1489 rev_info.diff =1;1490 rev_info.disable_stdin =1;1491 rev_info.no_commit_id =1;1492 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1493 rev_info.diffopt.use_color =0;1494 rev_info.diffopt.file = fp;1495 rev_info.diffopt.close_file =1;1496add_pending_object(&rev_info, &tree->object,"");1497diff_setup_done(&rev_info.diffopt);1498run_diff_index(&rev_info,1);1499}15001501/**1502 * Like parse_mail(), but parses the mail by looking up its commit ID1503 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1504 * of patches.1505 *1506 * state->orig_commit will be set to the original commit ID.1507 *1508 * Will always return 0 as the patch should never be skipped.1509 */1510static intparse_mail_rebase(struct am_state *state,const char*mail)1511{1512struct commit *commit;1513unsigned char commit_sha1[GIT_SHA1_RAWSZ];15141515if(get_mail_commit_sha1(commit_sha1, mail) <0)1516die(_("could not parse%s"), mail);15171518 commit =lookup_commit_or_die(commit_sha1, mail);15191520get_commit_info(state, commit);15211522write_commit_patch(state, commit);15231524hashcpy(state->orig_commit, commit_sha1);1525write_state_text(state,"original-commit",sha1_to_hex(commit_sha1));15261527return0;1528}15291530/**1531 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1532 * `index_file` is not NULL, the patch will be applied to that index.1533 */1534static intrun_apply(const struct am_state *state,const char*index_file)1535{1536struct child_process cp = CHILD_PROCESS_INIT;15371538 cp.git_cmd =1;15391540if(index_file)1541argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);15421543/*1544 * If we are allowed to fall back on 3-way merge, don't give false1545 * errors during the initial attempt.1546 */1547if(state->threeway && !index_file) {1548 cp.no_stdout =1;1549 cp.no_stderr =1;1550}15511552argv_array_push(&cp.args,"apply");15531554argv_array_pushv(&cp.args, state->git_apply_opts.argv);15551556if(index_file)1557argv_array_push(&cp.args,"--cached");1558else1559argv_array_push(&cp.args,"--index");15601561argv_array_push(&cp.args,am_path(state,"patch"));15621563if(run_command(&cp))1564return-1;15651566/* Reload index as git-apply will have modified it. */1567discard_cache();1568read_cache_from(index_file ? index_file :get_index_file());15691570return0;1571}15721573/**1574 * Builds an index that contains just the blobs needed for a 3way merge.1575 */1576static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1577{1578struct child_process cp = CHILD_PROCESS_INIT;15791580 cp.git_cmd =1;1581argv_array_push(&cp.args,"apply");1582argv_array_pushv(&cp.args, state->git_apply_opts.argv);1583argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1584argv_array_push(&cp.args,am_path(state,"patch"));15851586if(run_command(&cp))1587return-1;15881589return0;1590}15911592/**1593 * Do the three-way merge using fake ancestor, his tree constructed1594 * from the fake ancestor and the postimage of the patch, and our1595 * state.1596 */1597static intrun_fallback_merge_recursive(const struct am_state *state,1598unsigned char*orig_tree,1599unsigned char*our_tree,1600unsigned char*his_tree)1601{1602struct child_process cp = CHILD_PROCESS_INIT;1603int status;16041605 cp.git_cmd =1;16061607argv_array_pushf(&cp.env_array,"GITHEAD_%s=%.*s",1608sha1_to_hex(his_tree),linelen(state->msg), state->msg);1609if(state->quiet)1610argv_array_push(&cp.env_array,"GIT_MERGE_VERBOSITY=0");16111612argv_array_push(&cp.args,"merge-recursive");1613argv_array_push(&cp.args,sha1_to_hex(orig_tree));1614argv_array_push(&cp.args,"--");1615argv_array_push(&cp.args,sha1_to_hex(our_tree));1616argv_array_push(&cp.args,sha1_to_hex(his_tree));16171618 status =run_command(&cp) ? (-1) :0;1619discard_cache();1620read_cache();1621return status;1622}16231624/**1625 * Attempt a threeway merge, using index_path as the temporary index.1626 */1627static intfall_back_threeway(const struct am_state *state,const char*index_path)1628{1629unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1630 our_tree[GIT_SHA1_RAWSZ];16311632if(get_sha1("HEAD", our_tree) <0)1633hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);16341635if(build_fake_ancestor(state, index_path))1636returnerror("could not build fake ancestor");16371638discard_cache();1639read_cache_from(index_path);16401641if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1642returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));16431644say(state, stdout,_("Using index info to reconstruct a base tree..."));16451646if(!state->quiet) {1647/*1648 * List paths that needed 3-way fallback, so that the user can1649 * review them with extra care to spot mismerges.1650 */1651struct rev_info rev_info;1652const char*diff_filter_str ="--diff-filter=AM";16531654init_revisions(&rev_info, NULL);1655 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1656diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1657add_pending_sha1(&rev_info,"HEAD", our_tree,0);1658diff_setup_done(&rev_info.diffopt);1659run_diff_index(&rev_info,1);1660}16611662if(run_apply(state, index_path))1663returnerror(_("Did you hand edit your patch?\n"1664"It does not apply to blobs recorded in its index."));16651666if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1667returnerror("could not write tree");16681669say(state, stdout,_("Falling back to patching base and 3-way merge..."));16701671discard_cache();1672read_cache();16731674/*1675 * This is not so wrong. Depending on which base we picked, orig_tree1676 * may be wildly different from ours, but his_tree has the same set of1677 * wildly different changes in parts the patch did not touch, so1678 * recursive ends up canceling them, saying that we reverted all those1679 * changes.1680 */16811682if(run_fallback_merge_recursive(state, orig_tree, our_tree, his_tree)) {1683rerere(state->allow_rerere_autoupdate);1684returnerror(_("Failed to merge in the changes."));1685}16861687return0;1688}16891690/**1691 * Commits the current index with state->msg as the commit message and1692 * state->author_name, state->author_email and state->author_date as the author1693 * information.1694 */1695static voiddo_commit(const struct am_state *state)1696{1697unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1698 commit[GIT_SHA1_RAWSZ];1699unsigned char*ptr;1700struct commit_list *parents = NULL;1701const char*reflog_msg, *author;1702struct strbuf sb = STRBUF_INIT;17031704if(run_hook_le(NULL,"pre-applypatch", NULL))1705exit(1);17061707if(write_cache_as_tree(tree,0, NULL))1708die(_("git write-tree failed to write a tree"));17091710if(!get_sha1_commit("HEAD", parent)) {1711 ptr = parent;1712commit_list_insert(lookup_commit(parent), &parents);1713}else{1714 ptr = NULL;1715say(state, stderr,_("applying to an empty history"));1716}17171718 author =fmt_ident(state->author_name, state->author_email,1719 state->ignore_date ? NULL : state->author_date,1720 IDENT_STRICT);17211722if(state->committer_date_is_author_date)1723setenv("GIT_COMMITTER_DATE",1724 state->ignore_date ?"": state->author_date,1);17251726if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1727 author, state->sign_commit))1728die(_("failed to write commit object"));17291730 reflog_msg =getenv("GIT_REFLOG_ACTION");1731if(!reflog_msg)1732 reflog_msg ="am";17331734strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1735 state->msg);17361737update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);17381739if(state->rebasing) {1740FILE*fp =xfopen(am_path(state,"rewritten"),"a");17411742assert(!is_null_sha1(state->orig_commit));1743fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1744fprintf(fp,"%s\n",sha1_to_hex(commit));1745fclose(fp);1746}17471748run_hook_le(NULL,"post-applypatch", NULL);17491750strbuf_release(&sb);1751}17521753/**1754 * Validates the am_state for resuming -- the "msg" and authorship fields must1755 * be filled up.1756 */1757static voidvalidate_resume_state(const struct am_state *state)1758{1759if(!state->msg)1760die(_("cannot resume:%sdoes not exist."),1761am_path(state,"final-commit"));17621763if(!state->author_name || !state->author_email || !state->author_date)1764die(_("cannot resume:%sdoes not exist."),1765am_path(state,"author-script"));1766}17671768/**1769 * Interactively prompt the user on whether the current patch should be1770 * applied.1771 *1772 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1773 * skip it.1774 */1775static intdo_interactive(struct am_state *state)1776{1777assert(state->msg);17781779if(!isatty(0))1780die(_("cannot be interactive without stdin connected to a terminal."));17811782for(;;) {1783const char*reply;17841785puts(_("Commit Body is:"));1786puts("--------------------------");1787printf("%s", state->msg);1788puts("--------------------------");17891790/*1791 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1792 * in your translation. The program will only accept English1793 * input at this point.1794 */1795 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17961797if(!reply) {1798continue;1799}else if(*reply =='y'|| *reply =='Y') {1800return0;1801}else if(*reply =='a'|| *reply =='A') {1802 state->interactive =0;1803return0;1804}else if(*reply =='n'|| *reply =='N') {1805return1;1806}else if(*reply =='e'|| *reply =='E') {1807struct strbuf msg = STRBUF_INIT;18081809if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1810free(state->msg);1811 state->msg =strbuf_detach(&msg, &state->msg_len);1812}1813strbuf_release(&msg);1814}else if(*reply =='v'|| *reply =='V') {1815const char*pager =git_pager(1);1816struct child_process cp = CHILD_PROCESS_INIT;18171818if(!pager)1819 pager ="cat";1820argv_array_push(&cp.args, pager);1821argv_array_push(&cp.args,am_path(state,"patch"));1822run_command(&cp);1823}1824}1825}18261827/**1828 * Applies all queued mail.1829 *1830 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1831 * well as the state directory's "patch" file is used as-is for applying the1832 * patch and committing it.1833 */1834static voidam_run(struct am_state *state,int resume)1835{1836const char*argv_gc_auto[] = {"gc","--auto", NULL};1837struct strbuf sb = STRBUF_INIT;18381839unlink(am_path(state,"dirtyindex"));18401841refresh_and_write_cache();18421843if(index_has_changes(&sb)) {1844write_state_bool(state,"dirtyindex",1);1845die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1846}18471848strbuf_release(&sb);18491850while(state->cur <= state->last) {1851const char*mail =am_path(state,msgnum(state));1852int apply_status;18531854if(!file_exists(mail))1855goto next;18561857if(resume) {1858validate_resume_state(state);1859}else{1860int skip;18611862if(state->rebasing)1863 skip =parse_mail_rebase(state, mail);1864else1865 skip =parse_mail(state, mail);18661867if(skip)1868goto next;/* mail should be skipped */18691870write_author_script(state);1871write_commit_msg(state);1872}18731874if(state->interactive &&do_interactive(state))1875goto next;18761877if(run_applypatch_msg_hook(state))1878exit(1);18791880say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18811882 apply_status =run_apply(state, NULL);18831884if(apply_status && state->threeway) {1885struct strbuf sb = STRBUF_INIT;18861887strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1888 apply_status =fall_back_threeway(state, sb.buf);1889strbuf_release(&sb);18901891/*1892 * Applying the patch to an earlier tree and merging1893 * the result may have produced the same tree as ours.1894 */1895if(!apply_status && !index_has_changes(NULL)) {1896say(state, stdout,_("No changes -- Patch already applied."));1897goto next;1898}1899}19001901if(apply_status) {1902int advice_amworkdir =1;19031904printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1905linelen(state->msg), state->msg);19061907git_config_get_bool("advice.amworkdir", &advice_amworkdir);19081909if(advice_amworkdir)1910printf_ln(_("The copy of the patch that failed is found in:%s"),1911am_path(state,"patch"));19121913die_user_resolve(state);1914}19151916do_commit(state);19171918next:1919am_next(state);19201921if(resume)1922am_load(state);1923 resume =0;1924}19251926if(!is_empty_file(am_path(state,"rewritten"))) {1927assert(state->rebasing);1928copy_notes_for_rebase(state);1929run_post_rewrite_hook(state);1930}19311932/*1933 * In rebasing mode, it's up to the caller to take care of1934 * housekeeping.1935 */1936if(!state->rebasing) {1937am_destroy(state);1938run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1939}1940}19411942/**1943 * Resume the current am session after patch application failure. The user did1944 * all the hard work, and we do not have to do any patch application. Just1945 * trust and commit what the user has in the index and working tree.1946 */1947static voidam_resolve(struct am_state *state)1948{1949validate_resume_state(state);19501951say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);19521953if(!index_has_changes(NULL)) {1954printf_ln(_("No changes - did you forget to use 'git add'?\n"1955"If there is nothing left to stage, chances are that something else\n"1956"already introduced the same changes; you might want to skip this patch."));1957die_user_resolve(state);1958}19591960if(unmerged_cache()) {1961printf_ln(_("You still have unmerged paths in your index.\n"1962"Did you forget to use 'git add'?"));1963die_user_resolve(state);1964}19651966if(state->interactive) {1967write_index_patch(state);1968if(do_interactive(state))1969goto next;1970}19711972rerere(0);19731974do_commit(state);19751976next:1977am_next(state);1978am_load(state);1979am_run(state,0);1980}19811982/**1983 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1984 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1985 * failure.1986 */1987static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1988{1989struct lock_file *lock_file;1990struct unpack_trees_options opts;1991struct tree_desc t[2];19921993if(parse_tree(head) ||parse_tree(remote))1994return-1;19951996 lock_file =xcalloc(1,sizeof(struct lock_file));1997hold_locked_index(lock_file,1);19981999refresh_cache(REFRESH_QUIET);20002001memset(&opts,0,sizeof(opts));2002 opts.head_idx =1;2003 opts.src_index = &the_index;2004 opts.dst_index = &the_index;2005 opts.update =1;2006 opts.merge =1;2007 opts.reset = reset;2008 opts.fn = twoway_merge;2009init_tree_desc(&t[0], head->buffer, head->size);2010init_tree_desc(&t[1], remote->buffer, remote->size);20112012if(unpack_trees(2, t, &opts)) {2013rollback_lock_file(lock_file);2014return-1;2015}20162017if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2018die(_("unable to write new index file"));20192020return0;2021}20222023/**2024 * Merges a tree into the index. The index's stat info will take precedence2025 * over the merged tree's. Returns 0 on success, -1 on failure.2026 */2027static intmerge_tree(struct tree *tree)2028{2029struct lock_file *lock_file;2030struct unpack_trees_options opts;2031struct tree_desc t[1];20322033if(parse_tree(tree))2034return-1;20352036 lock_file =xcalloc(1,sizeof(struct lock_file));2037hold_locked_index(lock_file,1);20382039memset(&opts,0,sizeof(opts));2040 opts.head_idx =1;2041 opts.src_index = &the_index;2042 opts.dst_index = &the_index;2043 opts.merge =1;2044 opts.fn = oneway_merge;2045init_tree_desc(&t[0], tree->buffer, tree->size);20462047if(unpack_trees(1, t, &opts)) {2048rollback_lock_file(lock_file);2049return-1;2050}20512052if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2053die(_("unable to write new index file"));20542055return0;2056}20572058/**2059 * Clean the index without touching entries that are not modified between2060 * `head` and `remote`.2061 */2062static intclean_index(const unsigned char*head,const unsigned char*remote)2063{2064struct tree *head_tree, *remote_tree, *index_tree;2065unsigned char index[GIT_SHA1_RAWSZ];20662067 head_tree =parse_tree_indirect(head);2068if(!head_tree)2069returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));20702071 remote_tree =parse_tree_indirect(remote);2072if(!remote_tree)2073returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));20742075read_cache_unmerged();20762077if(fast_forward_to(head_tree, head_tree,1))2078return-1;20792080if(write_cache_as_tree(index,0, NULL))2081return-1;20822083 index_tree =parse_tree_indirect(index);2084if(!index_tree)2085returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));20862087if(fast_forward_to(index_tree, remote_tree,0))2088return-1;20892090if(merge_tree(remote_tree))2091return-1;20922093remove_branch_state();20942095return0;2096}20972098/**2099 * Resets rerere's merge resolution metadata.2100 */2101static voidam_rerere_clear(void)2102{2103struct string_list merge_rr = STRING_LIST_INIT_DUP;2104rerere_clear(&merge_rr);2105string_list_clear(&merge_rr,1);2106}21072108/**2109 * Resume the current am session by skipping the current patch.2110 */2111static voidam_skip(struct am_state *state)2112{2113unsigned char head[GIT_SHA1_RAWSZ];21142115am_rerere_clear();21162117if(get_sha1("HEAD", head))2118hashcpy(head, EMPTY_TREE_SHA1_BIN);21192120if(clean_index(head, head))2121die(_("failed to clean index"));21222123am_next(state);2124am_load(state);2125am_run(state,0);2126}21272128/**2129 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2130 *2131 * It is not safe to reset HEAD when:2132 * 1. git-am previously failed because the index was dirty.2133 * 2. HEAD has moved since git-am previously failed.2134 */2135static intsafe_to_abort(const struct am_state *state)2136{2137struct strbuf sb = STRBUF_INIT;2138unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];21392140if(file_exists(am_path(state,"dirtyindex")))2141return0;21422143if(read_state_file(&sb, state,"abort-safety",1) >0) {2144if(get_sha1_hex(sb.buf, abort_safety))2145die(_("could not parse%s"),am_path(state,"abort_safety"));2146}else2147hashclr(abort_safety);21482149if(get_sha1("HEAD", head))2150hashclr(head);21512152if(!hashcmp(head, abort_safety))2153return1;21542155error(_("You seem to have moved HEAD since the last 'am' failure.\n"2156"Not rewinding to ORIG_HEAD"));21572158return0;2159}21602161/**2162 * Aborts the current am session if it is safe to do so.2163 */2164static voidam_abort(struct am_state *state)2165{2166unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2167int has_curr_head, has_orig_head;2168char*curr_branch;21692170if(!safe_to_abort(state)) {2171am_destroy(state);2172return;2173}21742175am_rerere_clear();21762177 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2178 has_curr_head = !is_null_sha1(curr_head);2179if(!has_curr_head)2180hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);21812182 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2183if(!has_orig_head)2184hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);21852186clean_index(curr_head, orig_head);21872188if(has_orig_head)2189update_ref("am --abort","HEAD", orig_head,2190 has_curr_head ? curr_head : NULL,0,2191 UPDATE_REFS_DIE_ON_ERR);2192else if(curr_branch)2193delete_ref(curr_branch, NULL, REF_NODEREF);21942195free(curr_branch);2196am_destroy(state);2197}21982199/**2200 * parse_options() callback that validates and sets opt->value to the2201 * PATCH_FORMAT_* enum value corresponding to `arg`.2202 */2203static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2204{2205int*opt_value = opt->value;22062207if(!strcmp(arg,"mbox"))2208*opt_value = PATCH_FORMAT_MBOX;2209else if(!strcmp(arg,"stgit"))2210*opt_value = PATCH_FORMAT_STGIT;2211else if(!strcmp(arg,"stgit-series"))2212*opt_value = PATCH_FORMAT_STGIT_SERIES;2213else if(!strcmp(arg,"hg"))2214*opt_value = PATCH_FORMAT_HG;2215else2216returnerror(_("Invalid value for --patch-format:%s"), arg);2217return0;2218}22192220enum resume_mode {2221 RESUME_FALSE =0,2222 RESUME_APPLY,2223 RESUME_RESOLVED,2224 RESUME_SKIP,2225 RESUME_ABORT2226};22272228static intgit_am_config(const char*k,const char*v,void*cb)2229{2230int status;22312232 status =git_gpg_config(k, v, NULL);2233if(status)2234return status;22352236returngit_default_config(k, v, NULL);2237}22382239intcmd_am(int argc,const char**argv,const char*prefix)2240{2241struct am_state state;2242int binary = -1;2243int keep_cr = -1;2244int patch_format = PATCH_FORMAT_UNKNOWN;2245enum resume_mode resume = RESUME_FALSE;2246int in_progress;22472248const char*const usage[] = {2249N_("git am [<options>] [(<mbox>|<Maildir>)...]"),2250N_("git am [<options>] (--continue | --skip | --abort)"),2251 NULL2252};22532254struct option options[] = {2255OPT_BOOL('i',"interactive", &state.interactive,2256N_("run interactively")),2257OPT_HIDDEN_BOOL('b',"binary", &binary,2258N_("historical option -- no-op")),2259OPT_BOOL('3',"3way", &state.threeway,2260N_("allow fall back on 3way merging if needed")),2261OPT__QUIET(&state.quiet,N_("be quiet")),2262OPT_SET_INT('s',"signoff", &state.signoff,2263N_("add a Signed-off-by line to the commit message"),2264 SIGNOFF_EXPLICIT),2265OPT_BOOL('u',"utf8", &state.utf8,2266N_("recode into utf8 (default)")),2267OPT_SET_INT('k',"keep", &state.keep,2268N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2269OPT_SET_INT(0,"keep-non-patch", &state.keep,2270N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2271OPT_BOOL('m',"message-id", &state.message_id,2272N_("pass -m flag to git-mailinfo")),2273{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2274N_("pass --keep-cr flag to git-mailsplit for mbox format"),2275 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2276{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2277N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2278 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2279OPT_BOOL('c',"scissors", &state.scissors,2280N_("strip everything before a scissors line")),2281OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2282N_("pass it through git-apply"),22830),2284OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2285N_("pass it through git-apply"),2286 PARSE_OPT_NOARG),2287OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2288N_("pass it through git-apply"),2289 PARSE_OPT_NOARG),2290OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2291N_("pass it through git-apply"),22920),2293OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2294N_("pass it through git-apply"),22950),2296OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2297N_("pass it through git-apply"),22980),2299OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2300N_("pass it through git-apply"),23010),2302OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2303N_("pass it through git-apply"),23040),2305OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2306N_("format the patch(es) are in"),2307 parse_opt_patchformat),2308OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2309N_("pass it through git-apply"),2310 PARSE_OPT_NOARG),2311OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2312N_("override error message when patch failure occurs")),2313OPT_CMDMODE(0,"continue", &resume,2314N_("continue applying patches after resolving a conflict"),2315 RESUME_RESOLVED),2316OPT_CMDMODE('r',"resolved", &resume,2317N_("synonyms for --continue"),2318 RESUME_RESOLVED),2319OPT_CMDMODE(0,"skip", &resume,2320N_("skip the current patch"),2321 RESUME_SKIP),2322OPT_CMDMODE(0,"abort", &resume,2323N_("restore the original branch and abort the patching operation."),2324 RESUME_ABORT),2325OPT_BOOL(0,"committer-date-is-author-date",2326&state.committer_date_is_author_date,2327N_("lie about committer date")),2328OPT_BOOL(0,"ignore-date", &state.ignore_date,2329N_("use current timestamp for author date")),2330OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2331{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2332N_("GPG-sign commits"),2333 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2334OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2335N_("(internal use for git-rebase)")),2336OPT_END()2337};23382339git_config(git_am_config, NULL);23402341am_state_init(&state,git_path("rebase-apply"));23422343 in_progress =am_in_progress(&state);2344if(in_progress)2345am_load(&state);23462347 argc =parse_options(argc, argv, prefix, options, usage,0);23482349if(binary >=0)2350fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2351"it will be removed. Please do not use it anymore."));23522353/* Ensure a valid committer ident can be constructed */2354git_committer_info(IDENT_STRICT);23552356if(read_index_preload(&the_index, NULL) <0)2357die(_("failed to read the index"));23582359if(in_progress) {2360/*2361 * Catch user error to feed us patches when there is a session2362 * in progress:2363 *2364 * 1. mbox path(s) are provided on the command-line.2365 * 2. stdin is not a tty: the user is trying to feed us a patch2366 * from standard input. This is somewhat unreliable -- stdin2367 * could be /dev/null for example and the caller did not2368 * intend to feed us a patch but wanted to continue2369 * unattended.2370 */2371if(argc || (resume == RESUME_FALSE && !isatty(0)))2372die(_("previous rebase directory%sstill exists but mbox given."),2373 state.dir);23742375if(resume == RESUME_FALSE)2376 resume = RESUME_APPLY;23772378if(state.signoff == SIGNOFF_EXPLICIT)2379am_append_signoff(&state);2380}else{2381struct argv_array paths = ARGV_ARRAY_INIT;2382int i;23832384/*2385 * Handle stray state directory in the independent-run case. In2386 * the --rebasing case, it is up to the caller to take care of2387 * stray directories.2388 */2389if(file_exists(state.dir) && !state.rebasing) {2390if(resume == RESUME_ABORT) {2391am_destroy(&state);2392am_state_release(&state);2393return0;2394}23952396die(_("Stray%sdirectory found.\n"2397"Use\"git am --abort\"to remove it."),2398 state.dir);2399}24002401if(resume)2402die(_("Resolve operation not in progress, we are not resuming."));24032404for(i =0; i < argc; i++) {2405if(is_absolute_path(argv[i]) || !prefix)2406argv_array_push(&paths, argv[i]);2407else2408argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2409}24102411am_setup(&state, patch_format, paths.argv, keep_cr);24122413argv_array_clear(&paths);2414}24152416switch(resume) {2417case RESUME_FALSE:2418am_run(&state,0);2419break;2420case RESUME_APPLY:2421am_run(&state,1);2422break;2423case RESUME_RESOLVED:2424am_resolve(&state);2425break;2426case RESUME_SKIP:2427am_skip(&state);2428break;2429case RESUME_ABORT:2430am_abort(&state);2431break;2432default:2433die("BUG: invalid resume value");2434}24352436am_state_release(&state);24372438return0;2439}