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/* when --rebasing, records the original commit the patch came from */ 99unsigned char orig_commit[GIT_SHA1_RAWSZ]; 100 101/* number of digits in patch filename */ 102int prec; 103 104/* various operating modes and command line options */ 105int threeway; 106int quiet; 107int signoff; 108int utf8; 109int keep;/* enum keep_type */ 110int message_id; 111int scissors;/* enum scissors_type */ 112struct argv_array git_apply_opts; 113const char*resolvemsg; 114int committer_date_is_author_date; 115int ignore_date; 116const char*sign_commit; 117int rebasing; 118}; 119 120/** 121 * Initializes am_state with the default values. The state directory is set to 122 * dir. 123 */ 124static voidam_state_init(struct am_state *state,const char*dir) 125{ 126int gpgsign; 127 128memset(state,0,sizeof(*state)); 129 130assert(dir); 131 state->dir =xstrdup(dir); 132 133 state->prec =4; 134 135 state->utf8 =1; 136 137git_config_get_bool("am.messageid", &state->message_id); 138 139 state->scissors = SCISSORS_UNSET; 140 141argv_array_init(&state->git_apply_opts); 142 143if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 144 state->sign_commit = gpgsign ?"": NULL; 145} 146 147/** 148 * Releases memory allocated by an am_state. 149 */ 150static voidam_state_release(struct am_state *state) 151{ 152free(state->dir); 153free(state->author_name); 154free(state->author_email); 155free(state->author_date); 156free(state->msg); 157argv_array_clear(&state->git_apply_opts); 158} 159 160/** 161 * Returns path relative to the am_state directory. 162 */ 163staticinlineconst char*am_path(const struct am_state *state,const char*path) 164{ 165returnmkpath("%s/%s", state->dir, path); 166} 167 168/** 169 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 170 * at the end. 171 */ 172static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 173{ 174va_list ap; 175 176va_start(ap, fmt); 177if(!state->quiet) { 178vfprintf(fp, fmt, ap); 179putc('\n', fp); 180} 181va_end(ap); 182} 183 184/** 185 * Returns 1 if there is an am session in progress, 0 otherwise. 186 */ 187static intam_in_progress(const struct am_state *state) 188{ 189struct stat st; 190 191if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 192return0; 193if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 194return0; 195if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 196return0; 197return1; 198} 199 200/** 201 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 202 * number of bytes read on success, -1 if the file does not exist. If `trim` is 203 * set, trailing whitespace will be removed. 204 */ 205static intread_state_file(struct strbuf *sb,const struct am_state *state, 206const char*file,int trim) 207{ 208strbuf_reset(sb); 209 210if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 211if(trim) 212strbuf_trim(sb); 213 214return sb->len; 215} 216 217if(errno == ENOENT) 218return-1; 219 220die_errno(_("could not read '%s'"),am_path(state, file)); 221} 222 223/** 224 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 225 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 226 * match `key`. Returns NULL on failure. 227 * 228 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 229 * the author-script. 230 */ 231static char*read_shell_var(FILE*fp,const char*key) 232{ 233struct strbuf sb = STRBUF_INIT; 234const char*str; 235 236if(strbuf_getline(&sb, fp,'\n')) 237goto fail; 238 239if(!skip_prefix(sb.buf, key, &str)) 240goto fail; 241 242if(!skip_prefix(str,"=", &str)) 243goto fail; 244 245strbuf_remove(&sb,0, str - sb.buf); 246 247 str =sq_dequote(sb.buf); 248if(!str) 249goto fail; 250 251returnstrbuf_detach(&sb, NULL); 252 253fail: 254strbuf_release(&sb); 255return NULL; 256} 257 258/** 259 * Reads and parses the state directory's "author-script" file, and sets 260 * state->author_name, state->author_email and state->author_date accordingly. 261 * Returns 0 on success, -1 if the file could not be parsed. 262 * 263 * The author script is of the format: 264 * 265 * GIT_AUTHOR_NAME='$author_name' 266 * GIT_AUTHOR_EMAIL='$author_email' 267 * GIT_AUTHOR_DATE='$author_date' 268 * 269 * where $author_name, $author_email and $author_date are quoted. We are strict 270 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 271 * script, and thus if the file differs from what this function expects, it is 272 * better to bail out than to do something that the user does not expect. 273 */ 274static intread_author_script(struct am_state *state) 275{ 276const char*filename =am_path(state,"author-script"); 277FILE*fp; 278 279assert(!state->author_name); 280assert(!state->author_email); 281assert(!state->author_date); 282 283 fp =fopen(filename,"r"); 284if(!fp) { 285if(errno == ENOENT) 286return0; 287die_errno(_("could not open '%s' for reading"), filename); 288} 289 290 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 291if(!state->author_name) { 292fclose(fp); 293return-1; 294} 295 296 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 297if(!state->author_email) { 298fclose(fp); 299return-1; 300} 301 302 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 303if(!state->author_date) { 304fclose(fp); 305return-1; 306} 307 308if(fgetc(fp) != EOF) { 309fclose(fp); 310return-1; 311} 312 313fclose(fp); 314return0; 315} 316 317/** 318 * Saves state->author_name, state->author_email and state->author_date in the 319 * state directory's "author-script" file. 320 */ 321static voidwrite_author_script(const struct am_state *state) 322{ 323struct strbuf sb = STRBUF_INIT; 324 325strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 326sq_quote_buf(&sb, state->author_name); 327strbuf_addch(&sb,'\n'); 328 329strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 330sq_quote_buf(&sb, state->author_email); 331strbuf_addch(&sb,'\n'); 332 333strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 334sq_quote_buf(&sb, state->author_date); 335strbuf_addch(&sb,'\n'); 336 337write_file(am_path(state,"author-script"),1,"%s", sb.buf); 338 339strbuf_release(&sb); 340} 341 342/** 343 * Reads the commit message from the state directory's "final-commit" file, 344 * setting state->msg to its contents and state->msg_len to the length of its 345 * contents in bytes. 346 * 347 * Returns 0 on success, -1 if the file does not exist. 348 */ 349static intread_commit_msg(struct am_state *state) 350{ 351struct strbuf sb = STRBUF_INIT; 352 353assert(!state->msg); 354 355if(read_state_file(&sb, state,"final-commit",0) <0) { 356strbuf_release(&sb); 357return-1; 358} 359 360 state->msg =strbuf_detach(&sb, &state->msg_len); 361return0; 362} 363 364/** 365 * Saves state->msg in the state directory's "final-commit" file. 366 */ 367static voidwrite_commit_msg(const struct am_state *state) 368{ 369int fd; 370const char*filename =am_path(state,"final-commit"); 371 372 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 373if(write_in_full(fd, state->msg, state->msg_len) <0) 374die_errno(_("could not write to%s"), filename); 375close(fd); 376} 377 378/** 379 * Loads state from disk. 380 */ 381static voidam_load(struct am_state *state) 382{ 383struct strbuf sb = STRBUF_INIT; 384 385if(read_state_file(&sb, state,"next",1) <0) 386die("BUG: state file 'next' does not exist"); 387 state->cur =strtol(sb.buf, NULL,10); 388 389if(read_state_file(&sb, state,"last",1) <0) 390die("BUG: state file 'last' does not exist"); 391 state->last =strtol(sb.buf, NULL,10); 392 393if(read_author_script(state) <0) 394die(_("could not parse author script")); 395 396read_commit_msg(state); 397 398if(read_state_file(&sb, state,"original-commit",1) <0) 399hashclr(state->orig_commit); 400else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 401die(_("could not parse%s"),am_path(state,"original-commit")); 402 403read_state_file(&sb, state,"threeway",1); 404 state->threeway = !strcmp(sb.buf,"t"); 405 406read_state_file(&sb, state,"quiet",1); 407 state->quiet = !strcmp(sb.buf,"t"); 408 409read_state_file(&sb, state,"sign",1); 410 state->signoff = !strcmp(sb.buf,"t"); 411 412read_state_file(&sb, state,"utf8",1); 413 state->utf8 = !strcmp(sb.buf,"t"); 414 415read_state_file(&sb, state,"keep",1); 416if(!strcmp(sb.buf,"t")) 417 state->keep = KEEP_TRUE; 418else if(!strcmp(sb.buf,"b")) 419 state->keep = KEEP_NON_PATCH; 420else 421 state->keep = KEEP_FALSE; 422 423read_state_file(&sb, state,"messageid",1); 424 state->message_id = !strcmp(sb.buf,"t"); 425 426read_state_file(&sb, state,"scissors",1); 427if(!strcmp(sb.buf,"t")) 428 state->scissors = SCISSORS_TRUE; 429else if(!strcmp(sb.buf,"f")) 430 state->scissors = SCISSORS_FALSE; 431else 432 state->scissors = SCISSORS_UNSET; 433 434read_state_file(&sb, state,"apply-opt",1); 435argv_array_clear(&state->git_apply_opts); 436if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 437die(_("could not parse%s"),am_path(state,"apply-opt")); 438 439 state->rebasing = !!file_exists(am_path(state,"rebasing")); 440 441strbuf_release(&sb); 442} 443 444/** 445 * Removes the am_state directory, forcefully terminating the current am 446 * session. 447 */ 448static voidam_destroy(const struct am_state *state) 449{ 450struct strbuf sb = STRBUF_INIT; 451 452strbuf_addstr(&sb, state->dir); 453remove_dir_recursively(&sb,0); 454strbuf_release(&sb); 455} 456 457/** 458 * Runs post-rewrite hook. Returns it exit code. 459 */ 460static intrun_post_rewrite_hook(const struct am_state *state) 461{ 462struct child_process cp = CHILD_PROCESS_INIT; 463const char*hook =find_hook("post-rewrite"); 464int ret; 465 466if(!hook) 467return0; 468 469argv_array_push(&cp.args, hook); 470argv_array_push(&cp.args,"rebase"); 471 472 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 473 cp.stdout_to_stderr =1; 474 475 ret =run_command(&cp); 476 477close(cp.in); 478return ret; 479} 480 481/** 482 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 483 * non-indented lines and checking if they look like they begin with valid 484 * header field names. 485 * 486 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 487 */ 488static intis_mail(FILE*fp) 489{ 490const char*header_regex ="^[!-9;-~]+:"; 491struct strbuf sb = STRBUF_INIT; 492 regex_t regex; 493int ret =1; 494 495if(fseek(fp,0L, SEEK_SET)) 496die_errno(_("fseek failed")); 497 498if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 499die("invalid pattern:%s", header_regex); 500 501while(!strbuf_getline_crlf(&sb, fp)) { 502if(!sb.len) 503break;/* End of header */ 504 505/* Ignore indented folded lines */ 506if(*sb.buf =='\t'|| *sb.buf ==' ') 507continue; 508 509/* It's a header if it matches header_regex */ 510if(regexec(®ex, sb.buf,0, NULL,0)) { 511 ret =0; 512goto done; 513} 514} 515 516done: 517regfree(®ex); 518strbuf_release(&sb); 519return ret; 520} 521 522/** 523 * Attempts to detect the patch_format of the patches contained in `paths`, 524 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 525 * detection fails. 526 */ 527static intdetect_patch_format(const char**paths) 528{ 529enum patch_format ret = PATCH_FORMAT_UNKNOWN; 530struct strbuf l1 = STRBUF_INIT; 531FILE*fp; 532 533/* 534 * We default to mbox format if input is from stdin and for directories 535 */ 536if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 537return PATCH_FORMAT_MBOX; 538 539/* 540 * Otherwise, check the first few lines of the first patch, starting 541 * from the first non-blank line, to try to detect its format. 542 */ 543 544 fp =xfopen(*paths,"r"); 545 546while(!strbuf_getline_crlf(&l1, fp)) { 547if(l1.len) 548break; 549} 550 551if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 552 ret = PATCH_FORMAT_MBOX; 553goto done; 554} 555 556if(l1.len &&is_mail(fp)) { 557 ret = PATCH_FORMAT_MBOX; 558goto done; 559} 560 561done: 562fclose(fp); 563strbuf_release(&l1); 564return ret; 565} 566 567/** 568 * Splits out individual email patches from `paths`, where each path is either 569 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 570 */ 571static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 572{ 573struct child_process cp = CHILD_PROCESS_INIT; 574struct strbuf last = STRBUF_INIT; 575 576 cp.git_cmd =1; 577argv_array_push(&cp.args,"mailsplit"); 578argv_array_pushf(&cp.args,"-d%d", state->prec); 579argv_array_pushf(&cp.args,"-o%s", state->dir); 580argv_array_push(&cp.args,"-b"); 581if(keep_cr) 582argv_array_push(&cp.args,"--keep-cr"); 583argv_array_push(&cp.args,"--"); 584argv_array_pushv(&cp.args, paths); 585 586if(capture_command(&cp, &last,8)) 587return-1; 588 589 state->cur =1; 590 state->last =strtol(last.buf, NULL,10); 591 592return0; 593} 594 595/** 596 * Splits a list of files/directories into individual email patches. Each path 597 * in `paths` must be a file/directory that is formatted according to 598 * `patch_format`. 599 * 600 * Once split out, the individual email patches will be stored in the state 601 * directory, with each patch's filename being its index, padded to state->prec 602 * digits. 603 * 604 * state->cur will be set to the index of the first mail, and state->last will 605 * be set to the index of the last mail. 606 * 607 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 608 * to disable this behavior, -1 to use the default configured setting. 609 * 610 * Returns 0 on success, -1 on failure. 611 */ 612static intsplit_mail(struct am_state *state,enum patch_format patch_format, 613const char**paths,int keep_cr) 614{ 615if(keep_cr <0) { 616 keep_cr =0; 617git_config_get_bool("am.keepcr", &keep_cr); 618} 619 620switch(patch_format) { 621case PATCH_FORMAT_MBOX: 622returnsplit_mail_mbox(state, paths, keep_cr); 623default: 624die("BUG: invalid patch_format"); 625} 626return-1; 627} 628 629/** 630 * Setup a new am session for applying patches 631 */ 632static voidam_setup(struct am_state *state,enum patch_format patch_format, 633const char**paths,int keep_cr) 634{ 635unsigned char curr_head[GIT_SHA1_RAWSZ]; 636const char*str; 637struct strbuf sb = STRBUF_INIT; 638 639if(!patch_format) 640 patch_format =detect_patch_format(paths); 641 642if(!patch_format) { 643fprintf_ln(stderr,_("Patch format detection failed.")); 644exit(128); 645} 646 647if(mkdir(state->dir,0777) <0&& errno != EEXIST) 648die_errno(_("failed to create directory '%s'"), state->dir); 649 650if(split_mail(state, patch_format, paths, keep_cr) <0) { 651am_destroy(state); 652die(_("Failed to split patches.")); 653} 654 655if(state->rebasing) 656 state->threeway =1; 657 658write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f"); 659 660write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f"); 661 662write_file(am_path(state,"sign"),1, state->signoff ?"t":"f"); 663 664write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f"); 665 666switch(state->keep) { 667case KEEP_FALSE: 668 str ="f"; 669break; 670case KEEP_TRUE: 671 str ="t"; 672break; 673case KEEP_NON_PATCH: 674 str ="b"; 675break; 676default: 677die("BUG: invalid value for state->keep"); 678} 679 680write_file(am_path(state,"keep"),1,"%s", str); 681 682write_file(am_path(state,"messageid"),1, state->message_id ?"t":"f"); 683 684switch(state->scissors) { 685case SCISSORS_UNSET: 686 str =""; 687break; 688case SCISSORS_FALSE: 689 str ="f"; 690break; 691case SCISSORS_TRUE: 692 str ="t"; 693break; 694default: 695die("BUG: invalid value for state->scissors"); 696} 697 698write_file(am_path(state,"scissors"),1,"%s", str); 699 700sq_quote_argv(&sb, state->git_apply_opts.argv,0); 701write_file(am_path(state,"apply-opt"),1,"%s", sb.buf); 702 703if(state->rebasing) 704write_file(am_path(state,"rebasing"),1,"%s",""); 705else 706write_file(am_path(state,"applying"),1,"%s",""); 707 708if(!get_sha1("HEAD", curr_head)) { 709write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head)); 710if(!state->rebasing) 711update_ref("am","ORIG_HEAD", curr_head, NULL,0, 712 UPDATE_REFS_DIE_ON_ERR); 713}else{ 714write_file(am_path(state,"abort-safety"),1,"%s",""); 715if(!state->rebasing) 716delete_ref("ORIG_HEAD", NULL,0); 717} 718 719/* 720 * NOTE: Since the "next" and "last" files determine if an am_state 721 * session is in progress, they should be written last. 722 */ 723 724write_file(am_path(state,"next"),1,"%d", state->cur); 725 726write_file(am_path(state,"last"),1,"%d", state->last); 727 728strbuf_release(&sb); 729} 730 731/** 732 * Increments the patch pointer, and cleans am_state for the application of the 733 * next patch. 734 */ 735static voidam_next(struct am_state *state) 736{ 737unsigned char head[GIT_SHA1_RAWSZ]; 738 739free(state->author_name); 740 state->author_name = NULL; 741 742free(state->author_email); 743 state->author_email = NULL; 744 745free(state->author_date); 746 state->author_date = NULL; 747 748free(state->msg); 749 state->msg = NULL; 750 state->msg_len =0; 751 752unlink(am_path(state,"author-script")); 753unlink(am_path(state,"final-commit")); 754 755hashclr(state->orig_commit); 756unlink(am_path(state,"original-commit")); 757 758if(!get_sha1("HEAD", head)) 759write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head)); 760else 761write_file(am_path(state,"abort-safety"),1,"%s",""); 762 763 state->cur++; 764write_file(am_path(state,"next"),1,"%d", state->cur); 765} 766 767/** 768 * Returns the filename of the current patch email. 769 */ 770static const char*msgnum(const struct am_state *state) 771{ 772static struct strbuf sb = STRBUF_INIT; 773 774strbuf_reset(&sb); 775strbuf_addf(&sb,"%0*d", state->prec, state->cur); 776 777return sb.buf; 778} 779 780/** 781 * Refresh and write index. 782 */ 783static voidrefresh_and_write_cache(void) 784{ 785struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file)); 786 787hold_locked_index(lock_file,1); 788refresh_cache(REFRESH_QUIET); 789if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 790die(_("unable to write index file")); 791} 792 793/** 794 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn 795 * branch, returns 1 if there are entries in the index, 0 otherwise. If an 796 * strbuf is provided, the space-separated list of files that differ will be 797 * appended to it. 798 */ 799static intindex_has_changes(struct strbuf *sb) 800{ 801unsigned char head[GIT_SHA1_RAWSZ]; 802int i; 803 804if(!get_sha1_tree("HEAD", head)) { 805struct diff_options opt; 806 807diff_setup(&opt); 808DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); 809if(!sb) 810DIFF_OPT_SET(&opt, QUICK); 811do_diff_cache(head, &opt); 812diffcore_std(&opt); 813for(i =0; sb && i < diff_queued_diff.nr; i++) { 814if(i) 815strbuf_addch(sb,' '); 816strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); 817} 818diff_flush(&opt); 819returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0; 820}else{ 821for(i =0; sb && i < active_nr; i++) { 822if(i) 823strbuf_addch(sb,' '); 824strbuf_addstr(sb, active_cache[i]->name); 825} 826return!!active_nr; 827} 828} 829 830/** 831 * Dies with a user-friendly message on how to proceed after resolving the 832 * problem. This message can be overridden with state->resolvemsg. 833 */ 834static void NORETURN die_user_resolve(const struct am_state *state) 835{ 836if(state->resolvemsg) { 837printf_ln("%s", state->resolvemsg); 838}else{ 839const char*cmdline ="git am"; 840 841printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline); 842printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline); 843printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline); 844} 845 846exit(128); 847} 848 849/** 850 * Parses `mail` using git-mailinfo, extracting its patch and authorship info. 851 * state->msg will be set to the patch message. state->author_name, 852 * state->author_email and state->author_date will be set to the patch author's 853 * name, email and date respectively. The patch body will be written to the 854 * state directory's "patch" file. 855 * 856 * Returns 1 if the patch should be skipped, 0 otherwise. 857 */ 858static intparse_mail(struct am_state *state,const char*mail) 859{ 860FILE*fp; 861struct child_process cp = CHILD_PROCESS_INIT; 862struct strbuf sb = STRBUF_INIT; 863struct strbuf msg = STRBUF_INIT; 864struct strbuf author_name = STRBUF_INIT; 865struct strbuf author_date = STRBUF_INIT; 866struct strbuf author_email = STRBUF_INIT; 867int ret =0; 868 869 cp.git_cmd =1; 870 cp.in =xopen(mail, O_RDONLY,0); 871 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777); 872 873argv_array_push(&cp.args,"mailinfo"); 874argv_array_push(&cp.args, state->utf8 ?"-u":"-n"); 875 876switch(state->keep) { 877case KEEP_FALSE: 878break; 879case KEEP_TRUE: 880argv_array_push(&cp.args,"-k"); 881break; 882case KEEP_NON_PATCH: 883argv_array_push(&cp.args,"-b"); 884break; 885default: 886die("BUG: invalid value for state->keep"); 887} 888 889if(state->message_id) 890argv_array_push(&cp.args,"-m"); 891 892switch(state->scissors) { 893case SCISSORS_UNSET: 894break; 895case SCISSORS_FALSE: 896argv_array_push(&cp.args,"--no-scissors"); 897break; 898case SCISSORS_TRUE: 899argv_array_push(&cp.args,"--scissors"); 900break; 901default: 902die("BUG: invalid value for state->scissors"); 903} 904 905argv_array_push(&cp.args,am_path(state,"msg")); 906argv_array_push(&cp.args,am_path(state,"patch")); 907 908if(run_command(&cp) <0) 909die("could not parse patch"); 910 911close(cp.in); 912close(cp.out); 913 914/* Extract message and author information */ 915 fp =xfopen(am_path(state,"info"),"r"); 916while(!strbuf_getline(&sb, fp,'\n')) { 917const char*x; 918 919if(skip_prefix(sb.buf,"Subject: ", &x)) { 920if(msg.len) 921strbuf_addch(&msg,'\n'); 922strbuf_addstr(&msg, x); 923}else if(skip_prefix(sb.buf,"Author: ", &x)) 924strbuf_addstr(&author_name, x); 925else if(skip_prefix(sb.buf,"Email: ", &x)) 926strbuf_addstr(&author_email, x); 927else if(skip_prefix(sb.buf,"Date: ", &x)) 928strbuf_addstr(&author_date, x); 929} 930fclose(fp); 931 932/* Skip pine's internal folder data */ 933if(!strcmp(author_name.buf,"Mail System Internal Data")) { 934 ret =1; 935goto finish; 936} 937 938if(is_empty_file(am_path(state,"patch"))) { 939printf_ln(_("Patch is empty. Was it split wrong?")); 940die_user_resolve(state); 941} 942 943strbuf_addstr(&msg,"\n\n"); 944if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0) 945die_errno(_("could not read '%s'"),am_path(state,"msg")); 946stripspace(&msg,0); 947 948if(state->signoff) 949append_signoff(&msg,0,0); 950 951assert(!state->author_name); 952 state->author_name =strbuf_detach(&author_name, NULL); 953 954assert(!state->author_email); 955 state->author_email =strbuf_detach(&author_email, NULL); 956 957assert(!state->author_date); 958 state->author_date =strbuf_detach(&author_date, NULL); 959 960assert(!state->msg); 961 state->msg =strbuf_detach(&msg, &state->msg_len); 962 963finish: 964strbuf_release(&msg); 965strbuf_release(&author_date); 966strbuf_release(&author_email); 967strbuf_release(&author_name); 968strbuf_release(&sb); 969return ret; 970} 971 972/** 973 * Sets commit_id to the commit hash where the mail was generated from. 974 * Returns 0 on success, -1 on failure. 975 */ 976static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail) 977{ 978struct strbuf sb = STRBUF_INIT; 979FILE*fp =xfopen(mail,"r"); 980const char*x; 981 982if(strbuf_getline(&sb, fp,'\n')) 983return-1; 984 985if(!skip_prefix(sb.buf,"From ", &x)) 986return-1; 987 988if(get_sha1_hex(x, commit_id) <0) 989return-1; 990 991strbuf_release(&sb); 992fclose(fp); 993return0; 994} 995 996/** 997 * Sets state->msg, state->author_name, state->author_email, state->author_date 998 * to the commit's respective info. 999 */1000static voidget_commit_info(struct am_state *state,struct commit *commit)1001{1002const char*buffer, *ident_line, *author_date, *msg;1003size_t ident_len;1004struct ident_split ident_split;1005struct strbuf sb = STRBUF_INIT;10061007 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());10081009 ident_line =find_commit_header(buffer,"author", &ident_len);10101011if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1012strbuf_add(&sb, ident_line, ident_len);1013die(_("invalid ident line:%s"), sb.buf);1014}10151016assert(!state->author_name);1017if(ident_split.name_begin) {1018strbuf_add(&sb, ident_split.name_begin,1019 ident_split.name_end - ident_split.name_begin);1020 state->author_name =strbuf_detach(&sb, NULL);1021}else1022 state->author_name =xstrdup("");10231024assert(!state->author_email);1025if(ident_split.mail_begin) {1026strbuf_add(&sb, ident_split.mail_begin,1027 ident_split.mail_end - ident_split.mail_begin);1028 state->author_email =strbuf_detach(&sb, NULL);1029}else1030 state->author_email =xstrdup("");10311032 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1033strbuf_addstr(&sb, author_date);1034assert(!state->author_date);1035 state->author_date =strbuf_detach(&sb, NULL);10361037assert(!state->msg);1038 msg =strstr(buffer,"\n\n");1039if(!msg)1040die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1041 state->msg =xstrdup(msg +2);1042 state->msg_len =strlen(state->msg);1043}10441045/**1046 * Writes `commit` as a patch to the state directory's "patch" file.1047 */1048static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1049{1050struct rev_info rev_info;1051FILE*fp;10521053 fp =xfopen(am_path(state,"patch"),"w");1054init_revisions(&rev_info, NULL);1055 rev_info.diff =1;1056 rev_info.abbrev =0;1057 rev_info.disable_stdin =1;1058 rev_info.show_root_diff =1;1059 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1060 rev_info.no_commit_id =1;1061DIFF_OPT_SET(&rev_info.diffopt, BINARY);1062DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1063 rev_info.diffopt.use_color =0;1064 rev_info.diffopt.file = fp;1065 rev_info.diffopt.close_file =1;1066add_pending_object(&rev_info, &commit->object,"");1067diff_setup_done(&rev_info.diffopt);1068log_tree_commit(&rev_info, commit);1069}10701071/**1072 * Like parse_mail(), but parses the mail by looking up its commit ID1073 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1074 * of patches.1075 *1076 * state->orig_commit will be set to the original commit ID.1077 *1078 * Will always return 0 as the patch should never be skipped.1079 */1080static intparse_mail_rebase(struct am_state *state,const char*mail)1081{1082struct commit *commit;1083unsigned char commit_sha1[GIT_SHA1_RAWSZ];10841085if(get_mail_commit_sha1(commit_sha1, mail) <0)1086die(_("could not parse%s"), mail);10871088 commit =lookup_commit_or_die(commit_sha1, mail);10891090get_commit_info(state, commit);10911092write_commit_patch(state, commit);10931094hashcpy(state->orig_commit, commit_sha1);1095write_file(am_path(state,"original-commit"),1,"%s",1096sha1_to_hex(commit_sha1));10971098return0;1099}11001101/**1102 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1103 * `index_file` is not NULL, the patch will be applied to that index.1104 */1105static intrun_apply(const struct am_state *state,const char*index_file)1106{1107struct child_process cp = CHILD_PROCESS_INIT;11081109 cp.git_cmd =1;11101111if(index_file)1112argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);11131114/*1115 * If we are allowed to fall back on 3-way merge, don't give false1116 * errors during the initial attempt.1117 */1118if(state->threeway && !index_file) {1119 cp.no_stdout =1;1120 cp.no_stderr =1;1121}11221123argv_array_push(&cp.args,"apply");11241125argv_array_pushv(&cp.args, state->git_apply_opts.argv);11261127if(index_file)1128argv_array_push(&cp.args,"--cached");1129else1130argv_array_push(&cp.args,"--index");11311132argv_array_push(&cp.args,am_path(state,"patch"));11331134if(run_command(&cp))1135return-1;11361137/* Reload index as git-apply will have modified it. */1138discard_cache();1139read_cache_from(index_file ? index_file :get_index_file());11401141return0;1142}11431144/**1145 * Builds an index that contains just the blobs needed for a 3way merge.1146 */1147static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1148{1149struct child_process cp = CHILD_PROCESS_INIT;11501151 cp.git_cmd =1;1152argv_array_push(&cp.args,"apply");1153argv_array_pushv(&cp.args, state->git_apply_opts.argv);1154argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1155argv_array_push(&cp.args,am_path(state,"patch"));11561157if(run_command(&cp))1158return-1;11591160return0;1161}11621163/**1164 * Attempt a threeway merge, using index_path as the temporary index.1165 */1166static intfall_back_threeway(const struct am_state *state,const char*index_path)1167{1168unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1169 our_tree[GIT_SHA1_RAWSZ];1170const unsigned char*bases[1] = {orig_tree};1171struct merge_options o;1172struct commit *result;1173char*his_tree_name;11741175if(get_sha1("HEAD", our_tree) <0)1176hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);11771178if(build_fake_ancestor(state, index_path))1179returnerror("could not build fake ancestor");11801181discard_cache();1182read_cache_from(index_path);11831184if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1185returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));11861187say(state, stdout,_("Using index info to reconstruct a base tree..."));11881189if(!state->quiet) {1190/*1191 * List paths that needed 3-way fallback, so that the user can1192 * review them with extra care to spot mismerges.1193 */1194struct rev_info rev_info;1195const char*diff_filter_str ="--diff-filter=AM";11961197init_revisions(&rev_info, NULL);1198 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1199diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1200add_pending_sha1(&rev_info,"HEAD", our_tree,0);1201diff_setup_done(&rev_info.diffopt);1202run_diff_index(&rev_info,1);1203}12041205if(run_apply(state, index_path))1206returnerror(_("Did you hand edit your patch?\n"1207"It does not apply to blobs recorded in its index."));12081209if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1210returnerror("could not write tree");12111212say(state, stdout,_("Falling back to patching base and 3-way merge..."));12131214discard_cache();1215read_cache();12161217/*1218 * This is not so wrong. Depending on which base we picked, orig_tree1219 * may be wildly different from ours, but his_tree has the same set of1220 * wildly different changes in parts the patch did not touch, so1221 * recursive ends up canceling them, saying that we reverted all those1222 * changes.1223 */12241225init_merge_options(&o);12261227 o.branch1 ="HEAD";1228 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1229 o.branch2 = his_tree_name;12301231if(state->quiet)1232 o.verbosity =0;12331234if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1235free(his_tree_name);1236returnerror(_("Failed to merge in the changes."));1237}12381239free(his_tree_name);1240return0;1241}12421243/**1244 * Commits the current index with state->msg as the commit message and1245 * state->author_name, state->author_email and state->author_date as the author1246 * information.1247 */1248static voiddo_commit(const struct am_state *state)1249{1250unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1251 commit[GIT_SHA1_RAWSZ];1252unsigned char*ptr;1253struct commit_list *parents = NULL;1254const char*reflog_msg, *author;1255struct strbuf sb = STRBUF_INIT;12561257if(write_cache_as_tree(tree,0, NULL))1258die(_("git write-tree failed to write a tree"));12591260if(!get_sha1_commit("HEAD", parent)) {1261 ptr = parent;1262commit_list_insert(lookup_commit(parent), &parents);1263}else{1264 ptr = NULL;1265say(state, stderr,_("applying to an empty history"));1266}12671268 author =fmt_ident(state->author_name, state->author_email,1269 state->ignore_date ? NULL : state->author_date,1270 IDENT_STRICT);12711272if(state->committer_date_is_author_date)1273setenv("GIT_COMMITTER_DATE",1274 state->ignore_date ?"": state->author_date,1);12751276if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1277 author, state->sign_commit))1278die(_("failed to write commit object"));12791280 reflog_msg =getenv("GIT_REFLOG_ACTION");1281if(!reflog_msg)1282 reflog_msg ="am";12831284strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1285 state->msg);12861287update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);12881289if(state->rebasing) {1290FILE*fp =xfopen(am_path(state,"rewritten"),"a");12911292assert(!is_null_sha1(state->orig_commit));1293fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1294fprintf(fp,"%s\n",sha1_to_hex(commit));1295fclose(fp);1296}12971298strbuf_release(&sb);1299}13001301/**1302 * Validates the am_state for resuming -- the "msg" and authorship fields must1303 * be filled up.1304 */1305static voidvalidate_resume_state(const struct am_state *state)1306{1307if(!state->msg)1308die(_("cannot resume:%sdoes not exist."),1309am_path(state,"final-commit"));13101311if(!state->author_name || !state->author_email || !state->author_date)1312die(_("cannot resume:%sdoes not exist."),1313am_path(state,"author-script"));1314}13151316/**1317 * Applies all queued mail.1318 *1319 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1320 * well as the state directory's "patch" file is used as-is for applying the1321 * patch and committing it.1322 */1323static voidam_run(struct am_state *state,int resume)1324{1325const char*argv_gc_auto[] = {"gc","--auto", NULL};1326struct strbuf sb = STRBUF_INIT;13271328unlink(am_path(state,"dirtyindex"));13291330refresh_and_write_cache();13311332if(index_has_changes(&sb)) {1333write_file(am_path(state,"dirtyindex"),1,"t");1334die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1335}13361337strbuf_release(&sb);13381339while(state->cur <= state->last) {1340const char*mail =am_path(state,msgnum(state));1341int apply_status;13421343if(!file_exists(mail))1344goto next;13451346if(resume) {1347validate_resume_state(state);1348 resume =0;1349}else{1350int skip;13511352if(state->rebasing)1353 skip =parse_mail_rebase(state, mail);1354else1355 skip =parse_mail(state, mail);13561357if(skip)1358goto next;/* mail should be skipped */13591360write_author_script(state);1361write_commit_msg(state);1362}13631364say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);13651366 apply_status =run_apply(state, NULL);13671368if(apply_status && state->threeway) {1369struct strbuf sb = STRBUF_INIT;13701371strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1372 apply_status =fall_back_threeway(state, sb.buf);1373strbuf_release(&sb);13741375/*1376 * Applying the patch to an earlier tree and merging1377 * the result may have produced the same tree as ours.1378 */1379if(!apply_status && !index_has_changes(NULL)) {1380say(state, stdout,_("No changes -- Patch already applied."));1381goto next;1382}1383}13841385if(apply_status) {1386int advice_amworkdir =1;13871388printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1389linelen(state->msg), state->msg);13901391git_config_get_bool("advice.amworkdir", &advice_amworkdir);13921393if(advice_amworkdir)1394printf_ln(_("The copy of the patch that failed is found in:%s"),1395am_path(state,"patch"));13961397die_user_resolve(state);1398}13991400do_commit(state);14011402next:1403am_next(state);1404}14051406if(!is_empty_file(am_path(state,"rewritten"))) {1407assert(state->rebasing);1408run_post_rewrite_hook(state);1409}14101411/*1412 * In rebasing mode, it's up to the caller to take care of1413 * housekeeping.1414 */1415if(!state->rebasing) {1416am_destroy(state);1417run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1418}1419}14201421/**1422 * Resume the current am session after patch application failure. The user did1423 * all the hard work, and we do not have to do any patch application. Just1424 * trust and commit what the user has in the index and working tree.1425 */1426static voidam_resolve(struct am_state *state)1427{1428validate_resume_state(state);14291430say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);14311432if(!index_has_changes(NULL)) {1433printf_ln(_("No changes - did you forget to use 'git add'?\n"1434"If there is nothing left to stage, chances are that something else\n"1435"already introduced the same changes; you might want to skip this patch."));1436die_user_resolve(state);1437}14381439if(unmerged_cache()) {1440printf_ln(_("You still have unmerged paths in your index.\n"1441"Did you forget to use 'git add'?"));1442die_user_resolve(state);1443}14441445do_commit(state);14461447am_next(state);1448am_run(state,0);1449}14501451/**1452 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1453 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1454 * failure.1455 */1456static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1457{1458struct lock_file *lock_file;1459struct unpack_trees_options opts;1460struct tree_desc t[2];14611462if(parse_tree(head) ||parse_tree(remote))1463return-1;14641465 lock_file =xcalloc(1,sizeof(struct lock_file));1466hold_locked_index(lock_file,1);14671468refresh_cache(REFRESH_QUIET);14691470memset(&opts,0,sizeof(opts));1471 opts.head_idx =1;1472 opts.src_index = &the_index;1473 opts.dst_index = &the_index;1474 opts.update =1;1475 opts.merge =1;1476 opts.reset = reset;1477 opts.fn = twoway_merge;1478init_tree_desc(&t[0], head->buffer, head->size);1479init_tree_desc(&t[1], remote->buffer, remote->size);14801481if(unpack_trees(2, t, &opts)) {1482rollback_lock_file(lock_file);1483return-1;1484}14851486if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1487die(_("unable to write new index file"));14881489return0;1490}14911492/**1493 * Clean the index without touching entries that are not modified between1494 * `head` and `remote`.1495 */1496static intclean_index(const unsigned char*head,const unsigned char*remote)1497{1498struct lock_file *lock_file;1499struct tree *head_tree, *remote_tree, *index_tree;1500unsigned char index[GIT_SHA1_RAWSZ];1501struct pathspec pathspec;15021503 head_tree =parse_tree_indirect(head);1504if(!head_tree)1505returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));15061507 remote_tree =parse_tree_indirect(remote);1508if(!remote_tree)1509returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));15101511read_cache_unmerged();15121513if(fast_forward_to(head_tree, head_tree,1))1514return-1;15151516if(write_cache_as_tree(index,0, NULL))1517return-1;15181519 index_tree =parse_tree_indirect(index);1520if(!index_tree)1521returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));15221523if(fast_forward_to(index_tree, remote_tree,0))1524return-1;15251526memset(&pathspec,0,sizeof(pathspec));15271528 lock_file =xcalloc(1,sizeof(struct lock_file));1529hold_locked_index(lock_file,1);15301531if(read_tree(remote_tree,0, &pathspec)) {1532rollback_lock_file(lock_file);1533return-1;1534}15351536if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1537die(_("unable to write new index file"));15381539remove_branch_state();15401541return0;1542}15431544/**1545 * Resume the current am session by skipping the current patch.1546 */1547static voidam_skip(struct am_state *state)1548{1549unsigned char head[GIT_SHA1_RAWSZ];15501551if(get_sha1("HEAD", head))1552hashcpy(head, EMPTY_TREE_SHA1_BIN);15531554if(clean_index(head, head))1555die(_("failed to clean index"));15561557am_next(state);1558am_run(state,0);1559}15601561/**1562 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.1563 *1564 * It is not safe to reset HEAD when:1565 * 1. git-am previously failed because the index was dirty.1566 * 2. HEAD has moved since git-am previously failed.1567 */1568static intsafe_to_abort(const struct am_state *state)1569{1570struct strbuf sb = STRBUF_INIT;1571unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];15721573if(file_exists(am_path(state,"dirtyindex")))1574return0;15751576if(read_state_file(&sb, state,"abort-safety",1) >0) {1577if(get_sha1_hex(sb.buf, abort_safety))1578die(_("could not parse%s"),am_path(state,"abort_safety"));1579}else1580hashclr(abort_safety);15811582if(get_sha1("HEAD", head))1583hashclr(head);15841585if(!hashcmp(head, abort_safety))1586return1;15871588error(_("You seem to have moved HEAD since the last 'am' failure.\n"1589"Not rewinding to ORIG_HEAD"));15901591return0;1592}15931594/**1595 * Aborts the current am session if it is safe to do so.1596 */1597static voidam_abort(struct am_state *state)1598{1599unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];1600int has_curr_head, has_orig_head;1601char*curr_branch;16021603if(!safe_to_abort(state)) {1604am_destroy(state);1605return;1606}16071608 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);1609 has_curr_head = !is_null_sha1(curr_head);1610if(!has_curr_head)1611hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);16121613 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);1614if(!has_orig_head)1615hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);16161617clean_index(curr_head, orig_head);16181619if(has_orig_head)1620update_ref("am --abort","HEAD", orig_head,1621 has_curr_head ? curr_head : NULL,0,1622 UPDATE_REFS_DIE_ON_ERR);1623else if(curr_branch)1624delete_ref(curr_branch, NULL, REF_NODEREF);16251626free(curr_branch);1627am_destroy(state);1628}16291630/**1631 * parse_options() callback that validates and sets opt->value to the1632 * PATCH_FORMAT_* enum value corresponding to `arg`.1633 */1634static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)1635{1636int*opt_value = opt->value;16371638if(!strcmp(arg,"mbox"))1639*opt_value = PATCH_FORMAT_MBOX;1640else1641returnerror(_("Invalid value for --patch-format:%s"), arg);1642return0;1643}16441645enum resume_mode {1646 RESUME_FALSE =0,1647 RESUME_APPLY,1648 RESUME_RESOLVED,1649 RESUME_SKIP,1650 RESUME_ABORT1651};16521653intcmd_am(int argc,const char**argv,const char*prefix)1654{1655struct am_state state;1656int keep_cr = -1;1657int patch_format = PATCH_FORMAT_UNKNOWN;1658enum resume_mode resume = RESUME_FALSE;16591660const char*const usage[] = {1661N_("git am [options] [(<mbox>|<Maildir>)...]"),1662N_("git am [options] (--continue | --skip | --abort)"),1663 NULL1664};16651666struct option options[] = {1667OPT_BOOL('3',"3way", &state.threeway,1668N_("allow fall back on 3way merging if needed")),1669OPT__QUIET(&state.quiet,N_("be quiet")),1670OPT_BOOL('s',"signoff", &state.signoff,1671N_("add a Signed-off-by line to the commit message")),1672OPT_BOOL('u',"utf8", &state.utf8,1673N_("recode into utf8 (default)")),1674OPT_SET_INT('k',"keep", &state.keep,1675N_("pass -k flag to git-mailinfo"), KEEP_TRUE),1676OPT_SET_INT(0,"keep-non-patch", &state.keep,1677N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),1678OPT_BOOL('m',"message-id", &state.message_id,1679N_("pass -m flag to git-mailinfo")),1680{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,1681N_("pass --keep-cr flag to git-mailsplit for mbox format"),1682 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},1683{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,1684N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),1685 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},1686OPT_BOOL('c',"scissors", &state.scissors,1687N_("strip everything before a scissors line")),1688OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),1689N_("pass it through git-apply"),16900),1691OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,1692N_("pass it through git-apply"),1693 PARSE_OPT_NOARG),1694OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,1695N_("pass it through git-apply"),1696 PARSE_OPT_NOARG),1697OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),1698N_("pass it through git-apply"),16990),1700OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),1701N_("pass it through git-apply"),17020),1703OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),1704N_("pass it through git-apply"),17050),1706OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),1707N_("pass it through git-apply"),17080),1709OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),1710N_("pass it through git-apply"),17110),1712OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),1713N_("format the patch(es) are in"),1714 parse_opt_patchformat),1715OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,1716N_("pass it through git-apply"),1717 PARSE_OPT_NOARG),1718OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,1719N_("override error message when patch failure occurs")),1720OPT_CMDMODE(0,"continue", &resume,1721N_("continue applying patches after resolving a conflict"),1722 RESUME_RESOLVED),1723OPT_CMDMODE('r',"resolved", &resume,1724N_("synonyms for --continue"),1725 RESUME_RESOLVED),1726OPT_CMDMODE(0,"skip", &resume,1727N_("skip the current patch"),1728 RESUME_SKIP),1729OPT_CMDMODE(0,"abort", &resume,1730N_("restore the original branch and abort the patching operation."),1731 RESUME_ABORT),1732OPT_BOOL(0,"committer-date-is-author-date",1733&state.committer_date_is_author_date,1734N_("lie about committer date")),1735OPT_BOOL(0,"ignore-date", &state.ignore_date,1736N_("use current timestamp for author date")),1737{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),1738N_("GPG-sign commits"),1739 PARSE_OPT_OPTARG, NULL, (intptr_t)""},1740OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,1741N_("(internal use for git-rebase)")),1742OPT_END()1743};17441745/*1746 * NEEDSWORK: Once all the features of git-am.sh have been1747 * re-implemented in builtin/am.c, this preamble can be removed.1748 */1749if(!getenv("_GIT_USE_BUILTIN_AM")) {1750const char*path =mkpath("%s/git-am",git_exec_path());17511752if(sane_execvp(path, (char**)argv) <0)1753die_errno("could not exec%s", path);1754}else{1755 prefix =setup_git_directory();1756trace_repo_setup(prefix);1757setup_work_tree();1758}17591760git_config(git_default_config, NULL);17611762am_state_init(&state,git_path("rebase-apply"));17631764 argc =parse_options(argc, argv, prefix, options, usage,0);17651766if(read_index_preload(&the_index, NULL) <0)1767die(_("failed to read the index"));17681769if(am_in_progress(&state)) {1770/*1771 * Catch user error to feed us patches when there is a session1772 * in progress:1773 *1774 * 1. mbox path(s) are provided on the command-line.1775 * 2. stdin is not a tty: the user is trying to feed us a patch1776 * from standard input. This is somewhat unreliable -- stdin1777 * could be /dev/null for example and the caller did not1778 * intend to feed us a patch but wanted to continue1779 * unattended.1780 */1781if(argc || (resume == RESUME_FALSE && !isatty(0)))1782die(_("previous rebase directory%sstill exists but mbox given."),1783 state.dir);17841785if(resume == RESUME_FALSE)1786 resume = RESUME_APPLY;17871788am_load(&state);1789}else{1790struct argv_array paths = ARGV_ARRAY_INIT;1791int i;17921793/*1794 * Handle stray state directory in the independent-run case. In1795 * the --rebasing case, it is up to the caller to take care of1796 * stray directories.1797 */1798if(file_exists(state.dir) && !state.rebasing) {1799if(resume == RESUME_ABORT) {1800am_destroy(&state);1801am_state_release(&state);1802return0;1803}18041805die(_("Stray%sdirectory found.\n"1806"Use\"git am --abort\"to remove it."),1807 state.dir);1808}18091810if(resume)1811die(_("Resolve operation not in progress, we are not resuming."));18121813for(i =0; i < argc; i++) {1814if(is_absolute_path(argv[i]) || !prefix)1815argv_array_push(&paths, argv[i]);1816else1817argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));1818}18191820am_setup(&state, patch_format, paths.argv, keep_cr);18211822argv_array_clear(&paths);1823}18241825switch(resume) {1826case RESUME_FALSE:1827am_run(&state,0);1828break;1829case RESUME_APPLY:1830am_run(&state,1);1831break;1832case RESUME_RESOLVED:1833am_resolve(&state);1834break;1835case RESUME_SKIP:1836am_skip(&state);1837break;1838case RESUME_ABORT:1839am_abort(&state);1840break;1841default:1842die("BUG: invalid resume value");1843}18441845am_state_release(&state);18461847return0;1848}