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"lockfile.h" 14#include"cache-tree.h" 15#include"refs.h" 16#include"commit.h" 17#include"diff.h" 18#include"diffcore.h" 19#include"unpack-trees.h" 20#include"branch.h" 21#include"sequencer.h" 22#include"revision.h" 23#include"merge-recursive.h" 24#include"revision.h" 25#include"log-tree.h" 26 27/** 28 * Returns 1 if the file is empty or does not exist, 0 otherwise. 29 */ 30static intis_empty_file(const char*filename) 31{ 32struct stat st; 33 34if(stat(filename, &st) <0) { 35if(errno == ENOENT) 36return1; 37die_errno(_("could not stat%s"), filename); 38} 39 40return!st.st_size; 41} 42 43/** 44 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. 45 */ 46static intstrbuf_getline_crlf(struct strbuf *sb,FILE*fp) 47{ 48if(strbuf_getwholeline(sb, fp,'\n')) 49return EOF; 50if(sb->buf[sb->len -1] =='\n') { 51strbuf_setlen(sb, sb->len -1); 52if(sb->len >0&& sb->buf[sb->len -1] =='\r') 53strbuf_setlen(sb, sb->len -1); 54} 55return0; 56} 57 58/** 59 * Returns the length of the first line of msg. 60 */ 61static intlinelen(const char*msg) 62{ 63returnstrchrnul(msg,'\n') - msg; 64} 65 66enum patch_format { 67 PATCH_FORMAT_UNKNOWN =0, 68 PATCH_FORMAT_MBOX 69}; 70 71enum keep_type { 72 KEEP_FALSE =0, 73 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 74 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 75}; 76 77enum scissors_type { 78 SCISSORS_UNSET = -1, 79 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 80 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 81}; 82 83struct am_state { 84/* state directory path */ 85char*dir; 86 87/* current and last patch numbers, 1-indexed */ 88int cur; 89int last; 90 91/* commit metadata and message */ 92char*author_name; 93char*author_email; 94char*author_date; 95char*msg; 96size_t msg_len; 97 98/* number of digits in patch filename */ 99int prec; 100 101/* various operating modes and command line options */ 102int threeway; 103int quiet; 104int signoff; 105int utf8; 106int keep;/* enum keep_type */ 107int message_id; 108int scissors;/* enum scissors_type */ 109const char*resolvemsg; 110int rebasing; 111}; 112 113/** 114 * Initializes am_state with the default values. The state directory is set to 115 * dir. 116 */ 117static voidam_state_init(struct am_state *state,const char*dir) 118{ 119memset(state,0,sizeof(*state)); 120 121assert(dir); 122 state->dir =xstrdup(dir); 123 124 state->prec =4; 125 126 state->utf8 =1; 127 128git_config_get_bool("am.messageid", &state->message_id); 129 130 state->scissors = SCISSORS_UNSET; 131} 132 133/** 134 * Releases memory allocated by an am_state. 135 */ 136static voidam_state_release(struct am_state *state) 137{ 138free(state->dir); 139free(state->author_name); 140free(state->author_email); 141free(state->author_date); 142free(state->msg); 143} 144 145/** 146 * Returns path relative to the am_state directory. 147 */ 148staticinlineconst char*am_path(const struct am_state *state,const char*path) 149{ 150returnmkpath("%s/%s", state->dir, path); 151} 152 153/** 154 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 155 * at the end. 156 */ 157static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 158{ 159va_list ap; 160 161va_start(ap, fmt); 162if(!state->quiet) { 163vfprintf(fp, fmt, ap); 164putc('\n', fp); 165} 166va_end(ap); 167} 168 169/** 170 * Returns 1 if there is an am session in progress, 0 otherwise. 171 */ 172static intam_in_progress(const struct am_state *state) 173{ 174struct stat st; 175 176if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 177return0; 178if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 179return0; 180if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 181return0; 182return1; 183} 184 185/** 186 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 187 * number of bytes read on success, -1 if the file does not exist. If `trim` is 188 * set, trailing whitespace will be removed. 189 */ 190static intread_state_file(struct strbuf *sb,const struct am_state *state, 191const char*file,int trim) 192{ 193strbuf_reset(sb); 194 195if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 196if(trim) 197strbuf_trim(sb); 198 199return sb->len; 200} 201 202if(errno == ENOENT) 203return-1; 204 205die_errno(_("could not read '%s'"),am_path(state, file)); 206} 207 208/** 209 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 210 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 211 * match `key`. Returns NULL on failure. 212 * 213 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 214 * the author-script. 215 */ 216static char*read_shell_var(FILE*fp,const char*key) 217{ 218struct strbuf sb = STRBUF_INIT; 219const char*str; 220 221if(strbuf_getline(&sb, fp,'\n')) 222goto fail; 223 224if(!skip_prefix(sb.buf, key, &str)) 225goto fail; 226 227if(!skip_prefix(str,"=", &str)) 228goto fail; 229 230strbuf_remove(&sb,0, str - sb.buf); 231 232 str =sq_dequote(sb.buf); 233if(!str) 234goto fail; 235 236returnstrbuf_detach(&sb, NULL); 237 238fail: 239strbuf_release(&sb); 240return NULL; 241} 242 243/** 244 * Reads and parses the state directory's "author-script" file, and sets 245 * state->author_name, state->author_email and state->author_date accordingly. 246 * Returns 0 on success, -1 if the file could not be parsed. 247 * 248 * The author script is of the format: 249 * 250 * GIT_AUTHOR_NAME='$author_name' 251 * GIT_AUTHOR_EMAIL='$author_email' 252 * GIT_AUTHOR_DATE='$author_date' 253 * 254 * where $author_name, $author_email and $author_date are quoted. We are strict 255 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 256 * script, and thus if the file differs from what this function expects, it is 257 * better to bail out than to do something that the user does not expect. 258 */ 259static intread_author_script(struct am_state *state) 260{ 261const char*filename =am_path(state,"author-script"); 262FILE*fp; 263 264assert(!state->author_name); 265assert(!state->author_email); 266assert(!state->author_date); 267 268 fp =fopen(filename,"r"); 269if(!fp) { 270if(errno == ENOENT) 271return0; 272die_errno(_("could not open '%s' for reading"), filename); 273} 274 275 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 276if(!state->author_name) { 277fclose(fp); 278return-1; 279} 280 281 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 282if(!state->author_email) { 283fclose(fp); 284return-1; 285} 286 287 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 288if(!state->author_date) { 289fclose(fp); 290return-1; 291} 292 293if(fgetc(fp) != EOF) { 294fclose(fp); 295return-1; 296} 297 298fclose(fp); 299return0; 300} 301 302/** 303 * Saves state->author_name, state->author_email and state->author_date in the 304 * state directory's "author-script" file. 305 */ 306static voidwrite_author_script(const struct am_state *state) 307{ 308struct strbuf sb = STRBUF_INIT; 309 310strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 311sq_quote_buf(&sb, state->author_name); 312strbuf_addch(&sb,'\n'); 313 314strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 315sq_quote_buf(&sb, state->author_email); 316strbuf_addch(&sb,'\n'); 317 318strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 319sq_quote_buf(&sb, state->author_date); 320strbuf_addch(&sb,'\n'); 321 322write_file(am_path(state,"author-script"),1,"%s", sb.buf); 323 324strbuf_release(&sb); 325} 326 327/** 328 * Reads the commit message from the state directory's "final-commit" file, 329 * setting state->msg to its contents and state->msg_len to the length of its 330 * contents in bytes. 331 * 332 * Returns 0 on success, -1 if the file does not exist. 333 */ 334static intread_commit_msg(struct am_state *state) 335{ 336struct strbuf sb = STRBUF_INIT; 337 338assert(!state->msg); 339 340if(read_state_file(&sb, state,"final-commit",0) <0) { 341strbuf_release(&sb); 342return-1; 343} 344 345 state->msg =strbuf_detach(&sb, &state->msg_len); 346return0; 347} 348 349/** 350 * Saves state->msg in the state directory's "final-commit" file. 351 */ 352static voidwrite_commit_msg(const struct am_state *state) 353{ 354int fd; 355const char*filename =am_path(state,"final-commit"); 356 357 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 358if(write_in_full(fd, state->msg, state->msg_len) <0) 359die_errno(_("could not write to%s"), filename); 360close(fd); 361} 362 363/** 364 * Loads state from disk. 365 */ 366static voidam_load(struct am_state *state) 367{ 368struct strbuf sb = STRBUF_INIT; 369 370if(read_state_file(&sb, state,"next",1) <0) 371die("BUG: state file 'next' does not exist"); 372 state->cur =strtol(sb.buf, NULL,10); 373 374if(read_state_file(&sb, state,"last",1) <0) 375die("BUG: state file 'last' does not exist"); 376 state->last =strtol(sb.buf, NULL,10); 377 378if(read_author_script(state) <0) 379die(_("could not parse author script")); 380 381read_commit_msg(state); 382 383read_state_file(&sb, state,"threeway",1); 384 state->threeway = !strcmp(sb.buf,"t"); 385 386read_state_file(&sb, state,"quiet",1); 387 state->quiet = !strcmp(sb.buf,"t"); 388 389read_state_file(&sb, state,"sign",1); 390 state->signoff = !strcmp(sb.buf,"t"); 391 392read_state_file(&sb, state,"utf8",1); 393 state->utf8 = !strcmp(sb.buf,"t"); 394 395read_state_file(&sb, state,"keep",1); 396if(!strcmp(sb.buf,"t")) 397 state->keep = KEEP_TRUE; 398else if(!strcmp(sb.buf,"b")) 399 state->keep = KEEP_NON_PATCH; 400else 401 state->keep = KEEP_FALSE; 402 403read_state_file(&sb, state,"messageid",1); 404 state->message_id = !strcmp(sb.buf,"t"); 405 406read_state_file(&sb, state,"scissors",1); 407if(!strcmp(sb.buf,"t")) 408 state->scissors = SCISSORS_TRUE; 409else if(!strcmp(sb.buf,"f")) 410 state->scissors = SCISSORS_FALSE; 411else 412 state->scissors = SCISSORS_UNSET; 413 414 state->rebasing = !!file_exists(am_path(state,"rebasing")); 415 416strbuf_release(&sb); 417} 418 419/** 420 * Removes the am_state directory, forcefully terminating the current am 421 * session. 422 */ 423static voidam_destroy(const struct am_state *state) 424{ 425struct strbuf sb = STRBUF_INIT; 426 427strbuf_addstr(&sb, state->dir); 428remove_dir_recursively(&sb,0); 429strbuf_release(&sb); 430} 431 432/** 433 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 434 * non-indented lines and checking if they look like they begin with valid 435 * header field names. 436 * 437 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 438 */ 439static intis_mail(FILE*fp) 440{ 441const char*header_regex ="^[!-9;-~]+:"; 442struct strbuf sb = STRBUF_INIT; 443 regex_t regex; 444int ret =1; 445 446if(fseek(fp,0L, SEEK_SET)) 447die_errno(_("fseek failed")); 448 449if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 450die("invalid pattern:%s", header_regex); 451 452while(!strbuf_getline_crlf(&sb, fp)) { 453if(!sb.len) 454break;/* End of header */ 455 456/* Ignore indented folded lines */ 457if(*sb.buf =='\t'|| *sb.buf ==' ') 458continue; 459 460/* It's a header if it matches header_regex */ 461if(regexec(®ex, sb.buf,0, NULL,0)) { 462 ret =0; 463goto done; 464} 465} 466 467done: 468regfree(®ex); 469strbuf_release(&sb); 470return ret; 471} 472 473/** 474 * Attempts to detect the patch_format of the patches contained in `paths`, 475 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 476 * detection fails. 477 */ 478static intdetect_patch_format(const char**paths) 479{ 480enum patch_format ret = PATCH_FORMAT_UNKNOWN; 481struct strbuf l1 = STRBUF_INIT; 482FILE*fp; 483 484/* 485 * We default to mbox format if input is from stdin and for directories 486 */ 487if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 488return PATCH_FORMAT_MBOX; 489 490/* 491 * Otherwise, check the first few lines of the first patch, starting 492 * from the first non-blank line, to try to detect its format. 493 */ 494 495 fp =xfopen(*paths,"r"); 496 497while(!strbuf_getline_crlf(&l1, fp)) { 498if(l1.len) 499break; 500} 501 502if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 503 ret = PATCH_FORMAT_MBOX; 504goto done; 505} 506 507if(l1.len &&is_mail(fp)) { 508 ret = PATCH_FORMAT_MBOX; 509goto done; 510} 511 512done: 513fclose(fp); 514strbuf_release(&l1); 515return ret; 516} 517 518/** 519 * Splits out individual email patches from `paths`, where each path is either 520 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 521 */ 522static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 523{ 524struct child_process cp = CHILD_PROCESS_INIT; 525struct strbuf last = STRBUF_INIT; 526 527 cp.git_cmd =1; 528argv_array_push(&cp.args,"mailsplit"); 529argv_array_pushf(&cp.args,"-d%d", state->prec); 530argv_array_pushf(&cp.args,"-o%s", state->dir); 531argv_array_push(&cp.args,"-b"); 532if(keep_cr) 533argv_array_push(&cp.args,"--keep-cr"); 534argv_array_push(&cp.args,"--"); 535argv_array_pushv(&cp.args, paths); 536 537if(capture_command(&cp, &last,8)) 538return-1; 539 540 state->cur =1; 541 state->last =strtol(last.buf, NULL,10); 542 543return0; 544} 545 546/** 547 * Splits a list of files/directories into individual email patches. Each path 548 * in `paths` must be a file/directory that is formatted according to 549 * `patch_format`. 550 * 551 * Once split out, the individual email patches will be stored in the state 552 * directory, with each patch's filename being its index, padded to state->prec 553 * digits. 554 * 555 * state->cur will be set to the index of the first mail, and state->last will 556 * be set to the index of the last mail. 557 * 558 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 559 * to disable this behavior, -1 to use the default configured setting. 560 * 561 * Returns 0 on success, -1 on failure. 562 */ 563static intsplit_mail(struct am_state *state,enum patch_format patch_format, 564const char**paths,int keep_cr) 565{ 566if(keep_cr <0) { 567 keep_cr =0; 568git_config_get_bool("am.keepcr", &keep_cr); 569} 570 571switch(patch_format) { 572case PATCH_FORMAT_MBOX: 573returnsplit_mail_mbox(state, paths, keep_cr); 574default: 575die("BUG: invalid patch_format"); 576} 577return-1; 578} 579 580/** 581 * Setup a new am session for applying patches 582 */ 583static voidam_setup(struct am_state *state,enum patch_format patch_format, 584const char**paths,int keep_cr) 585{ 586unsigned char curr_head[GIT_SHA1_RAWSZ]; 587const char*str; 588 589if(!patch_format) 590 patch_format =detect_patch_format(paths); 591 592if(!patch_format) { 593fprintf_ln(stderr,_("Patch format detection failed.")); 594exit(128); 595} 596 597if(mkdir(state->dir,0777) <0&& errno != EEXIST) 598die_errno(_("failed to create directory '%s'"), state->dir); 599 600if(split_mail(state, patch_format, paths, keep_cr) <0) { 601am_destroy(state); 602die(_("Failed to split patches.")); 603} 604 605if(state->rebasing) 606 state->threeway =1; 607 608write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f"); 609 610write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f"); 611 612write_file(am_path(state,"sign"),1, state->signoff ?"t":"f"); 613 614write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f"); 615 616switch(state->keep) { 617case KEEP_FALSE: 618 str ="f"; 619break; 620case KEEP_TRUE: 621 str ="t"; 622break; 623case KEEP_NON_PATCH: 624 str ="b"; 625break; 626default: 627die("BUG: invalid value for state->keep"); 628} 629 630write_file(am_path(state,"keep"),1,"%s", str); 631 632write_file(am_path(state,"messageid"),1, state->message_id ?"t":"f"); 633 634switch(state->scissors) { 635case SCISSORS_UNSET: 636 str =""; 637break; 638case SCISSORS_FALSE: 639 str ="f"; 640break; 641case SCISSORS_TRUE: 642 str ="t"; 643break; 644default: 645die("BUG: invalid value for state->scissors"); 646} 647 648write_file(am_path(state,"scissors"),1,"%s", str); 649 650if(state->rebasing) 651write_file(am_path(state,"rebasing"),1,"%s",""); 652else 653write_file(am_path(state,"applying"),1,"%s",""); 654 655if(!get_sha1("HEAD", curr_head)) { 656write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head)); 657if(!state->rebasing) 658update_ref("am","ORIG_HEAD", curr_head, NULL,0, 659 UPDATE_REFS_DIE_ON_ERR); 660}else{ 661write_file(am_path(state,"abort-safety"),1,"%s",""); 662if(!state->rebasing) 663delete_ref("ORIG_HEAD", NULL,0); 664} 665 666/* 667 * NOTE: Since the "next" and "last" files determine if an am_state 668 * session is in progress, they should be written last. 669 */ 670 671write_file(am_path(state,"next"),1,"%d", state->cur); 672 673write_file(am_path(state,"last"),1,"%d", state->last); 674} 675 676/** 677 * Increments the patch pointer, and cleans am_state for the application of the 678 * next patch. 679 */ 680static voidam_next(struct am_state *state) 681{ 682unsigned char head[GIT_SHA1_RAWSZ]; 683 684free(state->author_name); 685 state->author_name = NULL; 686 687free(state->author_email); 688 state->author_email = NULL; 689 690free(state->author_date); 691 state->author_date = NULL; 692 693free(state->msg); 694 state->msg = NULL; 695 state->msg_len =0; 696 697unlink(am_path(state,"author-script")); 698unlink(am_path(state,"final-commit")); 699 700if(!get_sha1("HEAD", head)) 701write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head)); 702else 703write_file(am_path(state,"abort-safety"),1,"%s",""); 704 705 state->cur++; 706write_file(am_path(state,"next"),1,"%d", state->cur); 707} 708 709/** 710 * Returns the filename of the current patch email. 711 */ 712static const char*msgnum(const struct am_state *state) 713{ 714static struct strbuf sb = STRBUF_INIT; 715 716strbuf_reset(&sb); 717strbuf_addf(&sb,"%0*d", state->prec, state->cur); 718 719return sb.buf; 720} 721 722/** 723 * Refresh and write index. 724 */ 725static voidrefresh_and_write_cache(void) 726{ 727struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file)); 728 729hold_locked_index(lock_file,1); 730refresh_cache(REFRESH_QUIET); 731if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 732die(_("unable to write index file")); 733} 734 735/** 736 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn 737 * branch, returns 1 if there are entries in the index, 0 otherwise. If an 738 * strbuf is provided, the space-separated list of files that differ will be 739 * appended to it. 740 */ 741static intindex_has_changes(struct strbuf *sb) 742{ 743unsigned char head[GIT_SHA1_RAWSZ]; 744int i; 745 746if(!get_sha1_tree("HEAD", head)) { 747struct diff_options opt; 748 749diff_setup(&opt); 750DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); 751if(!sb) 752DIFF_OPT_SET(&opt, QUICK); 753do_diff_cache(head, &opt); 754diffcore_std(&opt); 755for(i =0; sb && i < diff_queued_diff.nr; i++) { 756if(i) 757strbuf_addch(sb,' '); 758strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); 759} 760diff_flush(&opt); 761returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0; 762}else{ 763for(i =0; sb && i < active_nr; i++) { 764if(i) 765strbuf_addch(sb,' '); 766strbuf_addstr(sb, active_cache[i]->name); 767} 768return!!active_nr; 769} 770} 771 772/** 773 * Dies with a user-friendly message on how to proceed after resolving the 774 * problem. This message can be overridden with state->resolvemsg. 775 */ 776static void NORETURN die_user_resolve(const struct am_state *state) 777{ 778if(state->resolvemsg) { 779printf_ln("%s", state->resolvemsg); 780}else{ 781const char*cmdline ="git am"; 782 783printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline); 784printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline); 785printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline); 786} 787 788exit(128); 789} 790 791/** 792 * Parses `mail` using git-mailinfo, extracting its patch and authorship info. 793 * state->msg will be set to the patch message. state->author_name, 794 * state->author_email and state->author_date will be set to the patch author's 795 * name, email and date respectively. The patch body will be written to the 796 * state directory's "patch" file. 797 * 798 * Returns 1 if the patch should be skipped, 0 otherwise. 799 */ 800static intparse_mail(struct am_state *state,const char*mail) 801{ 802FILE*fp; 803struct child_process cp = CHILD_PROCESS_INIT; 804struct strbuf sb = STRBUF_INIT; 805struct strbuf msg = STRBUF_INIT; 806struct strbuf author_name = STRBUF_INIT; 807struct strbuf author_date = STRBUF_INIT; 808struct strbuf author_email = STRBUF_INIT; 809int ret =0; 810 811 cp.git_cmd =1; 812 cp.in =xopen(mail, O_RDONLY,0); 813 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777); 814 815argv_array_push(&cp.args,"mailinfo"); 816argv_array_push(&cp.args, state->utf8 ?"-u":"-n"); 817 818switch(state->keep) { 819case KEEP_FALSE: 820break; 821case KEEP_TRUE: 822argv_array_push(&cp.args,"-k"); 823break; 824case KEEP_NON_PATCH: 825argv_array_push(&cp.args,"-b"); 826break; 827default: 828die("BUG: invalid value for state->keep"); 829} 830 831if(state->message_id) 832argv_array_push(&cp.args,"-m"); 833 834switch(state->scissors) { 835case SCISSORS_UNSET: 836break; 837case SCISSORS_FALSE: 838argv_array_push(&cp.args,"--no-scissors"); 839break; 840case SCISSORS_TRUE: 841argv_array_push(&cp.args,"--scissors"); 842break; 843default: 844die("BUG: invalid value for state->scissors"); 845} 846 847argv_array_push(&cp.args,am_path(state,"msg")); 848argv_array_push(&cp.args,am_path(state,"patch")); 849 850if(run_command(&cp) <0) 851die("could not parse patch"); 852 853close(cp.in); 854close(cp.out); 855 856/* Extract message and author information */ 857 fp =xfopen(am_path(state,"info"),"r"); 858while(!strbuf_getline(&sb, fp,'\n')) { 859const char*x; 860 861if(skip_prefix(sb.buf,"Subject: ", &x)) { 862if(msg.len) 863strbuf_addch(&msg,'\n'); 864strbuf_addstr(&msg, x); 865}else if(skip_prefix(sb.buf,"Author: ", &x)) 866strbuf_addstr(&author_name, x); 867else if(skip_prefix(sb.buf,"Email: ", &x)) 868strbuf_addstr(&author_email, x); 869else if(skip_prefix(sb.buf,"Date: ", &x)) 870strbuf_addstr(&author_date, x); 871} 872fclose(fp); 873 874/* Skip pine's internal folder data */ 875if(!strcmp(author_name.buf,"Mail System Internal Data")) { 876 ret =1; 877goto finish; 878} 879 880if(is_empty_file(am_path(state,"patch"))) { 881printf_ln(_("Patch is empty. Was it split wrong?")); 882die_user_resolve(state); 883} 884 885strbuf_addstr(&msg,"\n\n"); 886if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0) 887die_errno(_("could not read '%s'"),am_path(state,"msg")); 888stripspace(&msg,0); 889 890if(state->signoff) 891append_signoff(&msg,0,0); 892 893assert(!state->author_name); 894 state->author_name =strbuf_detach(&author_name, NULL); 895 896assert(!state->author_email); 897 state->author_email =strbuf_detach(&author_email, NULL); 898 899assert(!state->author_date); 900 state->author_date =strbuf_detach(&author_date, NULL); 901 902assert(!state->msg); 903 state->msg =strbuf_detach(&msg, &state->msg_len); 904 905finish: 906strbuf_release(&msg); 907strbuf_release(&author_date); 908strbuf_release(&author_email); 909strbuf_release(&author_name); 910strbuf_release(&sb); 911return ret; 912} 913 914/** 915 * Sets commit_id to the commit hash where the mail was generated from. 916 * Returns 0 on success, -1 on failure. 917 */ 918static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail) 919{ 920struct strbuf sb = STRBUF_INIT; 921FILE*fp =xfopen(mail,"r"); 922const char*x; 923 924if(strbuf_getline(&sb, fp,'\n')) 925return-1; 926 927if(!skip_prefix(sb.buf,"From ", &x)) 928return-1; 929 930if(get_sha1_hex(x, commit_id) <0) 931return-1; 932 933strbuf_release(&sb); 934fclose(fp); 935return0; 936} 937 938/** 939 * Sets state->msg, state->author_name, state->author_email, state->author_date 940 * to the commit's respective info. 941 */ 942static voidget_commit_info(struct am_state *state,struct commit *commit) 943{ 944const char*buffer, *ident_line, *author_date, *msg; 945size_t ident_len; 946struct ident_split ident_split; 947struct strbuf sb = STRBUF_INIT; 948 949 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding()); 950 951 ident_line =find_commit_header(buffer,"author", &ident_len); 952 953if(split_ident_line(&ident_split, ident_line, ident_len) <0) { 954strbuf_add(&sb, ident_line, ident_len); 955die(_("invalid ident line:%s"), sb.buf); 956} 957 958assert(!state->author_name); 959if(ident_split.name_begin) { 960strbuf_add(&sb, ident_split.name_begin, 961 ident_split.name_end - ident_split.name_begin); 962 state->author_name =strbuf_detach(&sb, NULL); 963}else 964 state->author_name =xstrdup(""); 965 966assert(!state->author_email); 967if(ident_split.mail_begin) { 968strbuf_add(&sb, ident_split.mail_begin, 969 ident_split.mail_end - ident_split.mail_begin); 970 state->author_email =strbuf_detach(&sb, NULL); 971}else 972 state->author_email =xstrdup(""); 973 974 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL)); 975strbuf_addstr(&sb, author_date); 976assert(!state->author_date); 977 state->author_date =strbuf_detach(&sb, NULL); 978 979assert(!state->msg); 980 msg =strstr(buffer,"\n\n"); 981if(!msg) 982die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1)); 983 state->msg =xstrdup(msg +2); 984 state->msg_len =strlen(state->msg); 985} 986 987/** 988 * Writes `commit` as a patch to the state directory's "patch" file. 989 */ 990static voidwrite_commit_patch(const struct am_state *state,struct commit *commit) 991{ 992struct rev_info rev_info; 993FILE*fp; 994 995 fp =xfopen(am_path(state,"patch"),"w"); 996init_revisions(&rev_info, NULL); 997 rev_info.diff =1; 998 rev_info.abbrev =0; 999 rev_info.disable_stdin =1;1000 rev_info.show_root_diff =1;1001 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1002 rev_info.no_commit_id =1;1003DIFF_OPT_SET(&rev_info.diffopt, BINARY);1004DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1005 rev_info.diffopt.use_color =0;1006 rev_info.diffopt.file = fp;1007 rev_info.diffopt.close_file =1;1008add_pending_object(&rev_info, &commit->object,"");1009diff_setup_done(&rev_info.diffopt);1010log_tree_commit(&rev_info, commit);1011}10121013/**1014 * Like parse_mail(), but parses the mail by looking up its commit ID1015 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1016 * of patches.1017 *1018 * Will always return 0 as the patch should never be skipped.1019 */1020static intparse_mail_rebase(struct am_state *state,const char*mail)1021{1022struct commit *commit;1023unsigned char commit_sha1[GIT_SHA1_RAWSZ];10241025if(get_mail_commit_sha1(commit_sha1, mail) <0)1026die(_("could not parse%s"), mail);10271028 commit =lookup_commit_or_die(commit_sha1, mail);10291030get_commit_info(state, commit);10311032write_commit_patch(state, commit);10331034return0;1035}10361037/**1038 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1039 * `index_file` is not NULL, the patch will be applied to that index.1040 */1041static intrun_apply(const struct am_state *state,const char*index_file)1042{1043struct child_process cp = CHILD_PROCESS_INIT;10441045 cp.git_cmd =1;10461047if(index_file)1048argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);10491050/*1051 * If we are allowed to fall back on 3-way merge, don't give false1052 * errors during the initial attempt.1053 */1054if(state->threeway && !index_file) {1055 cp.no_stdout =1;1056 cp.no_stderr =1;1057}10581059argv_array_push(&cp.args,"apply");10601061if(index_file)1062argv_array_push(&cp.args,"--cached");1063else1064argv_array_push(&cp.args,"--index");10651066argv_array_push(&cp.args,am_path(state,"patch"));10671068if(run_command(&cp))1069return-1;10701071/* Reload index as git-apply will have modified it. */1072discard_cache();1073read_cache_from(index_file ? index_file :get_index_file());10741075return0;1076}10771078/**1079 * Builds an index that contains just the blobs needed for a 3way merge.1080 */1081static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1082{1083struct child_process cp = CHILD_PROCESS_INIT;10841085 cp.git_cmd =1;1086argv_array_push(&cp.args,"apply");1087argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1088argv_array_push(&cp.args,am_path(state,"patch"));10891090if(run_command(&cp))1091return-1;10921093return0;1094}10951096/**1097 * Attempt a threeway merge, using index_path as the temporary index.1098 */1099static intfall_back_threeway(const struct am_state *state,const char*index_path)1100{1101unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1102 our_tree[GIT_SHA1_RAWSZ];1103const unsigned char*bases[1] = {orig_tree};1104struct merge_options o;1105struct commit *result;1106char*his_tree_name;11071108if(get_sha1("HEAD", our_tree) <0)1109hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);11101111if(build_fake_ancestor(state, index_path))1112returnerror("could not build fake ancestor");11131114discard_cache();1115read_cache_from(index_path);11161117if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1118returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));11191120say(state, stdout,_("Using index info to reconstruct a base tree..."));11211122if(!state->quiet) {1123/*1124 * List paths that needed 3-way fallback, so that the user can1125 * review them with extra care to spot mismerges.1126 */1127struct rev_info rev_info;1128const char*diff_filter_str ="--diff-filter=AM";11291130init_revisions(&rev_info, NULL);1131 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1132diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1133add_pending_sha1(&rev_info,"HEAD", our_tree,0);1134diff_setup_done(&rev_info.diffopt);1135run_diff_index(&rev_info,1);1136}11371138if(run_apply(state, index_path))1139returnerror(_("Did you hand edit your patch?\n"1140"It does not apply to blobs recorded in its index."));11411142if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1143returnerror("could not write tree");11441145say(state, stdout,_("Falling back to patching base and 3-way merge..."));11461147discard_cache();1148read_cache();11491150/*1151 * This is not so wrong. Depending on which base we picked, orig_tree1152 * may be wildly different from ours, but his_tree has the same set of1153 * wildly different changes in parts the patch did not touch, so1154 * recursive ends up canceling them, saying that we reverted all those1155 * changes.1156 */11571158init_merge_options(&o);11591160 o.branch1 ="HEAD";1161 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1162 o.branch2 = his_tree_name;11631164if(state->quiet)1165 o.verbosity =0;11661167if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1168free(his_tree_name);1169returnerror(_("Failed to merge in the changes."));1170}11711172free(his_tree_name);1173return0;1174}11751176/**1177 * Commits the current index with state->msg as the commit message and1178 * state->author_name, state->author_email and state->author_date as the author1179 * information.1180 */1181static voiddo_commit(const struct am_state *state)1182{1183unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1184 commit[GIT_SHA1_RAWSZ];1185unsigned char*ptr;1186struct commit_list *parents = NULL;1187const char*reflog_msg, *author;1188struct strbuf sb = STRBUF_INIT;11891190if(write_cache_as_tree(tree,0, NULL))1191die(_("git write-tree failed to write a tree"));11921193if(!get_sha1_commit("HEAD", parent)) {1194 ptr = parent;1195commit_list_insert(lookup_commit(parent), &parents);1196}else{1197 ptr = NULL;1198say(state, stderr,_("applying to an empty history"));1199}12001201 author =fmt_ident(state->author_name, state->author_email,1202 state->author_date, IDENT_STRICT);12031204if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1205 author, NULL))1206die(_("failed to write commit object"));12071208 reflog_msg =getenv("GIT_REFLOG_ACTION");1209if(!reflog_msg)1210 reflog_msg ="am";12111212strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1213 state->msg);12141215update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);12161217strbuf_release(&sb);1218}12191220/**1221 * Validates the am_state for resuming -- the "msg" and authorship fields must1222 * be filled up.1223 */1224static voidvalidate_resume_state(const struct am_state *state)1225{1226if(!state->msg)1227die(_("cannot resume:%sdoes not exist."),1228am_path(state,"final-commit"));12291230if(!state->author_name || !state->author_email || !state->author_date)1231die(_("cannot resume:%sdoes not exist."),1232am_path(state,"author-script"));1233}12341235/**1236 * Applies all queued mail.1237 *1238 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1239 * well as the state directory's "patch" file is used as-is for applying the1240 * patch and committing it.1241 */1242static voidam_run(struct am_state *state,int resume)1243{1244const char*argv_gc_auto[] = {"gc","--auto", NULL};1245struct strbuf sb = STRBUF_INIT;12461247unlink(am_path(state,"dirtyindex"));12481249refresh_and_write_cache();12501251if(index_has_changes(&sb)) {1252write_file(am_path(state,"dirtyindex"),1,"t");1253die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1254}12551256strbuf_release(&sb);12571258while(state->cur <= state->last) {1259const char*mail =am_path(state,msgnum(state));1260int apply_status;12611262if(!file_exists(mail))1263goto next;12641265if(resume) {1266validate_resume_state(state);1267 resume =0;1268}else{1269int skip;12701271if(state->rebasing)1272 skip =parse_mail_rebase(state, mail);1273else1274 skip =parse_mail(state, mail);12751276if(skip)1277goto next;/* mail should be skipped */12781279write_author_script(state);1280write_commit_msg(state);1281}12821283say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);12841285 apply_status =run_apply(state, NULL);12861287if(apply_status && state->threeway) {1288struct strbuf sb = STRBUF_INIT;12891290strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1291 apply_status =fall_back_threeway(state, sb.buf);1292strbuf_release(&sb);12931294/*1295 * Applying the patch to an earlier tree and merging1296 * the result may have produced the same tree as ours.1297 */1298if(!apply_status && !index_has_changes(NULL)) {1299say(state, stdout,_("No changes -- Patch already applied."));1300goto next;1301}1302}13031304if(apply_status) {1305int advice_amworkdir =1;13061307printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1308linelen(state->msg), state->msg);13091310git_config_get_bool("advice.amworkdir", &advice_amworkdir);13111312if(advice_amworkdir)1313printf_ln(_("The copy of the patch that failed is found in:%s"),1314am_path(state,"patch"));13151316die_user_resolve(state);1317}13181319do_commit(state);13201321next:1322am_next(state);1323}13241325/*1326 * In rebasing mode, it's up to the caller to take care of1327 * housekeeping.1328 */1329if(!state->rebasing) {1330am_destroy(state);1331run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1332}1333}13341335/**1336 * Resume the current am session after patch application failure. The user did1337 * all the hard work, and we do not have to do any patch application. Just1338 * trust and commit what the user has in the index and working tree.1339 */1340static voidam_resolve(struct am_state *state)1341{1342validate_resume_state(state);13431344say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);13451346if(!index_has_changes(NULL)) {1347printf_ln(_("No changes - did you forget to use 'git add'?\n"1348"If there is nothing left to stage, chances are that something else\n"1349"already introduced the same changes; you might want to skip this patch."));1350die_user_resolve(state);1351}13521353if(unmerged_cache()) {1354printf_ln(_("You still have unmerged paths in your index.\n"1355"Did you forget to use 'git add'?"));1356die_user_resolve(state);1357}13581359do_commit(state);13601361am_next(state);1362am_run(state,0);1363}13641365/**1366 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1367 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1368 * failure.1369 */1370static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1371{1372struct lock_file *lock_file;1373struct unpack_trees_options opts;1374struct tree_desc t[2];13751376if(parse_tree(head) ||parse_tree(remote))1377return-1;13781379 lock_file =xcalloc(1,sizeof(struct lock_file));1380hold_locked_index(lock_file,1);13811382refresh_cache(REFRESH_QUIET);13831384memset(&opts,0,sizeof(opts));1385 opts.head_idx =1;1386 opts.src_index = &the_index;1387 opts.dst_index = &the_index;1388 opts.update =1;1389 opts.merge =1;1390 opts.reset = reset;1391 opts.fn = twoway_merge;1392init_tree_desc(&t[0], head->buffer, head->size);1393init_tree_desc(&t[1], remote->buffer, remote->size);13941395if(unpack_trees(2, t, &opts)) {1396rollback_lock_file(lock_file);1397return-1;1398}13991400if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1401die(_("unable to write new index file"));14021403return0;1404}14051406/**1407 * Clean the index without touching entries that are not modified between1408 * `head` and `remote`.1409 */1410static intclean_index(const unsigned char*head,const unsigned char*remote)1411{1412struct lock_file *lock_file;1413struct tree *head_tree, *remote_tree, *index_tree;1414unsigned char index[GIT_SHA1_RAWSZ];1415struct pathspec pathspec;14161417 head_tree =parse_tree_indirect(head);1418if(!head_tree)1419returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));14201421 remote_tree =parse_tree_indirect(remote);1422if(!remote_tree)1423returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));14241425read_cache_unmerged();14261427if(fast_forward_to(head_tree, head_tree,1))1428return-1;14291430if(write_cache_as_tree(index,0, NULL))1431return-1;14321433 index_tree =parse_tree_indirect(index);1434if(!index_tree)1435returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));14361437if(fast_forward_to(index_tree, remote_tree,0))1438return-1;14391440memset(&pathspec,0,sizeof(pathspec));14411442 lock_file =xcalloc(1,sizeof(struct lock_file));1443hold_locked_index(lock_file,1);14441445if(read_tree(remote_tree,0, &pathspec)) {1446rollback_lock_file(lock_file);1447return-1;1448}14491450if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1451die(_("unable to write new index file"));14521453remove_branch_state();14541455return0;1456}14571458/**1459 * Resume the current am session by skipping the current patch.1460 */1461static voidam_skip(struct am_state *state)1462{1463unsigned char head[GIT_SHA1_RAWSZ];14641465if(get_sha1("HEAD", head))1466hashcpy(head, EMPTY_TREE_SHA1_BIN);14671468if(clean_index(head, head))1469die(_("failed to clean index"));14701471am_next(state);1472am_run(state,0);1473}14741475/**1476 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.1477 *1478 * It is not safe to reset HEAD when:1479 * 1. git-am previously failed because the index was dirty.1480 * 2. HEAD has moved since git-am previously failed.1481 */1482static intsafe_to_abort(const struct am_state *state)1483{1484struct strbuf sb = STRBUF_INIT;1485unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];14861487if(file_exists(am_path(state,"dirtyindex")))1488return0;14891490if(read_state_file(&sb, state,"abort-safety",1) >0) {1491if(get_sha1_hex(sb.buf, abort_safety))1492die(_("could not parse%s"),am_path(state,"abort_safety"));1493}else1494hashclr(abort_safety);14951496if(get_sha1("HEAD", head))1497hashclr(head);14981499if(!hashcmp(head, abort_safety))1500return1;15011502error(_("You seem to have moved HEAD since the last 'am' failure.\n"1503"Not rewinding to ORIG_HEAD"));15041505return0;1506}15071508/**1509 * Aborts the current am session if it is safe to do so.1510 */1511static voidam_abort(struct am_state *state)1512{1513unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];1514int has_curr_head, has_orig_head;1515char*curr_branch;15161517if(!safe_to_abort(state)) {1518am_destroy(state);1519return;1520}15211522 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);1523 has_curr_head = !is_null_sha1(curr_head);1524if(!has_curr_head)1525hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);15261527 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);1528if(!has_orig_head)1529hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);15301531clean_index(curr_head, orig_head);15321533if(has_orig_head)1534update_ref("am --abort","HEAD", orig_head,1535 has_curr_head ? curr_head : NULL,0,1536 UPDATE_REFS_DIE_ON_ERR);1537else if(curr_branch)1538delete_ref(curr_branch, NULL, REF_NODEREF);15391540free(curr_branch);1541am_destroy(state);1542}15431544/**1545 * parse_options() callback that validates and sets opt->value to the1546 * PATCH_FORMAT_* enum value corresponding to `arg`.1547 */1548static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)1549{1550int*opt_value = opt->value;15511552if(!strcmp(arg,"mbox"))1553*opt_value = PATCH_FORMAT_MBOX;1554else1555returnerror(_("Invalid value for --patch-format:%s"), arg);1556return0;1557}15581559enum resume_mode {1560 RESUME_FALSE =0,1561 RESUME_APPLY,1562 RESUME_RESOLVED,1563 RESUME_SKIP,1564 RESUME_ABORT1565};15661567intcmd_am(int argc,const char**argv,const char*prefix)1568{1569struct am_state state;1570int keep_cr = -1;1571int patch_format = PATCH_FORMAT_UNKNOWN;1572enum resume_mode resume = RESUME_FALSE;15731574const char*const usage[] = {1575N_("git am [options] [(<mbox>|<Maildir>)...]"),1576N_("git am [options] (--continue | --skip | --abort)"),1577 NULL1578};15791580struct option options[] = {1581OPT_BOOL('3',"3way", &state.threeway,1582N_("allow fall back on 3way merging if needed")),1583OPT__QUIET(&state.quiet,N_("be quiet")),1584OPT_BOOL('s',"signoff", &state.signoff,1585N_("add a Signed-off-by line to the commit message")),1586OPT_BOOL('u',"utf8", &state.utf8,1587N_("recode into utf8 (default)")),1588OPT_SET_INT('k',"keep", &state.keep,1589N_("pass -k flag to git-mailinfo"), KEEP_TRUE),1590OPT_SET_INT(0,"keep-non-patch", &state.keep,1591N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),1592OPT_BOOL('m',"message-id", &state.message_id,1593N_("pass -m flag to git-mailinfo")),1594{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,1595N_("pass --keep-cr flag to git-mailsplit for mbox format"),1596 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},1597{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,1598N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),1599 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},1600OPT_BOOL('c',"scissors", &state.scissors,1601N_("strip everything before a scissors line")),1602OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),1603N_("format the patch(es) are in"),1604 parse_opt_patchformat),1605OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,1606N_("override error message when patch failure occurs")),1607OPT_CMDMODE(0,"continue", &resume,1608N_("continue applying patches after resolving a conflict"),1609 RESUME_RESOLVED),1610OPT_CMDMODE('r',"resolved", &resume,1611N_("synonyms for --continue"),1612 RESUME_RESOLVED),1613OPT_CMDMODE(0,"skip", &resume,1614N_("skip the current patch"),1615 RESUME_SKIP),1616OPT_CMDMODE(0,"abort", &resume,1617N_("restore the original branch and abort the patching operation."),1618 RESUME_ABORT),1619OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,1620N_("(internal use for git-rebase)")),1621OPT_END()1622};16231624/*1625 * NEEDSWORK: Once all the features of git-am.sh have been1626 * re-implemented in builtin/am.c, this preamble can be removed.1627 */1628if(!getenv("_GIT_USE_BUILTIN_AM")) {1629const char*path =mkpath("%s/git-am",git_exec_path());16301631if(sane_execvp(path, (char**)argv) <0)1632die_errno("could not exec%s", path);1633}else{1634 prefix =setup_git_directory();1635trace_repo_setup(prefix);1636setup_work_tree();1637}16381639git_config(git_default_config, NULL);16401641am_state_init(&state,git_path("rebase-apply"));16421643 argc =parse_options(argc, argv, prefix, options, usage,0);16441645if(read_index_preload(&the_index, NULL) <0)1646die(_("failed to read the index"));16471648if(am_in_progress(&state)) {1649/*1650 * Catch user error to feed us patches when there is a session1651 * in progress:1652 *1653 * 1. mbox path(s) are provided on the command-line.1654 * 2. stdin is not a tty: the user is trying to feed us a patch1655 * from standard input. This is somewhat unreliable -- stdin1656 * could be /dev/null for example and the caller did not1657 * intend to feed us a patch but wanted to continue1658 * unattended.1659 */1660if(argc || (resume == RESUME_FALSE && !isatty(0)))1661die(_("previous rebase directory%sstill exists but mbox given."),1662 state.dir);16631664if(resume == RESUME_FALSE)1665 resume = RESUME_APPLY;16661667am_load(&state);1668}else{1669struct argv_array paths = ARGV_ARRAY_INIT;1670int i;16711672/*1673 * Handle stray state directory in the independent-run case. In1674 * the --rebasing case, it is up to the caller to take care of1675 * stray directories.1676 */1677if(file_exists(state.dir) && !state.rebasing) {1678if(resume == RESUME_ABORT) {1679am_destroy(&state);1680am_state_release(&state);1681return0;1682}16831684die(_("Stray%sdirectory found.\n"1685"Use\"git am --abort\"to remove it."),1686 state.dir);1687}16881689if(resume)1690die(_("Resolve operation not in progress, we are not resuming."));16911692for(i =0; i < argc; i++) {1693if(is_absolute_path(argv[i]) || !prefix)1694argv_array_push(&paths, argv[i]);1695else1696argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));1697}16981699am_setup(&state, patch_format, paths.argv, keep_cr);17001701argv_array_clear(&paths);1702}17031704switch(resume) {1705case RESUME_FALSE:1706am_run(&state,0);1707break;1708case RESUME_APPLY:1709am_run(&state,1);1710break;1711case RESUME_RESOLVED:1712am_resolve(&state);1713break;1714case RESUME_SKIP:1715am_skip(&state);1716break;1717case RESUME_ABORT:1718am_abort(&state);1719break;1720default:1721die("BUG: invalid resume value");1722}17231724am_state_release(&state);17251726return0;1727}