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 77struct am_state { 78/* state directory path */ 79char*dir; 80 81/* current and last patch numbers, 1-indexed */ 82int cur; 83int last; 84 85/* commit metadata and message */ 86char*author_name; 87char*author_email; 88char*author_date; 89char*msg; 90size_t msg_len; 91 92/* number of digits in patch filename */ 93int prec; 94 95/* various operating modes and command line options */ 96int threeway; 97int quiet; 98int signoff; 99int utf8; 100int keep;/* enum keep_type */ 101int message_id; 102const char*resolvemsg; 103int rebasing; 104}; 105 106/** 107 * Initializes am_state with the default values. The state directory is set to 108 * dir. 109 */ 110static voidam_state_init(struct am_state *state,const char*dir) 111{ 112memset(state,0,sizeof(*state)); 113 114assert(dir); 115 state->dir =xstrdup(dir); 116 117 state->prec =4; 118 119 state->utf8 =1; 120 121git_config_get_bool("am.messageid", &state->message_id); 122} 123 124/** 125 * Releases memory allocated by an am_state. 126 */ 127static voidam_state_release(struct am_state *state) 128{ 129free(state->dir); 130free(state->author_name); 131free(state->author_email); 132free(state->author_date); 133free(state->msg); 134} 135 136/** 137 * Returns path relative to the am_state directory. 138 */ 139staticinlineconst char*am_path(const struct am_state *state,const char*path) 140{ 141returnmkpath("%s/%s", state->dir, path); 142} 143 144/** 145 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 146 * at the end. 147 */ 148static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 149{ 150va_list ap; 151 152va_start(ap, fmt); 153if(!state->quiet) { 154vfprintf(fp, fmt, ap); 155putc('\n', fp); 156} 157va_end(ap); 158} 159 160/** 161 * Returns 1 if there is an am session in progress, 0 otherwise. 162 */ 163static intam_in_progress(const struct am_state *state) 164{ 165struct stat st; 166 167if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 168return0; 169if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 170return0; 171if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 172return0; 173return1; 174} 175 176/** 177 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 178 * number of bytes read on success, -1 if the file does not exist. If `trim` is 179 * set, trailing whitespace will be removed. 180 */ 181static intread_state_file(struct strbuf *sb,const struct am_state *state, 182const char*file,int trim) 183{ 184strbuf_reset(sb); 185 186if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 187if(trim) 188strbuf_trim(sb); 189 190return sb->len; 191} 192 193if(errno == ENOENT) 194return-1; 195 196die_errno(_("could not read '%s'"),am_path(state, file)); 197} 198 199/** 200 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 201 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 202 * match `key`. Returns NULL on failure. 203 * 204 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 205 * the author-script. 206 */ 207static char*read_shell_var(FILE*fp,const char*key) 208{ 209struct strbuf sb = STRBUF_INIT; 210const char*str; 211 212if(strbuf_getline(&sb, fp,'\n')) 213goto fail; 214 215if(!skip_prefix(sb.buf, key, &str)) 216goto fail; 217 218if(!skip_prefix(str,"=", &str)) 219goto fail; 220 221strbuf_remove(&sb,0, str - sb.buf); 222 223 str =sq_dequote(sb.buf); 224if(!str) 225goto fail; 226 227returnstrbuf_detach(&sb, NULL); 228 229fail: 230strbuf_release(&sb); 231return NULL; 232} 233 234/** 235 * Reads and parses the state directory's "author-script" file, and sets 236 * state->author_name, state->author_email and state->author_date accordingly. 237 * Returns 0 on success, -1 if the file could not be parsed. 238 * 239 * The author script is of the format: 240 * 241 * GIT_AUTHOR_NAME='$author_name' 242 * GIT_AUTHOR_EMAIL='$author_email' 243 * GIT_AUTHOR_DATE='$author_date' 244 * 245 * where $author_name, $author_email and $author_date are quoted. We are strict 246 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 247 * script, and thus if the file differs from what this function expects, it is 248 * better to bail out than to do something that the user does not expect. 249 */ 250static intread_author_script(struct am_state *state) 251{ 252const char*filename =am_path(state,"author-script"); 253FILE*fp; 254 255assert(!state->author_name); 256assert(!state->author_email); 257assert(!state->author_date); 258 259 fp =fopen(filename,"r"); 260if(!fp) { 261if(errno == ENOENT) 262return0; 263die_errno(_("could not open '%s' for reading"), filename); 264} 265 266 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 267if(!state->author_name) { 268fclose(fp); 269return-1; 270} 271 272 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 273if(!state->author_email) { 274fclose(fp); 275return-1; 276} 277 278 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 279if(!state->author_date) { 280fclose(fp); 281return-1; 282} 283 284if(fgetc(fp) != EOF) { 285fclose(fp); 286return-1; 287} 288 289fclose(fp); 290return0; 291} 292 293/** 294 * Saves state->author_name, state->author_email and state->author_date in the 295 * state directory's "author-script" file. 296 */ 297static voidwrite_author_script(const struct am_state *state) 298{ 299struct strbuf sb = STRBUF_INIT; 300 301strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 302sq_quote_buf(&sb, state->author_name); 303strbuf_addch(&sb,'\n'); 304 305strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 306sq_quote_buf(&sb, state->author_email); 307strbuf_addch(&sb,'\n'); 308 309strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 310sq_quote_buf(&sb, state->author_date); 311strbuf_addch(&sb,'\n'); 312 313write_file(am_path(state,"author-script"),1,"%s", sb.buf); 314 315strbuf_release(&sb); 316} 317 318/** 319 * Reads the commit message from the state directory's "final-commit" file, 320 * setting state->msg to its contents and state->msg_len to the length of its 321 * contents in bytes. 322 * 323 * Returns 0 on success, -1 if the file does not exist. 324 */ 325static intread_commit_msg(struct am_state *state) 326{ 327struct strbuf sb = STRBUF_INIT; 328 329assert(!state->msg); 330 331if(read_state_file(&sb, state,"final-commit",0) <0) { 332strbuf_release(&sb); 333return-1; 334} 335 336 state->msg =strbuf_detach(&sb, &state->msg_len); 337return0; 338} 339 340/** 341 * Saves state->msg in the state directory's "final-commit" file. 342 */ 343static voidwrite_commit_msg(const struct am_state *state) 344{ 345int fd; 346const char*filename =am_path(state,"final-commit"); 347 348 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 349if(write_in_full(fd, state->msg, state->msg_len) <0) 350die_errno(_("could not write to%s"), filename); 351close(fd); 352} 353 354/** 355 * Loads state from disk. 356 */ 357static voidam_load(struct am_state *state) 358{ 359struct strbuf sb = STRBUF_INIT; 360 361if(read_state_file(&sb, state,"next",1) <0) 362die("BUG: state file 'next' does not exist"); 363 state->cur =strtol(sb.buf, NULL,10); 364 365if(read_state_file(&sb, state,"last",1) <0) 366die("BUG: state file 'last' does not exist"); 367 state->last =strtol(sb.buf, NULL,10); 368 369if(read_author_script(state) <0) 370die(_("could not parse author script")); 371 372read_commit_msg(state); 373 374read_state_file(&sb, state,"threeway",1); 375 state->threeway = !strcmp(sb.buf,"t"); 376 377read_state_file(&sb, state,"quiet",1); 378 state->quiet = !strcmp(sb.buf,"t"); 379 380read_state_file(&sb, state,"sign",1); 381 state->signoff = !strcmp(sb.buf,"t"); 382 383read_state_file(&sb, state,"utf8",1); 384 state->utf8 = !strcmp(sb.buf,"t"); 385 386read_state_file(&sb, state,"keep",1); 387if(!strcmp(sb.buf,"t")) 388 state->keep = KEEP_TRUE; 389else if(!strcmp(sb.buf,"b")) 390 state->keep = KEEP_NON_PATCH; 391else 392 state->keep = KEEP_FALSE; 393 394read_state_file(&sb, state,"messageid",1); 395 state->message_id = !strcmp(sb.buf,"t"); 396 397 state->rebasing = !!file_exists(am_path(state,"rebasing")); 398 399strbuf_release(&sb); 400} 401 402/** 403 * Removes the am_state directory, forcefully terminating the current am 404 * session. 405 */ 406static voidam_destroy(const struct am_state *state) 407{ 408struct strbuf sb = STRBUF_INIT; 409 410strbuf_addstr(&sb, state->dir); 411remove_dir_recursively(&sb,0); 412strbuf_release(&sb); 413} 414 415/** 416 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 417 * non-indented lines and checking if they look like they begin with valid 418 * header field names. 419 * 420 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 421 */ 422static intis_mail(FILE*fp) 423{ 424const char*header_regex ="^[!-9;-~]+:"; 425struct strbuf sb = STRBUF_INIT; 426 regex_t regex; 427int ret =1; 428 429if(fseek(fp,0L, SEEK_SET)) 430die_errno(_("fseek failed")); 431 432if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 433die("invalid pattern:%s", header_regex); 434 435while(!strbuf_getline_crlf(&sb, fp)) { 436if(!sb.len) 437break;/* End of header */ 438 439/* Ignore indented folded lines */ 440if(*sb.buf =='\t'|| *sb.buf ==' ') 441continue; 442 443/* It's a header if it matches header_regex */ 444if(regexec(®ex, sb.buf,0, NULL,0)) { 445 ret =0; 446goto done; 447} 448} 449 450done: 451regfree(®ex); 452strbuf_release(&sb); 453return ret; 454} 455 456/** 457 * Attempts to detect the patch_format of the patches contained in `paths`, 458 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 459 * detection fails. 460 */ 461static intdetect_patch_format(const char**paths) 462{ 463enum patch_format ret = PATCH_FORMAT_UNKNOWN; 464struct strbuf l1 = STRBUF_INIT; 465FILE*fp; 466 467/* 468 * We default to mbox format if input is from stdin and for directories 469 */ 470if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 471return PATCH_FORMAT_MBOX; 472 473/* 474 * Otherwise, check the first few lines of the first patch, starting 475 * from the first non-blank line, to try to detect its format. 476 */ 477 478 fp =xfopen(*paths,"r"); 479 480while(!strbuf_getline_crlf(&l1, fp)) { 481if(l1.len) 482break; 483} 484 485if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 486 ret = PATCH_FORMAT_MBOX; 487goto done; 488} 489 490if(l1.len &&is_mail(fp)) { 491 ret = PATCH_FORMAT_MBOX; 492goto done; 493} 494 495done: 496fclose(fp); 497strbuf_release(&l1); 498return ret; 499} 500 501/** 502 * Splits out individual email patches from `paths`, where each path is either 503 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 504 */ 505static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 506{ 507struct child_process cp = CHILD_PROCESS_INIT; 508struct strbuf last = STRBUF_INIT; 509 510 cp.git_cmd =1; 511argv_array_push(&cp.args,"mailsplit"); 512argv_array_pushf(&cp.args,"-d%d", state->prec); 513argv_array_pushf(&cp.args,"-o%s", state->dir); 514argv_array_push(&cp.args,"-b"); 515if(keep_cr) 516argv_array_push(&cp.args,"--keep-cr"); 517argv_array_push(&cp.args,"--"); 518argv_array_pushv(&cp.args, paths); 519 520if(capture_command(&cp, &last,8)) 521return-1; 522 523 state->cur =1; 524 state->last =strtol(last.buf, NULL,10); 525 526return0; 527} 528 529/** 530 * Splits a list of files/directories into individual email patches. Each path 531 * in `paths` must be a file/directory that is formatted according to 532 * `patch_format`. 533 * 534 * Once split out, the individual email patches will be stored in the state 535 * directory, with each patch's filename being its index, padded to state->prec 536 * digits. 537 * 538 * state->cur will be set to the index of the first mail, and state->last will 539 * be set to the index of the last mail. 540 * 541 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 542 * to disable this behavior, -1 to use the default configured setting. 543 * 544 * Returns 0 on success, -1 on failure. 545 */ 546static intsplit_mail(struct am_state *state,enum patch_format patch_format, 547const char**paths,int keep_cr) 548{ 549if(keep_cr <0) { 550 keep_cr =0; 551git_config_get_bool("am.keepcr", &keep_cr); 552} 553 554switch(patch_format) { 555case PATCH_FORMAT_MBOX: 556returnsplit_mail_mbox(state, paths, keep_cr); 557default: 558die("BUG: invalid patch_format"); 559} 560return-1; 561} 562 563/** 564 * Setup a new am session for applying patches 565 */ 566static voidam_setup(struct am_state *state,enum patch_format patch_format, 567const char**paths,int keep_cr) 568{ 569unsigned char curr_head[GIT_SHA1_RAWSZ]; 570const char*str; 571 572if(!patch_format) 573 patch_format =detect_patch_format(paths); 574 575if(!patch_format) { 576fprintf_ln(stderr,_("Patch format detection failed.")); 577exit(128); 578} 579 580if(mkdir(state->dir,0777) <0&& errno != EEXIST) 581die_errno(_("failed to create directory '%s'"), state->dir); 582 583if(split_mail(state, patch_format, paths, keep_cr) <0) { 584am_destroy(state); 585die(_("Failed to split patches.")); 586} 587 588if(state->rebasing) 589 state->threeway =1; 590 591write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f"); 592 593write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f"); 594 595write_file(am_path(state,"sign"),1, state->signoff ?"t":"f"); 596 597write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f"); 598 599switch(state->keep) { 600case KEEP_FALSE: 601 str ="f"; 602break; 603case KEEP_TRUE: 604 str ="t"; 605break; 606case KEEP_NON_PATCH: 607 str ="b"; 608break; 609default: 610die("BUG: invalid value for state->keep"); 611} 612 613write_file(am_path(state,"keep"),1,"%s", str); 614 615write_file(am_path(state,"messageid"),1, state->message_id ?"t":"f"); 616 617if(state->rebasing) 618write_file(am_path(state,"rebasing"),1,"%s",""); 619else 620write_file(am_path(state,"applying"),1,"%s",""); 621 622if(!get_sha1("HEAD", curr_head)) { 623write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head)); 624if(!state->rebasing) 625update_ref("am","ORIG_HEAD", curr_head, NULL,0, 626 UPDATE_REFS_DIE_ON_ERR); 627}else{ 628write_file(am_path(state,"abort-safety"),1,"%s",""); 629if(!state->rebasing) 630delete_ref("ORIG_HEAD", NULL,0); 631} 632 633/* 634 * NOTE: Since the "next" and "last" files determine if an am_state 635 * session is in progress, they should be written last. 636 */ 637 638write_file(am_path(state,"next"),1,"%d", state->cur); 639 640write_file(am_path(state,"last"),1,"%d", state->last); 641} 642 643/** 644 * Increments the patch pointer, and cleans am_state for the application of the 645 * next patch. 646 */ 647static voidam_next(struct am_state *state) 648{ 649unsigned char head[GIT_SHA1_RAWSZ]; 650 651free(state->author_name); 652 state->author_name = NULL; 653 654free(state->author_email); 655 state->author_email = NULL; 656 657free(state->author_date); 658 state->author_date = NULL; 659 660free(state->msg); 661 state->msg = NULL; 662 state->msg_len =0; 663 664unlink(am_path(state,"author-script")); 665unlink(am_path(state,"final-commit")); 666 667if(!get_sha1("HEAD", head)) 668write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head)); 669else 670write_file(am_path(state,"abort-safety"),1,"%s",""); 671 672 state->cur++; 673write_file(am_path(state,"next"),1,"%d", state->cur); 674} 675 676/** 677 * Returns the filename of the current patch email. 678 */ 679static const char*msgnum(const struct am_state *state) 680{ 681static struct strbuf sb = STRBUF_INIT; 682 683strbuf_reset(&sb); 684strbuf_addf(&sb,"%0*d", state->prec, state->cur); 685 686return sb.buf; 687} 688 689/** 690 * Refresh and write index. 691 */ 692static voidrefresh_and_write_cache(void) 693{ 694struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file)); 695 696hold_locked_index(lock_file,1); 697refresh_cache(REFRESH_QUIET); 698if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 699die(_("unable to write index file")); 700} 701 702/** 703 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn 704 * branch, returns 1 if there are entries in the index, 0 otherwise. If an 705 * strbuf is provided, the space-separated list of files that differ will be 706 * appended to it. 707 */ 708static intindex_has_changes(struct strbuf *sb) 709{ 710unsigned char head[GIT_SHA1_RAWSZ]; 711int i; 712 713if(!get_sha1_tree("HEAD", head)) { 714struct diff_options opt; 715 716diff_setup(&opt); 717DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); 718if(!sb) 719DIFF_OPT_SET(&opt, QUICK); 720do_diff_cache(head, &opt); 721diffcore_std(&opt); 722for(i =0; sb && i < diff_queued_diff.nr; i++) { 723if(i) 724strbuf_addch(sb,' '); 725strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); 726} 727diff_flush(&opt); 728returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0; 729}else{ 730for(i =0; sb && i < active_nr; i++) { 731if(i) 732strbuf_addch(sb,' '); 733strbuf_addstr(sb, active_cache[i]->name); 734} 735return!!active_nr; 736} 737} 738 739/** 740 * Dies with a user-friendly message on how to proceed after resolving the 741 * problem. This message can be overridden with state->resolvemsg. 742 */ 743static void NORETURN die_user_resolve(const struct am_state *state) 744{ 745if(state->resolvemsg) { 746printf_ln("%s", state->resolvemsg); 747}else{ 748const char*cmdline ="git am"; 749 750printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline); 751printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline); 752printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline); 753} 754 755exit(128); 756} 757 758/** 759 * Parses `mail` using git-mailinfo, extracting its patch and authorship info. 760 * state->msg will be set to the patch message. state->author_name, 761 * state->author_email and state->author_date will be set to the patch author's 762 * name, email and date respectively. The patch body will be written to the 763 * state directory's "patch" file. 764 * 765 * Returns 1 if the patch should be skipped, 0 otherwise. 766 */ 767static intparse_mail(struct am_state *state,const char*mail) 768{ 769FILE*fp; 770struct child_process cp = CHILD_PROCESS_INIT; 771struct strbuf sb = STRBUF_INIT; 772struct strbuf msg = STRBUF_INIT; 773struct strbuf author_name = STRBUF_INIT; 774struct strbuf author_date = STRBUF_INIT; 775struct strbuf author_email = STRBUF_INIT; 776int ret =0; 777 778 cp.git_cmd =1; 779 cp.in =xopen(mail, O_RDONLY,0); 780 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777); 781 782argv_array_push(&cp.args,"mailinfo"); 783argv_array_push(&cp.args, state->utf8 ?"-u":"-n"); 784 785switch(state->keep) { 786case KEEP_FALSE: 787break; 788case KEEP_TRUE: 789argv_array_push(&cp.args,"-k"); 790break; 791case KEEP_NON_PATCH: 792argv_array_push(&cp.args,"-b"); 793break; 794default: 795die("BUG: invalid value for state->keep"); 796} 797 798if(state->message_id) 799argv_array_push(&cp.args,"-m"); 800 801argv_array_push(&cp.args,am_path(state,"msg")); 802argv_array_push(&cp.args,am_path(state,"patch")); 803 804if(run_command(&cp) <0) 805die("could not parse patch"); 806 807close(cp.in); 808close(cp.out); 809 810/* Extract message and author information */ 811 fp =xfopen(am_path(state,"info"),"r"); 812while(!strbuf_getline(&sb, fp,'\n')) { 813const char*x; 814 815if(skip_prefix(sb.buf,"Subject: ", &x)) { 816if(msg.len) 817strbuf_addch(&msg,'\n'); 818strbuf_addstr(&msg, x); 819}else if(skip_prefix(sb.buf,"Author: ", &x)) 820strbuf_addstr(&author_name, x); 821else if(skip_prefix(sb.buf,"Email: ", &x)) 822strbuf_addstr(&author_email, x); 823else if(skip_prefix(sb.buf,"Date: ", &x)) 824strbuf_addstr(&author_date, x); 825} 826fclose(fp); 827 828/* Skip pine's internal folder data */ 829if(!strcmp(author_name.buf,"Mail System Internal Data")) { 830 ret =1; 831goto finish; 832} 833 834if(is_empty_file(am_path(state,"patch"))) { 835printf_ln(_("Patch is empty. Was it split wrong?")); 836die_user_resolve(state); 837} 838 839strbuf_addstr(&msg,"\n\n"); 840if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0) 841die_errno(_("could not read '%s'"),am_path(state,"msg")); 842stripspace(&msg,0); 843 844if(state->signoff) 845append_signoff(&msg,0,0); 846 847assert(!state->author_name); 848 state->author_name =strbuf_detach(&author_name, NULL); 849 850assert(!state->author_email); 851 state->author_email =strbuf_detach(&author_email, NULL); 852 853assert(!state->author_date); 854 state->author_date =strbuf_detach(&author_date, NULL); 855 856assert(!state->msg); 857 state->msg =strbuf_detach(&msg, &state->msg_len); 858 859finish: 860strbuf_release(&msg); 861strbuf_release(&author_date); 862strbuf_release(&author_email); 863strbuf_release(&author_name); 864strbuf_release(&sb); 865return ret; 866} 867 868/** 869 * Sets commit_id to the commit hash where the mail was generated from. 870 * Returns 0 on success, -1 on failure. 871 */ 872static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail) 873{ 874struct strbuf sb = STRBUF_INIT; 875FILE*fp =xfopen(mail,"r"); 876const char*x; 877 878if(strbuf_getline(&sb, fp,'\n')) 879return-1; 880 881if(!skip_prefix(sb.buf,"From ", &x)) 882return-1; 883 884if(get_sha1_hex(x, commit_id) <0) 885return-1; 886 887strbuf_release(&sb); 888fclose(fp); 889return0; 890} 891 892/** 893 * Sets state->msg, state->author_name, state->author_email, state->author_date 894 * to the commit's respective info. 895 */ 896static voidget_commit_info(struct am_state *state,struct commit *commit) 897{ 898const char*buffer, *ident_line, *author_date, *msg; 899size_t ident_len; 900struct ident_split ident_split; 901struct strbuf sb = STRBUF_INIT; 902 903 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding()); 904 905 ident_line =find_commit_header(buffer,"author", &ident_len); 906 907if(split_ident_line(&ident_split, ident_line, ident_len) <0) { 908strbuf_add(&sb, ident_line, ident_len); 909die(_("invalid ident line:%s"), sb.buf); 910} 911 912assert(!state->author_name); 913if(ident_split.name_begin) { 914strbuf_add(&sb, ident_split.name_begin, 915 ident_split.name_end - ident_split.name_begin); 916 state->author_name =strbuf_detach(&sb, NULL); 917}else 918 state->author_name =xstrdup(""); 919 920assert(!state->author_email); 921if(ident_split.mail_begin) { 922strbuf_add(&sb, ident_split.mail_begin, 923 ident_split.mail_end - ident_split.mail_begin); 924 state->author_email =strbuf_detach(&sb, NULL); 925}else 926 state->author_email =xstrdup(""); 927 928 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL)); 929strbuf_addstr(&sb, author_date); 930assert(!state->author_date); 931 state->author_date =strbuf_detach(&sb, NULL); 932 933assert(!state->msg); 934 msg =strstr(buffer,"\n\n"); 935if(!msg) 936die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1)); 937 state->msg =xstrdup(msg +2); 938 state->msg_len =strlen(state->msg); 939} 940 941/** 942 * Writes `commit` as a patch to the state directory's "patch" file. 943 */ 944static voidwrite_commit_patch(const struct am_state *state,struct commit *commit) 945{ 946struct rev_info rev_info; 947FILE*fp; 948 949 fp =xfopen(am_path(state,"patch"),"w"); 950init_revisions(&rev_info, NULL); 951 rev_info.diff =1; 952 rev_info.abbrev =0; 953 rev_info.disable_stdin =1; 954 rev_info.show_root_diff =1; 955 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; 956 rev_info.no_commit_id =1; 957DIFF_OPT_SET(&rev_info.diffopt, BINARY); 958DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX); 959 rev_info.diffopt.use_color =0; 960 rev_info.diffopt.file = fp; 961 rev_info.diffopt.close_file =1; 962add_pending_object(&rev_info, &commit->object,""); 963diff_setup_done(&rev_info.diffopt); 964log_tree_commit(&rev_info, commit); 965} 966 967/** 968 * Like parse_mail(), but parses the mail by looking up its commit ID 969 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging 970 * of patches. 971 * 972 * Will always return 0 as the patch should never be skipped. 973 */ 974static intparse_mail_rebase(struct am_state *state,const char*mail) 975{ 976struct commit *commit; 977unsigned char commit_sha1[GIT_SHA1_RAWSZ]; 978 979if(get_mail_commit_sha1(commit_sha1, mail) <0) 980die(_("could not parse%s"), mail); 981 982 commit =lookup_commit_or_die(commit_sha1, mail); 983 984get_commit_info(state, commit); 985 986write_commit_patch(state, commit); 987 988return0; 989} 990 991/** 992 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If 993 * `index_file` is not NULL, the patch will be applied to that index. 994 */ 995static intrun_apply(const struct am_state *state,const char*index_file) 996{ 997struct child_process cp = CHILD_PROCESS_INIT; 998 999 cp.git_cmd =1;10001001if(index_file)1002argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);10031004/*1005 * If we are allowed to fall back on 3-way merge, don't give false1006 * errors during the initial attempt.1007 */1008if(state->threeway && !index_file) {1009 cp.no_stdout =1;1010 cp.no_stderr =1;1011}10121013argv_array_push(&cp.args,"apply");10141015if(index_file)1016argv_array_push(&cp.args,"--cached");1017else1018argv_array_push(&cp.args,"--index");10191020argv_array_push(&cp.args,am_path(state,"patch"));10211022if(run_command(&cp))1023return-1;10241025/* Reload index as git-apply will have modified it. */1026discard_cache();1027read_cache_from(index_file ? index_file :get_index_file());10281029return0;1030}10311032/**1033 * Builds an index that contains just the blobs needed for a 3way merge.1034 */1035static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1036{1037struct child_process cp = CHILD_PROCESS_INIT;10381039 cp.git_cmd =1;1040argv_array_push(&cp.args,"apply");1041argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1042argv_array_push(&cp.args,am_path(state,"patch"));10431044if(run_command(&cp))1045return-1;10461047return0;1048}10491050/**1051 * Attempt a threeway merge, using index_path as the temporary index.1052 */1053static intfall_back_threeway(const struct am_state *state,const char*index_path)1054{1055unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1056 our_tree[GIT_SHA1_RAWSZ];1057const unsigned char*bases[1] = {orig_tree};1058struct merge_options o;1059struct commit *result;1060char*his_tree_name;10611062if(get_sha1("HEAD", our_tree) <0)1063hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);10641065if(build_fake_ancestor(state, index_path))1066returnerror("could not build fake ancestor");10671068discard_cache();1069read_cache_from(index_path);10701071if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1072returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));10731074say(state, stdout,_("Using index info to reconstruct a base tree..."));10751076if(!state->quiet) {1077/*1078 * List paths that needed 3-way fallback, so that the user can1079 * review them with extra care to spot mismerges.1080 */1081struct rev_info rev_info;1082const char*diff_filter_str ="--diff-filter=AM";10831084init_revisions(&rev_info, NULL);1085 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1086diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1087add_pending_sha1(&rev_info,"HEAD", our_tree,0);1088diff_setup_done(&rev_info.diffopt);1089run_diff_index(&rev_info,1);1090}10911092if(run_apply(state, index_path))1093returnerror(_("Did you hand edit your patch?\n"1094"It does not apply to blobs recorded in its index."));10951096if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1097returnerror("could not write tree");10981099say(state, stdout,_("Falling back to patching base and 3-way merge..."));11001101discard_cache();1102read_cache();11031104/*1105 * This is not so wrong. Depending on which base we picked, orig_tree1106 * may be wildly different from ours, but his_tree has the same set of1107 * wildly different changes in parts the patch did not touch, so1108 * recursive ends up canceling them, saying that we reverted all those1109 * changes.1110 */11111112init_merge_options(&o);11131114 o.branch1 ="HEAD";1115 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1116 o.branch2 = his_tree_name;11171118if(state->quiet)1119 o.verbosity =0;11201121if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1122free(his_tree_name);1123returnerror(_("Failed to merge in the changes."));1124}11251126free(his_tree_name);1127return0;1128}11291130/**1131 * Commits the current index with state->msg as the commit message and1132 * state->author_name, state->author_email and state->author_date as the author1133 * information.1134 */1135static voiddo_commit(const struct am_state *state)1136{1137unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1138 commit[GIT_SHA1_RAWSZ];1139unsigned char*ptr;1140struct commit_list *parents = NULL;1141const char*reflog_msg, *author;1142struct strbuf sb = STRBUF_INIT;11431144if(write_cache_as_tree(tree,0, NULL))1145die(_("git write-tree failed to write a tree"));11461147if(!get_sha1_commit("HEAD", parent)) {1148 ptr = parent;1149commit_list_insert(lookup_commit(parent), &parents);1150}else{1151 ptr = NULL;1152say(state, stderr,_("applying to an empty history"));1153}11541155 author =fmt_ident(state->author_name, state->author_email,1156 state->author_date, IDENT_STRICT);11571158if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1159 author, NULL))1160die(_("failed to write commit object"));11611162 reflog_msg =getenv("GIT_REFLOG_ACTION");1163if(!reflog_msg)1164 reflog_msg ="am";11651166strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1167 state->msg);11681169update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);11701171strbuf_release(&sb);1172}11731174/**1175 * Validates the am_state for resuming -- the "msg" and authorship fields must1176 * be filled up.1177 */1178static voidvalidate_resume_state(const struct am_state *state)1179{1180if(!state->msg)1181die(_("cannot resume:%sdoes not exist."),1182am_path(state,"final-commit"));11831184if(!state->author_name || !state->author_email || !state->author_date)1185die(_("cannot resume:%sdoes not exist."),1186am_path(state,"author-script"));1187}11881189/**1190 * Applies all queued mail.1191 *1192 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1193 * well as the state directory's "patch" file is used as-is for applying the1194 * patch and committing it.1195 */1196static voidam_run(struct am_state *state,int resume)1197{1198const char*argv_gc_auto[] = {"gc","--auto", NULL};1199struct strbuf sb = STRBUF_INIT;12001201unlink(am_path(state,"dirtyindex"));12021203refresh_and_write_cache();12041205if(index_has_changes(&sb)) {1206write_file(am_path(state,"dirtyindex"),1,"t");1207die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1208}12091210strbuf_release(&sb);12111212while(state->cur <= state->last) {1213const char*mail =am_path(state,msgnum(state));1214int apply_status;12151216if(!file_exists(mail))1217goto next;12181219if(resume) {1220validate_resume_state(state);1221 resume =0;1222}else{1223int skip;12241225if(state->rebasing)1226 skip =parse_mail_rebase(state, mail);1227else1228 skip =parse_mail(state, mail);12291230if(skip)1231goto next;/* mail should be skipped */12321233write_author_script(state);1234write_commit_msg(state);1235}12361237say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);12381239 apply_status =run_apply(state, NULL);12401241if(apply_status && state->threeway) {1242struct strbuf sb = STRBUF_INIT;12431244strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1245 apply_status =fall_back_threeway(state, sb.buf);1246strbuf_release(&sb);12471248/*1249 * Applying the patch to an earlier tree and merging1250 * the result may have produced the same tree as ours.1251 */1252if(!apply_status && !index_has_changes(NULL)) {1253say(state, stdout,_("No changes -- Patch already applied."));1254goto next;1255}1256}12571258if(apply_status) {1259int advice_amworkdir =1;12601261printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1262linelen(state->msg), state->msg);12631264git_config_get_bool("advice.amworkdir", &advice_amworkdir);12651266if(advice_amworkdir)1267printf_ln(_("The copy of the patch that failed is found in:%s"),1268am_path(state,"patch"));12691270die_user_resolve(state);1271}12721273do_commit(state);12741275next:1276am_next(state);1277}12781279/*1280 * In rebasing mode, it's up to the caller to take care of1281 * housekeeping.1282 */1283if(!state->rebasing) {1284am_destroy(state);1285run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1286}1287}12881289/**1290 * Resume the current am session after patch application failure. The user did1291 * all the hard work, and we do not have to do any patch application. Just1292 * trust and commit what the user has in the index and working tree.1293 */1294static voidam_resolve(struct am_state *state)1295{1296validate_resume_state(state);12971298say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);12991300if(!index_has_changes(NULL)) {1301printf_ln(_("No changes - did you forget to use 'git add'?\n"1302"If there is nothing left to stage, chances are that something else\n"1303"already introduced the same changes; you might want to skip this patch."));1304die_user_resolve(state);1305}13061307if(unmerged_cache()) {1308printf_ln(_("You still have unmerged paths in your index.\n"1309"Did you forget to use 'git add'?"));1310die_user_resolve(state);1311}13121313do_commit(state);13141315am_next(state);1316am_run(state,0);1317}13181319/**1320 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1321 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1322 * failure.1323 */1324static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1325{1326struct lock_file *lock_file;1327struct unpack_trees_options opts;1328struct tree_desc t[2];13291330if(parse_tree(head) ||parse_tree(remote))1331return-1;13321333 lock_file =xcalloc(1,sizeof(struct lock_file));1334hold_locked_index(lock_file,1);13351336refresh_cache(REFRESH_QUIET);13371338memset(&opts,0,sizeof(opts));1339 opts.head_idx =1;1340 opts.src_index = &the_index;1341 opts.dst_index = &the_index;1342 opts.update =1;1343 opts.merge =1;1344 opts.reset = reset;1345 opts.fn = twoway_merge;1346init_tree_desc(&t[0], head->buffer, head->size);1347init_tree_desc(&t[1], remote->buffer, remote->size);13481349if(unpack_trees(2, t, &opts)) {1350rollback_lock_file(lock_file);1351return-1;1352}13531354if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1355die(_("unable to write new index file"));13561357return0;1358}13591360/**1361 * Clean the index without touching entries that are not modified between1362 * `head` and `remote`.1363 */1364static intclean_index(const unsigned char*head,const unsigned char*remote)1365{1366struct lock_file *lock_file;1367struct tree *head_tree, *remote_tree, *index_tree;1368unsigned char index[GIT_SHA1_RAWSZ];1369struct pathspec pathspec;13701371 head_tree =parse_tree_indirect(head);1372if(!head_tree)1373returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));13741375 remote_tree =parse_tree_indirect(remote);1376if(!remote_tree)1377returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));13781379read_cache_unmerged();13801381if(fast_forward_to(head_tree, head_tree,1))1382return-1;13831384if(write_cache_as_tree(index,0, NULL))1385return-1;13861387 index_tree =parse_tree_indirect(index);1388if(!index_tree)1389returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));13901391if(fast_forward_to(index_tree, remote_tree,0))1392return-1;13931394memset(&pathspec,0,sizeof(pathspec));13951396 lock_file =xcalloc(1,sizeof(struct lock_file));1397hold_locked_index(lock_file,1);13981399if(read_tree(remote_tree,0, &pathspec)) {1400rollback_lock_file(lock_file);1401return-1;1402}14031404if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1405die(_("unable to write new index file"));14061407remove_branch_state();14081409return0;1410}14111412/**1413 * Resume the current am session by skipping the current patch.1414 */1415static voidam_skip(struct am_state *state)1416{1417unsigned char head[GIT_SHA1_RAWSZ];14181419if(get_sha1("HEAD", head))1420hashcpy(head, EMPTY_TREE_SHA1_BIN);14211422if(clean_index(head, head))1423die(_("failed to clean index"));14241425am_next(state);1426am_run(state,0);1427}14281429/**1430 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.1431 *1432 * It is not safe to reset HEAD when:1433 * 1. git-am previously failed because the index was dirty.1434 * 2. HEAD has moved since git-am previously failed.1435 */1436static intsafe_to_abort(const struct am_state *state)1437{1438struct strbuf sb = STRBUF_INIT;1439unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];14401441if(file_exists(am_path(state,"dirtyindex")))1442return0;14431444if(read_state_file(&sb, state,"abort-safety",1) >0) {1445if(get_sha1_hex(sb.buf, abort_safety))1446die(_("could not parse%s"),am_path(state,"abort_safety"));1447}else1448hashclr(abort_safety);14491450if(get_sha1("HEAD", head))1451hashclr(head);14521453if(!hashcmp(head, abort_safety))1454return1;14551456error(_("You seem to have moved HEAD since the last 'am' failure.\n"1457"Not rewinding to ORIG_HEAD"));14581459return0;1460}14611462/**1463 * Aborts the current am session if it is safe to do so.1464 */1465static voidam_abort(struct am_state *state)1466{1467unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];1468int has_curr_head, has_orig_head;1469char*curr_branch;14701471if(!safe_to_abort(state)) {1472am_destroy(state);1473return;1474}14751476 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);1477 has_curr_head = !is_null_sha1(curr_head);1478if(!has_curr_head)1479hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);14801481 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);1482if(!has_orig_head)1483hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);14841485clean_index(curr_head, orig_head);14861487if(has_orig_head)1488update_ref("am --abort","HEAD", orig_head,1489 has_curr_head ? curr_head : NULL,0,1490 UPDATE_REFS_DIE_ON_ERR);1491else if(curr_branch)1492delete_ref(curr_branch, NULL, REF_NODEREF);14931494free(curr_branch);1495am_destroy(state);1496}14971498/**1499 * parse_options() callback that validates and sets opt->value to the1500 * PATCH_FORMAT_* enum value corresponding to `arg`.1501 */1502static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)1503{1504int*opt_value = opt->value;15051506if(!strcmp(arg,"mbox"))1507*opt_value = PATCH_FORMAT_MBOX;1508else1509returnerror(_("Invalid value for --patch-format:%s"), arg);1510return0;1511}15121513enum resume_mode {1514 RESUME_FALSE =0,1515 RESUME_APPLY,1516 RESUME_RESOLVED,1517 RESUME_SKIP,1518 RESUME_ABORT1519};15201521intcmd_am(int argc,const char**argv,const char*prefix)1522{1523struct am_state state;1524int keep_cr = -1;1525int patch_format = PATCH_FORMAT_UNKNOWN;1526enum resume_mode resume = RESUME_FALSE;15271528const char*const usage[] = {1529N_("git am [options] [(<mbox>|<Maildir>)...]"),1530N_("git am [options] (--continue | --skip | --abort)"),1531 NULL1532};15331534struct option options[] = {1535OPT_BOOL('3',"3way", &state.threeway,1536N_("allow fall back on 3way merging if needed")),1537OPT__QUIET(&state.quiet,N_("be quiet")),1538OPT_BOOL('s',"signoff", &state.signoff,1539N_("add a Signed-off-by line to the commit message")),1540OPT_BOOL('u',"utf8", &state.utf8,1541N_("recode into utf8 (default)")),1542OPT_SET_INT('k',"keep", &state.keep,1543N_("pass -k flag to git-mailinfo"), KEEP_TRUE),1544OPT_SET_INT(0,"keep-non-patch", &state.keep,1545N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),1546OPT_BOOL('m',"message-id", &state.message_id,1547N_("pass -m flag to git-mailinfo")),1548{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,1549N_("pass --keep-cr flag to git-mailsplit for mbox format"),1550 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},1551{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,1552N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),1553 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},1554OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),1555N_("format the patch(es) are in"),1556 parse_opt_patchformat),1557OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,1558N_("override error message when patch failure occurs")),1559OPT_CMDMODE(0,"continue", &resume,1560N_("continue applying patches after resolving a conflict"),1561 RESUME_RESOLVED),1562OPT_CMDMODE('r',"resolved", &resume,1563N_("synonyms for --continue"),1564 RESUME_RESOLVED),1565OPT_CMDMODE(0,"skip", &resume,1566N_("skip the current patch"),1567 RESUME_SKIP),1568OPT_CMDMODE(0,"abort", &resume,1569N_("restore the original branch and abort the patching operation."),1570 RESUME_ABORT),1571OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,1572N_("(internal use for git-rebase)")),1573OPT_END()1574};15751576/*1577 * NEEDSWORK: Once all the features of git-am.sh have been1578 * re-implemented in builtin/am.c, this preamble can be removed.1579 */1580if(!getenv("_GIT_USE_BUILTIN_AM")) {1581const char*path =mkpath("%s/git-am",git_exec_path());15821583if(sane_execvp(path, (char**)argv) <0)1584die_errno("could not exec%s", path);1585}else{1586 prefix =setup_git_directory();1587trace_repo_setup(prefix);1588setup_work_tree();1589}15901591git_config(git_default_config, NULL);15921593am_state_init(&state,git_path("rebase-apply"));15941595 argc =parse_options(argc, argv, prefix, options, usage,0);15961597if(read_index_preload(&the_index, NULL) <0)1598die(_("failed to read the index"));15991600if(am_in_progress(&state)) {1601/*1602 * Catch user error to feed us patches when there is a session1603 * in progress:1604 *1605 * 1. mbox path(s) are provided on the command-line.1606 * 2. stdin is not a tty: the user is trying to feed us a patch1607 * from standard input. This is somewhat unreliable -- stdin1608 * could be /dev/null for example and the caller did not1609 * intend to feed us a patch but wanted to continue1610 * unattended.1611 */1612if(argc || (resume == RESUME_FALSE && !isatty(0)))1613die(_("previous rebase directory%sstill exists but mbox given."),1614 state.dir);16151616if(resume == RESUME_FALSE)1617 resume = RESUME_APPLY;16181619am_load(&state);1620}else{1621struct argv_array paths = ARGV_ARRAY_INIT;1622int i;16231624/*1625 * Handle stray state directory in the independent-run case. In1626 * the --rebasing case, it is up to the caller to take care of1627 * stray directories.1628 */1629if(file_exists(state.dir) && !state.rebasing) {1630if(resume == RESUME_ABORT) {1631am_destroy(&state);1632am_state_release(&state);1633return0;1634}16351636die(_("Stray%sdirectory found.\n"1637"Use\"git am --abort\"to remove it."),1638 state.dir);1639}16401641if(resume)1642die(_("Resolve operation not in progress, we are not resuming."));16431644for(i =0; i < argc; i++) {1645if(is_absolute_path(argv[i]) || !prefix)1646argv_array_push(&paths, argv[i]);1647else1648argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));1649}16501651am_setup(&state, patch_format, paths.argv, keep_cr);16521653argv_array_clear(&paths);1654}16551656switch(resume) {1657case RESUME_FALSE:1658am_run(&state,0);1659break;1660case RESUME_APPLY:1661am_run(&state,1);1662break;1663case RESUME_RESOLVED:1664am_resolve(&state);1665break;1666case RESUME_SKIP:1667am_skip(&state);1668break;1669case RESUME_ABORT:1670am_abort(&state);1671break;1672default:1673die("BUG: invalid resume value");1674}16751676am_state_release(&state);16771678return0;1679}