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 */ 101const char*resolvemsg; 102int rebasing; 103}; 104 105/** 106 * Initializes am_state with the default values. The state directory is set to 107 * dir. 108 */ 109static voidam_state_init(struct am_state *state,const char*dir) 110{ 111memset(state,0,sizeof(*state)); 112 113assert(dir); 114 state->dir =xstrdup(dir); 115 116 state->prec =4; 117 118 state->utf8 =1; 119} 120 121/** 122 * Releases memory allocated by an am_state. 123 */ 124static voidam_state_release(struct am_state *state) 125{ 126free(state->dir); 127free(state->author_name); 128free(state->author_email); 129free(state->author_date); 130free(state->msg); 131} 132 133/** 134 * Returns path relative to the am_state directory. 135 */ 136staticinlineconst char*am_path(const struct am_state *state,const char*path) 137{ 138returnmkpath("%s/%s", state->dir, path); 139} 140 141/** 142 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 143 * at the end. 144 */ 145static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 146{ 147va_list ap; 148 149va_start(ap, fmt); 150if(!state->quiet) { 151vfprintf(fp, fmt, ap); 152putc('\n', fp); 153} 154va_end(ap); 155} 156 157/** 158 * Returns 1 if there is an am session in progress, 0 otherwise. 159 */ 160static intam_in_progress(const struct am_state *state) 161{ 162struct stat st; 163 164if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 165return0; 166if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 167return0; 168if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 169return0; 170return1; 171} 172 173/** 174 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 175 * number of bytes read on success, -1 if the file does not exist. If `trim` is 176 * set, trailing whitespace will be removed. 177 */ 178static intread_state_file(struct strbuf *sb,const struct am_state *state, 179const char*file,int trim) 180{ 181strbuf_reset(sb); 182 183if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 184if(trim) 185strbuf_trim(sb); 186 187return sb->len; 188} 189 190if(errno == ENOENT) 191return-1; 192 193die_errno(_("could not read '%s'"),am_path(state, file)); 194} 195 196/** 197 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 198 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 199 * match `key`. Returns NULL on failure. 200 * 201 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 202 * the author-script. 203 */ 204static char*read_shell_var(FILE*fp,const char*key) 205{ 206struct strbuf sb = STRBUF_INIT; 207const char*str; 208 209if(strbuf_getline(&sb, fp,'\n')) 210goto fail; 211 212if(!skip_prefix(sb.buf, key, &str)) 213goto fail; 214 215if(!skip_prefix(str,"=", &str)) 216goto fail; 217 218strbuf_remove(&sb,0, str - sb.buf); 219 220 str =sq_dequote(sb.buf); 221if(!str) 222goto fail; 223 224returnstrbuf_detach(&sb, NULL); 225 226fail: 227strbuf_release(&sb); 228return NULL; 229} 230 231/** 232 * Reads and parses the state directory's "author-script" file, and sets 233 * state->author_name, state->author_email and state->author_date accordingly. 234 * Returns 0 on success, -1 if the file could not be parsed. 235 * 236 * The author script is of the format: 237 * 238 * GIT_AUTHOR_NAME='$author_name' 239 * GIT_AUTHOR_EMAIL='$author_email' 240 * GIT_AUTHOR_DATE='$author_date' 241 * 242 * where $author_name, $author_email and $author_date are quoted. We are strict 243 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 244 * script, and thus if the file differs from what this function expects, it is 245 * better to bail out than to do something that the user does not expect. 246 */ 247static intread_author_script(struct am_state *state) 248{ 249const char*filename =am_path(state,"author-script"); 250FILE*fp; 251 252assert(!state->author_name); 253assert(!state->author_email); 254assert(!state->author_date); 255 256 fp =fopen(filename,"r"); 257if(!fp) { 258if(errno == ENOENT) 259return0; 260die_errno(_("could not open '%s' for reading"), filename); 261} 262 263 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 264if(!state->author_name) { 265fclose(fp); 266return-1; 267} 268 269 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 270if(!state->author_email) { 271fclose(fp); 272return-1; 273} 274 275 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 276if(!state->author_date) { 277fclose(fp); 278return-1; 279} 280 281if(fgetc(fp) != EOF) { 282fclose(fp); 283return-1; 284} 285 286fclose(fp); 287return0; 288} 289 290/** 291 * Saves state->author_name, state->author_email and state->author_date in the 292 * state directory's "author-script" file. 293 */ 294static voidwrite_author_script(const struct am_state *state) 295{ 296struct strbuf sb = STRBUF_INIT; 297 298strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 299sq_quote_buf(&sb, state->author_name); 300strbuf_addch(&sb,'\n'); 301 302strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 303sq_quote_buf(&sb, state->author_email); 304strbuf_addch(&sb,'\n'); 305 306strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 307sq_quote_buf(&sb, state->author_date); 308strbuf_addch(&sb,'\n'); 309 310write_file(am_path(state,"author-script"),1,"%s", sb.buf); 311 312strbuf_release(&sb); 313} 314 315/** 316 * Reads the commit message from the state directory's "final-commit" file, 317 * setting state->msg to its contents and state->msg_len to the length of its 318 * contents in bytes. 319 * 320 * Returns 0 on success, -1 if the file does not exist. 321 */ 322static intread_commit_msg(struct am_state *state) 323{ 324struct strbuf sb = STRBUF_INIT; 325 326assert(!state->msg); 327 328if(read_state_file(&sb, state,"final-commit",0) <0) { 329strbuf_release(&sb); 330return-1; 331} 332 333 state->msg =strbuf_detach(&sb, &state->msg_len); 334return0; 335} 336 337/** 338 * Saves state->msg in the state directory's "final-commit" file. 339 */ 340static voidwrite_commit_msg(const struct am_state *state) 341{ 342int fd; 343const char*filename =am_path(state,"final-commit"); 344 345 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 346if(write_in_full(fd, state->msg, state->msg_len) <0) 347die_errno(_("could not write to%s"), filename); 348close(fd); 349} 350 351/** 352 * Loads state from disk. 353 */ 354static voidam_load(struct am_state *state) 355{ 356struct strbuf sb = STRBUF_INIT; 357 358if(read_state_file(&sb, state,"next",1) <0) 359die("BUG: state file 'next' does not exist"); 360 state->cur =strtol(sb.buf, NULL,10); 361 362if(read_state_file(&sb, state,"last",1) <0) 363die("BUG: state file 'last' does not exist"); 364 state->last =strtol(sb.buf, NULL,10); 365 366if(read_author_script(state) <0) 367die(_("could not parse author script")); 368 369read_commit_msg(state); 370 371read_state_file(&sb, state,"threeway",1); 372 state->threeway = !strcmp(sb.buf,"t"); 373 374read_state_file(&sb, state,"quiet",1); 375 state->quiet = !strcmp(sb.buf,"t"); 376 377read_state_file(&sb, state,"sign",1); 378 state->signoff = !strcmp(sb.buf,"t"); 379 380read_state_file(&sb, state,"utf8",1); 381 state->utf8 = !strcmp(sb.buf,"t"); 382 383read_state_file(&sb, state,"keep",1); 384if(!strcmp(sb.buf,"t")) 385 state->keep = KEEP_TRUE; 386else if(!strcmp(sb.buf,"b")) 387 state->keep = KEEP_NON_PATCH; 388else 389 state->keep = KEEP_FALSE; 390 391 state->rebasing = !!file_exists(am_path(state,"rebasing")); 392 393strbuf_release(&sb); 394} 395 396/** 397 * Removes the am_state directory, forcefully terminating the current am 398 * session. 399 */ 400static voidam_destroy(const struct am_state *state) 401{ 402struct strbuf sb = STRBUF_INIT; 403 404strbuf_addstr(&sb, state->dir); 405remove_dir_recursively(&sb,0); 406strbuf_release(&sb); 407} 408 409/** 410 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 411 * non-indented lines and checking if they look like they begin with valid 412 * header field names. 413 * 414 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 415 */ 416static intis_mail(FILE*fp) 417{ 418const char*header_regex ="^[!-9;-~]+:"; 419struct strbuf sb = STRBUF_INIT; 420 regex_t regex; 421int ret =1; 422 423if(fseek(fp,0L, SEEK_SET)) 424die_errno(_("fseek failed")); 425 426if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 427die("invalid pattern:%s", header_regex); 428 429while(!strbuf_getline_crlf(&sb, fp)) { 430if(!sb.len) 431break;/* End of header */ 432 433/* Ignore indented folded lines */ 434if(*sb.buf =='\t'|| *sb.buf ==' ') 435continue; 436 437/* It's a header if it matches header_regex */ 438if(regexec(®ex, sb.buf,0, NULL,0)) { 439 ret =0; 440goto done; 441} 442} 443 444done: 445regfree(®ex); 446strbuf_release(&sb); 447return ret; 448} 449 450/** 451 * Attempts to detect the patch_format of the patches contained in `paths`, 452 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 453 * detection fails. 454 */ 455static intdetect_patch_format(const char**paths) 456{ 457enum patch_format ret = PATCH_FORMAT_UNKNOWN; 458struct strbuf l1 = STRBUF_INIT; 459FILE*fp; 460 461/* 462 * We default to mbox format if input is from stdin and for directories 463 */ 464if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 465return PATCH_FORMAT_MBOX; 466 467/* 468 * Otherwise, check the first few lines of the first patch, starting 469 * from the first non-blank line, to try to detect its format. 470 */ 471 472 fp =xfopen(*paths,"r"); 473 474while(!strbuf_getline_crlf(&l1, fp)) { 475if(l1.len) 476break; 477} 478 479if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 480 ret = PATCH_FORMAT_MBOX; 481goto done; 482} 483 484if(l1.len &&is_mail(fp)) { 485 ret = PATCH_FORMAT_MBOX; 486goto done; 487} 488 489done: 490fclose(fp); 491strbuf_release(&l1); 492return ret; 493} 494 495/** 496 * Splits out individual email patches from `paths`, where each path is either 497 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 498 */ 499static intsplit_mail_mbox(struct am_state *state,const char**paths) 500{ 501struct child_process cp = CHILD_PROCESS_INIT; 502struct strbuf last = STRBUF_INIT; 503 504 cp.git_cmd =1; 505argv_array_push(&cp.args,"mailsplit"); 506argv_array_pushf(&cp.args,"-d%d", state->prec); 507argv_array_pushf(&cp.args,"-o%s", state->dir); 508argv_array_push(&cp.args,"-b"); 509argv_array_push(&cp.args,"--"); 510argv_array_pushv(&cp.args, paths); 511 512if(capture_command(&cp, &last,8)) 513return-1; 514 515 state->cur =1; 516 state->last =strtol(last.buf, NULL,10); 517 518return0; 519} 520 521/** 522 * Splits a list of files/directories into individual email patches. Each path 523 * in `paths` must be a file/directory that is formatted according to 524 * `patch_format`. 525 * 526 * Once split out, the individual email patches will be stored in the state 527 * directory, with each patch's filename being its index, padded to state->prec 528 * digits. 529 * 530 * state->cur will be set to the index of the first mail, and state->last will 531 * be set to the index of the last mail. 532 * 533 * Returns 0 on success, -1 on failure. 534 */ 535static intsplit_mail(struct am_state *state,enum patch_format patch_format, 536const char**paths) 537{ 538switch(patch_format) { 539case PATCH_FORMAT_MBOX: 540returnsplit_mail_mbox(state, paths); 541default: 542die("BUG: invalid patch_format"); 543} 544return-1; 545} 546 547/** 548 * Setup a new am session for applying patches 549 */ 550static voidam_setup(struct am_state *state,enum patch_format patch_format, 551const char**paths) 552{ 553unsigned char curr_head[GIT_SHA1_RAWSZ]; 554const char*str; 555 556if(!patch_format) 557 patch_format =detect_patch_format(paths); 558 559if(!patch_format) { 560fprintf_ln(stderr,_("Patch format detection failed.")); 561exit(128); 562} 563 564if(mkdir(state->dir,0777) <0&& errno != EEXIST) 565die_errno(_("failed to create directory '%s'"), state->dir); 566 567if(split_mail(state, patch_format, paths) <0) { 568am_destroy(state); 569die(_("Failed to split patches.")); 570} 571 572if(state->rebasing) 573 state->threeway =1; 574 575write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f"); 576 577write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f"); 578 579write_file(am_path(state,"sign"),1, state->signoff ?"t":"f"); 580 581write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f"); 582 583switch(state->keep) { 584case KEEP_FALSE: 585 str ="f"; 586break; 587case KEEP_TRUE: 588 str ="t"; 589break; 590case KEEP_NON_PATCH: 591 str ="b"; 592break; 593default: 594die("BUG: invalid value for state->keep"); 595} 596 597write_file(am_path(state,"keep"),1,"%s", str); 598 599if(state->rebasing) 600write_file(am_path(state,"rebasing"),1,"%s",""); 601else 602write_file(am_path(state,"applying"),1,"%s",""); 603 604if(!get_sha1("HEAD", curr_head)) { 605write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head)); 606if(!state->rebasing) 607update_ref("am","ORIG_HEAD", curr_head, NULL,0, 608 UPDATE_REFS_DIE_ON_ERR); 609}else{ 610write_file(am_path(state,"abort-safety"),1,"%s",""); 611if(!state->rebasing) 612delete_ref("ORIG_HEAD", NULL,0); 613} 614 615/* 616 * NOTE: Since the "next" and "last" files determine if an am_state 617 * session is in progress, they should be written last. 618 */ 619 620write_file(am_path(state,"next"),1,"%d", state->cur); 621 622write_file(am_path(state,"last"),1,"%d", state->last); 623} 624 625/** 626 * Increments the patch pointer, and cleans am_state for the application of the 627 * next patch. 628 */ 629static voidam_next(struct am_state *state) 630{ 631unsigned char head[GIT_SHA1_RAWSZ]; 632 633free(state->author_name); 634 state->author_name = NULL; 635 636free(state->author_email); 637 state->author_email = NULL; 638 639free(state->author_date); 640 state->author_date = NULL; 641 642free(state->msg); 643 state->msg = NULL; 644 state->msg_len =0; 645 646unlink(am_path(state,"author-script")); 647unlink(am_path(state,"final-commit")); 648 649if(!get_sha1("HEAD", head)) 650write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head)); 651else 652write_file(am_path(state,"abort-safety"),1,"%s",""); 653 654 state->cur++; 655write_file(am_path(state,"next"),1,"%d", state->cur); 656} 657 658/** 659 * Returns the filename of the current patch email. 660 */ 661static const char*msgnum(const struct am_state *state) 662{ 663static struct strbuf sb = STRBUF_INIT; 664 665strbuf_reset(&sb); 666strbuf_addf(&sb,"%0*d", state->prec, state->cur); 667 668return sb.buf; 669} 670 671/** 672 * Refresh and write index. 673 */ 674static voidrefresh_and_write_cache(void) 675{ 676struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file)); 677 678hold_locked_index(lock_file,1); 679refresh_cache(REFRESH_QUIET); 680if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 681die(_("unable to write index file")); 682} 683 684/** 685 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn 686 * branch, returns 1 if there are entries in the index, 0 otherwise. If an 687 * strbuf is provided, the space-separated list of files that differ will be 688 * appended to it. 689 */ 690static intindex_has_changes(struct strbuf *sb) 691{ 692unsigned char head[GIT_SHA1_RAWSZ]; 693int i; 694 695if(!get_sha1_tree("HEAD", head)) { 696struct diff_options opt; 697 698diff_setup(&opt); 699DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); 700if(!sb) 701DIFF_OPT_SET(&opt, QUICK); 702do_diff_cache(head, &opt); 703diffcore_std(&opt); 704for(i =0; sb && i < diff_queued_diff.nr; i++) { 705if(i) 706strbuf_addch(sb,' '); 707strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); 708} 709diff_flush(&opt); 710returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0; 711}else{ 712for(i =0; sb && i < active_nr; i++) { 713if(i) 714strbuf_addch(sb,' '); 715strbuf_addstr(sb, active_cache[i]->name); 716} 717return!!active_nr; 718} 719} 720 721/** 722 * Dies with a user-friendly message on how to proceed after resolving the 723 * problem. This message can be overridden with state->resolvemsg. 724 */ 725static void NORETURN die_user_resolve(const struct am_state *state) 726{ 727if(state->resolvemsg) { 728printf_ln("%s", state->resolvemsg); 729}else{ 730const char*cmdline ="git am"; 731 732printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline); 733printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline); 734printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline); 735} 736 737exit(128); 738} 739 740/** 741 * Parses `mail` using git-mailinfo, extracting its patch and authorship info. 742 * state->msg will be set to the patch message. state->author_name, 743 * state->author_email and state->author_date will be set to the patch author's 744 * name, email and date respectively. The patch body will be written to the 745 * state directory's "patch" file. 746 * 747 * Returns 1 if the patch should be skipped, 0 otherwise. 748 */ 749static intparse_mail(struct am_state *state,const char*mail) 750{ 751FILE*fp; 752struct child_process cp = CHILD_PROCESS_INIT; 753struct strbuf sb = STRBUF_INIT; 754struct strbuf msg = STRBUF_INIT; 755struct strbuf author_name = STRBUF_INIT; 756struct strbuf author_date = STRBUF_INIT; 757struct strbuf author_email = STRBUF_INIT; 758int ret =0; 759 760 cp.git_cmd =1; 761 cp.in =xopen(mail, O_RDONLY,0); 762 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777); 763 764argv_array_push(&cp.args,"mailinfo"); 765argv_array_push(&cp.args, state->utf8 ?"-u":"-n"); 766 767switch(state->keep) { 768case KEEP_FALSE: 769break; 770case KEEP_TRUE: 771argv_array_push(&cp.args,"-k"); 772break; 773case KEEP_NON_PATCH: 774argv_array_push(&cp.args,"-b"); 775break; 776default: 777die("BUG: invalid value for state->keep"); 778} 779 780argv_array_push(&cp.args,am_path(state,"msg")); 781argv_array_push(&cp.args,am_path(state,"patch")); 782 783if(run_command(&cp) <0) 784die("could not parse patch"); 785 786close(cp.in); 787close(cp.out); 788 789/* Extract message and author information */ 790 fp =xfopen(am_path(state,"info"),"r"); 791while(!strbuf_getline(&sb, fp,'\n')) { 792const char*x; 793 794if(skip_prefix(sb.buf,"Subject: ", &x)) { 795if(msg.len) 796strbuf_addch(&msg,'\n'); 797strbuf_addstr(&msg, x); 798}else if(skip_prefix(sb.buf,"Author: ", &x)) 799strbuf_addstr(&author_name, x); 800else if(skip_prefix(sb.buf,"Email: ", &x)) 801strbuf_addstr(&author_email, x); 802else if(skip_prefix(sb.buf,"Date: ", &x)) 803strbuf_addstr(&author_date, x); 804} 805fclose(fp); 806 807/* Skip pine's internal folder data */ 808if(!strcmp(author_name.buf,"Mail System Internal Data")) { 809 ret =1; 810goto finish; 811} 812 813if(is_empty_file(am_path(state,"patch"))) { 814printf_ln(_("Patch is empty. Was it split wrong?")); 815die_user_resolve(state); 816} 817 818strbuf_addstr(&msg,"\n\n"); 819if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0) 820die_errno(_("could not read '%s'"),am_path(state,"msg")); 821stripspace(&msg,0); 822 823if(state->signoff) 824append_signoff(&msg,0,0); 825 826assert(!state->author_name); 827 state->author_name =strbuf_detach(&author_name, NULL); 828 829assert(!state->author_email); 830 state->author_email =strbuf_detach(&author_email, NULL); 831 832assert(!state->author_date); 833 state->author_date =strbuf_detach(&author_date, NULL); 834 835assert(!state->msg); 836 state->msg =strbuf_detach(&msg, &state->msg_len); 837 838finish: 839strbuf_release(&msg); 840strbuf_release(&author_date); 841strbuf_release(&author_email); 842strbuf_release(&author_name); 843strbuf_release(&sb); 844return ret; 845} 846 847/** 848 * Sets commit_id to the commit hash where the mail was generated from. 849 * Returns 0 on success, -1 on failure. 850 */ 851static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail) 852{ 853struct strbuf sb = STRBUF_INIT; 854FILE*fp =xfopen(mail,"r"); 855const char*x; 856 857if(strbuf_getline(&sb, fp,'\n')) 858return-1; 859 860if(!skip_prefix(sb.buf,"From ", &x)) 861return-1; 862 863if(get_sha1_hex(x, commit_id) <0) 864return-1; 865 866strbuf_release(&sb); 867fclose(fp); 868return0; 869} 870 871/** 872 * Sets state->msg, state->author_name, state->author_email, state->author_date 873 * to the commit's respective info. 874 */ 875static voidget_commit_info(struct am_state *state,struct commit *commit) 876{ 877const char*buffer, *ident_line, *author_date, *msg; 878size_t ident_len; 879struct ident_split ident_split; 880struct strbuf sb = STRBUF_INIT; 881 882 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding()); 883 884 ident_line =find_commit_header(buffer,"author", &ident_len); 885 886if(split_ident_line(&ident_split, ident_line, ident_len) <0) { 887strbuf_add(&sb, ident_line, ident_len); 888die(_("invalid ident line:%s"), sb.buf); 889} 890 891assert(!state->author_name); 892if(ident_split.name_begin) { 893strbuf_add(&sb, ident_split.name_begin, 894 ident_split.name_end - ident_split.name_begin); 895 state->author_name =strbuf_detach(&sb, NULL); 896}else 897 state->author_name =xstrdup(""); 898 899assert(!state->author_email); 900if(ident_split.mail_begin) { 901strbuf_add(&sb, ident_split.mail_begin, 902 ident_split.mail_end - ident_split.mail_begin); 903 state->author_email =strbuf_detach(&sb, NULL); 904}else 905 state->author_email =xstrdup(""); 906 907 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL)); 908strbuf_addstr(&sb, author_date); 909assert(!state->author_date); 910 state->author_date =strbuf_detach(&sb, NULL); 911 912assert(!state->msg); 913 msg =strstr(buffer,"\n\n"); 914if(!msg) 915die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1)); 916 state->msg =xstrdup(msg +2); 917 state->msg_len =strlen(state->msg); 918} 919 920/** 921 * Writes `commit` as a patch to the state directory's "patch" file. 922 */ 923static voidwrite_commit_patch(const struct am_state *state,struct commit *commit) 924{ 925struct rev_info rev_info; 926FILE*fp; 927 928 fp =xfopen(am_path(state,"patch"),"w"); 929init_revisions(&rev_info, NULL); 930 rev_info.diff =1; 931 rev_info.abbrev =0; 932 rev_info.disable_stdin =1; 933 rev_info.show_root_diff =1; 934 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; 935 rev_info.no_commit_id =1; 936DIFF_OPT_SET(&rev_info.diffopt, BINARY); 937DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX); 938 rev_info.diffopt.use_color =0; 939 rev_info.diffopt.file = fp; 940 rev_info.diffopt.close_file =1; 941add_pending_object(&rev_info, &commit->object,""); 942diff_setup_done(&rev_info.diffopt); 943log_tree_commit(&rev_info, commit); 944} 945 946/** 947 * Like parse_mail(), but parses the mail by looking up its commit ID 948 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging 949 * of patches. 950 * 951 * Will always return 0 as the patch should never be skipped. 952 */ 953static intparse_mail_rebase(struct am_state *state,const char*mail) 954{ 955struct commit *commit; 956unsigned char commit_sha1[GIT_SHA1_RAWSZ]; 957 958if(get_mail_commit_sha1(commit_sha1, mail) <0) 959die(_("could not parse%s"), mail); 960 961 commit =lookup_commit_or_die(commit_sha1, mail); 962 963get_commit_info(state, commit); 964 965write_commit_patch(state, commit); 966 967return0; 968} 969 970/** 971 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If 972 * `index_file` is not NULL, the patch will be applied to that index. 973 */ 974static intrun_apply(const struct am_state *state,const char*index_file) 975{ 976struct child_process cp = CHILD_PROCESS_INIT; 977 978 cp.git_cmd =1; 979 980if(index_file) 981argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file); 982 983/* 984 * If we are allowed to fall back on 3-way merge, don't give false 985 * errors during the initial attempt. 986 */ 987if(state->threeway && !index_file) { 988 cp.no_stdout =1; 989 cp.no_stderr =1; 990} 991 992argv_array_push(&cp.args,"apply"); 993 994if(index_file) 995argv_array_push(&cp.args,"--cached"); 996else 997argv_array_push(&cp.args,"--index"); 998 999argv_array_push(&cp.args,am_path(state,"patch"));10001001if(run_command(&cp))1002return-1;10031004/* Reload index as git-apply will have modified it. */1005discard_cache();1006read_cache_from(index_file ? index_file :get_index_file());10071008return0;1009}10101011/**1012 * Builds an index that contains just the blobs needed for a 3way merge.1013 */1014static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1015{1016struct child_process cp = CHILD_PROCESS_INIT;10171018 cp.git_cmd =1;1019argv_array_push(&cp.args,"apply");1020argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1021argv_array_push(&cp.args,am_path(state,"patch"));10221023if(run_command(&cp))1024return-1;10251026return0;1027}10281029/**1030 * Attempt a threeway merge, using index_path as the temporary index.1031 */1032static intfall_back_threeway(const struct am_state *state,const char*index_path)1033{1034unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1035 our_tree[GIT_SHA1_RAWSZ];1036const unsigned char*bases[1] = {orig_tree};1037struct merge_options o;1038struct commit *result;1039char*his_tree_name;10401041if(get_sha1("HEAD", our_tree) <0)1042hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);10431044if(build_fake_ancestor(state, index_path))1045returnerror("could not build fake ancestor");10461047discard_cache();1048read_cache_from(index_path);10491050if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1051returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));10521053say(state, stdout,_("Using index info to reconstruct a base tree..."));10541055if(!state->quiet) {1056/*1057 * List paths that needed 3-way fallback, so that the user can1058 * review them with extra care to spot mismerges.1059 */1060struct rev_info rev_info;1061const char*diff_filter_str ="--diff-filter=AM";10621063init_revisions(&rev_info, NULL);1064 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1065diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1066add_pending_sha1(&rev_info,"HEAD", our_tree,0);1067diff_setup_done(&rev_info.diffopt);1068run_diff_index(&rev_info,1);1069}10701071if(run_apply(state, index_path))1072returnerror(_("Did you hand edit your patch?\n"1073"It does not apply to blobs recorded in its index."));10741075if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1076returnerror("could not write tree");10771078say(state, stdout,_("Falling back to patching base and 3-way merge..."));10791080discard_cache();1081read_cache();10821083/*1084 * This is not so wrong. Depending on which base we picked, orig_tree1085 * may be wildly different from ours, but his_tree has the same set of1086 * wildly different changes in parts the patch did not touch, so1087 * recursive ends up canceling them, saying that we reverted all those1088 * changes.1089 */10901091init_merge_options(&o);10921093 o.branch1 ="HEAD";1094 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1095 o.branch2 = his_tree_name;10961097if(state->quiet)1098 o.verbosity =0;10991100if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1101free(his_tree_name);1102returnerror(_("Failed to merge in the changes."));1103}11041105free(his_tree_name);1106return0;1107}11081109/**1110 * Commits the current index with state->msg as the commit message and1111 * state->author_name, state->author_email and state->author_date as the author1112 * information.1113 */1114static voiddo_commit(const struct am_state *state)1115{1116unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1117 commit[GIT_SHA1_RAWSZ];1118unsigned char*ptr;1119struct commit_list *parents = NULL;1120const char*reflog_msg, *author;1121struct strbuf sb = STRBUF_INIT;11221123if(write_cache_as_tree(tree,0, NULL))1124die(_("git write-tree failed to write a tree"));11251126if(!get_sha1_commit("HEAD", parent)) {1127 ptr = parent;1128commit_list_insert(lookup_commit(parent), &parents);1129}else{1130 ptr = NULL;1131say(state, stderr,_("applying to an empty history"));1132}11331134 author =fmt_ident(state->author_name, state->author_email,1135 state->author_date, IDENT_STRICT);11361137if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1138 author, NULL))1139die(_("failed to write commit object"));11401141 reflog_msg =getenv("GIT_REFLOG_ACTION");1142if(!reflog_msg)1143 reflog_msg ="am";11441145strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1146 state->msg);11471148update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);11491150strbuf_release(&sb);1151}11521153/**1154 * Validates the am_state for resuming -- the "msg" and authorship fields must1155 * be filled up.1156 */1157static voidvalidate_resume_state(const struct am_state *state)1158{1159if(!state->msg)1160die(_("cannot resume:%sdoes not exist."),1161am_path(state,"final-commit"));11621163if(!state->author_name || !state->author_email || !state->author_date)1164die(_("cannot resume:%sdoes not exist."),1165am_path(state,"author-script"));1166}11671168/**1169 * Applies all queued mail.1170 *1171 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1172 * well as the state directory's "patch" file is used as-is for applying the1173 * patch and committing it.1174 */1175static voidam_run(struct am_state *state,int resume)1176{1177const char*argv_gc_auto[] = {"gc","--auto", NULL};1178struct strbuf sb = STRBUF_INIT;11791180unlink(am_path(state,"dirtyindex"));11811182refresh_and_write_cache();11831184if(index_has_changes(&sb)) {1185write_file(am_path(state,"dirtyindex"),1,"t");1186die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1187}11881189strbuf_release(&sb);11901191while(state->cur <= state->last) {1192const char*mail =am_path(state,msgnum(state));1193int apply_status;11941195if(!file_exists(mail))1196goto next;11971198if(resume) {1199validate_resume_state(state);1200 resume =0;1201}else{1202int skip;12031204if(state->rebasing)1205 skip =parse_mail_rebase(state, mail);1206else1207 skip =parse_mail(state, mail);12081209if(skip)1210goto next;/* mail should be skipped */12111212write_author_script(state);1213write_commit_msg(state);1214}12151216say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);12171218 apply_status =run_apply(state, NULL);12191220if(apply_status && state->threeway) {1221struct strbuf sb = STRBUF_INIT;12221223strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1224 apply_status =fall_back_threeway(state, sb.buf);1225strbuf_release(&sb);12261227/*1228 * Applying the patch to an earlier tree and merging1229 * the result may have produced the same tree as ours.1230 */1231if(!apply_status && !index_has_changes(NULL)) {1232say(state, stdout,_("No changes -- Patch already applied."));1233goto next;1234}1235}12361237if(apply_status) {1238int advice_amworkdir =1;12391240printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1241linelen(state->msg), state->msg);12421243git_config_get_bool("advice.amworkdir", &advice_amworkdir);12441245if(advice_amworkdir)1246printf_ln(_("The copy of the patch that failed is found in:%s"),1247am_path(state,"patch"));12481249die_user_resolve(state);1250}12511252do_commit(state);12531254next:1255am_next(state);1256}12571258/*1259 * In rebasing mode, it's up to the caller to take care of1260 * housekeeping.1261 */1262if(!state->rebasing) {1263am_destroy(state);1264run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1265}1266}12671268/**1269 * Resume the current am session after patch application failure. The user did1270 * all the hard work, and we do not have to do any patch application. Just1271 * trust and commit what the user has in the index and working tree.1272 */1273static voidam_resolve(struct am_state *state)1274{1275validate_resume_state(state);12761277say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);12781279if(!index_has_changes(NULL)) {1280printf_ln(_("No changes - did you forget to use 'git add'?\n"1281"If there is nothing left to stage, chances are that something else\n"1282"already introduced the same changes; you might want to skip this patch."));1283die_user_resolve(state);1284}12851286if(unmerged_cache()) {1287printf_ln(_("You still have unmerged paths in your index.\n"1288"Did you forget to use 'git add'?"));1289die_user_resolve(state);1290}12911292do_commit(state);12931294am_next(state);1295am_run(state,0);1296}12971298/**1299 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1300 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1301 * failure.1302 */1303static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1304{1305struct lock_file *lock_file;1306struct unpack_trees_options opts;1307struct tree_desc t[2];13081309if(parse_tree(head) ||parse_tree(remote))1310return-1;13111312 lock_file =xcalloc(1,sizeof(struct lock_file));1313hold_locked_index(lock_file,1);13141315refresh_cache(REFRESH_QUIET);13161317memset(&opts,0,sizeof(opts));1318 opts.head_idx =1;1319 opts.src_index = &the_index;1320 opts.dst_index = &the_index;1321 opts.update =1;1322 opts.merge =1;1323 opts.reset = reset;1324 opts.fn = twoway_merge;1325init_tree_desc(&t[0], head->buffer, head->size);1326init_tree_desc(&t[1], remote->buffer, remote->size);13271328if(unpack_trees(2, t, &opts)) {1329rollback_lock_file(lock_file);1330return-1;1331}13321333if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1334die(_("unable to write new index file"));13351336return0;1337}13381339/**1340 * Clean the index without touching entries that are not modified between1341 * `head` and `remote`.1342 */1343static intclean_index(const unsigned char*head,const unsigned char*remote)1344{1345struct lock_file *lock_file;1346struct tree *head_tree, *remote_tree, *index_tree;1347unsigned char index[GIT_SHA1_RAWSZ];1348struct pathspec pathspec;13491350 head_tree =parse_tree_indirect(head);1351if(!head_tree)1352returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));13531354 remote_tree =parse_tree_indirect(remote);1355if(!remote_tree)1356returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));13571358read_cache_unmerged();13591360if(fast_forward_to(head_tree, head_tree,1))1361return-1;13621363if(write_cache_as_tree(index,0, NULL))1364return-1;13651366 index_tree =parse_tree_indirect(index);1367if(!index_tree)1368returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));13691370if(fast_forward_to(index_tree, remote_tree,0))1371return-1;13721373memset(&pathspec,0,sizeof(pathspec));13741375 lock_file =xcalloc(1,sizeof(struct lock_file));1376hold_locked_index(lock_file,1);13771378if(read_tree(remote_tree,0, &pathspec)) {1379rollback_lock_file(lock_file);1380return-1;1381}13821383if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1384die(_("unable to write new index file"));13851386remove_branch_state();13871388return0;1389}13901391/**1392 * Resume the current am session by skipping the current patch.1393 */1394static voidam_skip(struct am_state *state)1395{1396unsigned char head[GIT_SHA1_RAWSZ];13971398if(get_sha1("HEAD", head))1399hashcpy(head, EMPTY_TREE_SHA1_BIN);14001401if(clean_index(head, head))1402die(_("failed to clean index"));14031404am_next(state);1405am_run(state,0);1406}14071408/**1409 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.1410 *1411 * It is not safe to reset HEAD when:1412 * 1. git-am previously failed because the index was dirty.1413 * 2. HEAD has moved since git-am previously failed.1414 */1415static intsafe_to_abort(const struct am_state *state)1416{1417struct strbuf sb = STRBUF_INIT;1418unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];14191420if(file_exists(am_path(state,"dirtyindex")))1421return0;14221423if(read_state_file(&sb, state,"abort-safety",1) >0) {1424if(get_sha1_hex(sb.buf, abort_safety))1425die(_("could not parse%s"),am_path(state,"abort_safety"));1426}else1427hashclr(abort_safety);14281429if(get_sha1("HEAD", head))1430hashclr(head);14311432if(!hashcmp(head, abort_safety))1433return1;14341435error(_("You seem to have moved HEAD since the last 'am' failure.\n"1436"Not rewinding to ORIG_HEAD"));14371438return0;1439}14401441/**1442 * Aborts the current am session if it is safe to do so.1443 */1444static voidam_abort(struct am_state *state)1445{1446unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];1447int has_curr_head, has_orig_head;1448char*curr_branch;14491450if(!safe_to_abort(state)) {1451am_destroy(state);1452return;1453}14541455 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);1456 has_curr_head = !is_null_sha1(curr_head);1457if(!has_curr_head)1458hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);14591460 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);1461if(!has_orig_head)1462hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);14631464clean_index(curr_head, orig_head);14651466if(has_orig_head)1467update_ref("am --abort","HEAD", orig_head,1468 has_curr_head ? curr_head : NULL,0,1469 UPDATE_REFS_DIE_ON_ERR);1470else if(curr_branch)1471delete_ref(curr_branch, NULL, REF_NODEREF);14721473free(curr_branch);1474am_destroy(state);1475}14761477/**1478 * parse_options() callback that validates and sets opt->value to the1479 * PATCH_FORMAT_* enum value corresponding to `arg`.1480 */1481static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)1482{1483int*opt_value = opt->value;14841485if(!strcmp(arg,"mbox"))1486*opt_value = PATCH_FORMAT_MBOX;1487else1488returnerror(_("Invalid value for --patch-format:%s"), arg);1489return0;1490}14911492enum resume_mode {1493 RESUME_FALSE =0,1494 RESUME_APPLY,1495 RESUME_RESOLVED,1496 RESUME_SKIP,1497 RESUME_ABORT1498};14991500intcmd_am(int argc,const char**argv,const char*prefix)1501{1502struct am_state state;1503int patch_format = PATCH_FORMAT_UNKNOWN;1504enum resume_mode resume = RESUME_FALSE;15051506const char*const usage[] = {1507N_("git am [options] [(<mbox>|<Maildir>)...]"),1508N_("git am [options] (--continue | --skip | --abort)"),1509 NULL1510};15111512struct option options[] = {1513OPT_BOOL('3',"3way", &state.threeway,1514N_("allow fall back on 3way merging if needed")),1515OPT__QUIET(&state.quiet,N_("be quiet")),1516OPT_BOOL('s',"signoff", &state.signoff,1517N_("add a Signed-off-by line to the commit message")),1518OPT_BOOL('u',"utf8", &state.utf8,1519N_("recode into utf8 (default)")),1520OPT_SET_INT('k',"keep", &state.keep,1521N_("pass -k flag to git-mailinfo"), KEEP_TRUE),1522OPT_SET_INT(0,"keep-non-patch", &state.keep,1523N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),1524OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),1525N_("format the patch(es) are in"),1526 parse_opt_patchformat),1527OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,1528N_("override error message when patch failure occurs")),1529OPT_CMDMODE(0,"continue", &resume,1530N_("continue applying patches after resolving a conflict"),1531 RESUME_RESOLVED),1532OPT_CMDMODE('r',"resolved", &resume,1533N_("synonyms for --continue"),1534 RESUME_RESOLVED),1535OPT_CMDMODE(0,"skip", &resume,1536N_("skip the current patch"),1537 RESUME_SKIP),1538OPT_CMDMODE(0,"abort", &resume,1539N_("restore the original branch and abort the patching operation."),1540 RESUME_ABORT),1541OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,1542N_("(internal use for git-rebase)")),1543OPT_END()1544};15451546/*1547 * NEEDSWORK: Once all the features of git-am.sh have been1548 * re-implemented in builtin/am.c, this preamble can be removed.1549 */1550if(!getenv("_GIT_USE_BUILTIN_AM")) {1551const char*path =mkpath("%s/git-am",git_exec_path());15521553if(sane_execvp(path, (char**)argv) <0)1554die_errno("could not exec%s", path);1555}else{1556 prefix =setup_git_directory();1557trace_repo_setup(prefix);1558setup_work_tree();1559}15601561git_config(git_default_config, NULL);15621563am_state_init(&state,git_path("rebase-apply"));15641565 argc =parse_options(argc, argv, prefix, options, usage,0);15661567if(read_index_preload(&the_index, NULL) <0)1568die(_("failed to read the index"));15691570if(am_in_progress(&state)) {1571/*1572 * Catch user error to feed us patches when there is a session1573 * in progress:1574 *1575 * 1. mbox path(s) are provided on the command-line.1576 * 2. stdin is not a tty: the user is trying to feed us a patch1577 * from standard input. This is somewhat unreliable -- stdin1578 * could be /dev/null for example and the caller did not1579 * intend to feed us a patch but wanted to continue1580 * unattended.1581 */1582if(argc || (resume == RESUME_FALSE && !isatty(0)))1583die(_("previous rebase directory%sstill exists but mbox given."),1584 state.dir);15851586if(resume == RESUME_FALSE)1587 resume = RESUME_APPLY;15881589am_load(&state);1590}else{1591struct argv_array paths = ARGV_ARRAY_INIT;1592int i;15931594/*1595 * Handle stray state directory in the independent-run case. In1596 * the --rebasing case, it is up to the caller to take care of1597 * stray directories.1598 */1599if(file_exists(state.dir) && !state.rebasing) {1600if(resume == RESUME_ABORT) {1601am_destroy(&state);1602am_state_release(&state);1603return0;1604}16051606die(_("Stray%sdirectory found.\n"1607"Use\"git am --abort\"to remove it."),1608 state.dir);1609}16101611if(resume)1612die(_("Resolve operation not in progress, we are not resuming."));16131614for(i =0; i < argc; i++) {1615if(is_absolute_path(argv[i]) || !prefix)1616argv_array_push(&paths, argv[i]);1617else1618argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));1619}16201621am_setup(&state, patch_format, paths.argv);16221623argv_array_clear(&paths);1624}16251626switch(resume) {1627case RESUME_FALSE:1628am_run(&state,0);1629break;1630case RESUME_APPLY:1631am_run(&state,1);1632break;1633case RESUME_RESOLVED:1634am_resolve(&state);1635break;1636case RESUME_SKIP:1637am_skip(&state);1638break;1639case RESUME_ABORT:1640am_abort(&state);1641break;1642default:1643die("BUG: invalid resume value");1644}16451646am_state_release(&state);16471648return0;1649}