1/* 2 * Builtin "git am" 3 * 4 * Based on git-am.sh by Junio C Hamano. 5 */ 6#include"cache.h" 7#include"config.h" 8#include"builtin.h" 9#include"exec-cmd.h" 10#include"parse-options.h" 11#include"dir.h" 12#include"run-command.h" 13#include"quote.h" 14#include"tempfile.h" 15#include"lockfile.h" 16#include"cache-tree.h" 17#include"refs.h" 18#include"commit.h" 19#include"diff.h" 20#include"diffcore.h" 21#include"unpack-trees.h" 22#include"branch.h" 23#include"sequencer.h" 24#include"revision.h" 25#include"merge-recursive.h" 26#include"revision.h" 27#include"log-tree.h" 28#include"notes-utils.h" 29#include"rerere.h" 30#include"prompt.h" 31#include"mailinfo.h" 32#include"apply.h" 33#include"string-list.h" 34#include"packfile.h" 35#include"repository.h" 36 37/** 38 * Returns 1 if the file is empty or does not exist, 0 otherwise. 39 */ 40static intis_empty_file(const char*filename) 41{ 42struct stat st; 43 44if(stat(filename, &st) <0) { 45if(errno == ENOENT) 46return1; 47die_errno(_("could not stat%s"), filename); 48} 49 50return!st.st_size; 51} 52 53/** 54 * Returns the length of the first line of msg. 55 */ 56static intlinelen(const char*msg) 57{ 58returnstrchrnul(msg,'\n') - msg; 59} 60 61/** 62 * Returns true if `str` consists of only whitespace, false otherwise. 63 */ 64static intstr_isspace(const char*str) 65{ 66for(; *str; str++) 67if(!isspace(*str)) 68return0; 69 70return1; 71} 72 73enum patch_format { 74 PATCH_FORMAT_UNKNOWN =0, 75 PATCH_FORMAT_MBOX, 76 PATCH_FORMAT_STGIT, 77 PATCH_FORMAT_STGIT_SERIES, 78 PATCH_FORMAT_HG, 79 PATCH_FORMAT_MBOXRD 80}; 81 82enum keep_type { 83 KEEP_FALSE =0, 84 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 85 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 86}; 87 88enum scissors_type { 89 SCISSORS_UNSET = -1, 90 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 91 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 92}; 93 94enum signoff_type { 95 SIGNOFF_FALSE =0, 96 SIGNOFF_TRUE =1, 97 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 98}; 99 100struct am_state { 101/* state directory path */ 102char*dir; 103 104/* current and last patch numbers, 1-indexed */ 105int cur; 106int last; 107 108/* commit metadata and message */ 109char*author_name; 110char*author_email; 111char*author_date; 112char*msg; 113size_t msg_len; 114 115/* when --rebasing, records the original commit the patch came from */ 116struct object_id orig_commit; 117 118/* number of digits in patch filename */ 119int prec; 120 121/* various operating modes and command line options */ 122int interactive; 123int threeway; 124int quiet; 125int signoff;/* enum signoff_type */ 126int utf8; 127int keep;/* enum keep_type */ 128int message_id; 129int scissors;/* enum scissors_type */ 130struct argv_array git_apply_opts; 131const char*resolvemsg; 132int committer_date_is_author_date; 133int ignore_date; 134int allow_rerere_autoupdate; 135const char*sign_commit; 136int rebasing; 137}; 138 139/** 140 * Initializes am_state with the default values. 141 */ 142static voidam_state_init(struct am_state *state) 143{ 144int gpgsign; 145 146memset(state,0,sizeof(*state)); 147 148 state->dir =git_pathdup("rebase-apply"); 149 150 state->prec =4; 151 152git_config_get_bool("am.threeway", &state->threeway); 153 154 state->utf8 =1; 155 156git_config_get_bool("am.messageid", &state->message_id); 157 158 state->scissors = SCISSORS_UNSET; 159 160argv_array_init(&state->git_apply_opts); 161 162if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 163 state->sign_commit = gpgsign ?"": NULL; 164} 165 166/** 167 * Releases memory allocated by an am_state. 168 */ 169static voidam_state_release(struct am_state *state) 170{ 171free(state->dir); 172free(state->author_name); 173free(state->author_email); 174free(state->author_date); 175free(state->msg); 176argv_array_clear(&state->git_apply_opts); 177} 178 179/** 180 * Returns path relative to the am_state directory. 181 */ 182staticinlineconst char*am_path(const struct am_state *state,const char*path) 183{ 184returnmkpath("%s/%s", state->dir, path); 185} 186 187/** 188 * For convenience to call write_file() 189 */ 190static voidwrite_state_text(const struct am_state *state, 191const char*name,const char*string) 192{ 193write_file(am_path(state, name),"%s", string); 194} 195 196static voidwrite_state_count(const struct am_state *state, 197const char*name,int value) 198{ 199write_file(am_path(state, name),"%d", value); 200} 201 202static voidwrite_state_bool(const struct am_state *state, 203const char*name,int value) 204{ 205write_state_text(state, name, value ?"t":"f"); 206} 207 208/** 209 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 210 * at the end. 211 */ 212static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 213{ 214va_list ap; 215 216va_start(ap, fmt); 217if(!state->quiet) { 218vfprintf(fp, fmt, ap); 219putc('\n', fp); 220} 221va_end(ap); 222} 223 224/** 225 * Returns 1 if there is an am session in progress, 0 otherwise. 226 */ 227static intam_in_progress(const struct am_state *state) 228{ 229struct stat st; 230 231if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 232return0; 233if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 234return0; 235if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 236return0; 237return1; 238} 239 240/** 241 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 242 * number of bytes read on success, -1 if the file does not exist. If `trim` is 243 * set, trailing whitespace will be removed. 244 */ 245static intread_state_file(struct strbuf *sb,const struct am_state *state, 246const char*file,int trim) 247{ 248strbuf_reset(sb); 249 250if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 251if(trim) 252strbuf_trim(sb); 253 254return sb->len; 255} 256 257if(errno == ENOENT) 258return-1; 259 260die_errno(_("could not read '%s'"),am_path(state, file)); 261} 262 263/** 264 * Reads and parses the state directory's "author-script" file, and sets 265 * state->author_name, state->author_email and state->author_date accordingly. 266 * Returns 0 on success, -1 if the file could not be parsed. 267 * 268 * The author script is of the format: 269 * 270 * GIT_AUTHOR_NAME='$author_name' 271 * GIT_AUTHOR_EMAIL='$author_email' 272 * GIT_AUTHOR_DATE='$author_date' 273 * 274 * where $author_name, $author_email and $author_date are quoted. We are strict 275 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 276 * script, and thus if the file differs from what this function expects, it is 277 * better to bail out than to do something that the user does not expect. 278 */ 279static intread_am_author_script(struct am_state *state) 280{ 281const char*filename =am_path(state,"author-script"); 282 283assert(!state->author_name); 284assert(!state->author_email); 285assert(!state->author_date); 286 287returnread_author_script(filename, &state->author_name, 288&state->author_email, &state->author_date,1); 289} 290 291/** 292 * Saves state->author_name, state->author_email and state->author_date in the 293 * state directory's "author-script" file. 294 */ 295static voidwrite_author_script(const struct am_state *state) 296{ 297struct strbuf sb = STRBUF_INIT; 298 299strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 300sq_quote_buf(&sb, state->author_name); 301strbuf_addch(&sb,'\n'); 302 303strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 304sq_quote_buf(&sb, state->author_email); 305strbuf_addch(&sb,'\n'); 306 307strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 308sq_quote_buf(&sb, state->author_date); 309strbuf_addch(&sb,'\n'); 310 311write_state_text(state,"author-script", sb.buf); 312 313strbuf_release(&sb); 314} 315 316/** 317 * Reads the commit message from the state directory's "final-commit" file, 318 * setting state->msg to its contents and state->msg_len to the length of its 319 * contents in bytes. 320 * 321 * Returns 0 on success, -1 if the file does not exist. 322 */ 323static intread_commit_msg(struct am_state *state) 324{ 325struct strbuf sb = STRBUF_INIT; 326 327assert(!state->msg); 328 329if(read_state_file(&sb, state,"final-commit",0) <0) { 330strbuf_release(&sb); 331return-1; 332} 333 334 state->msg =strbuf_detach(&sb, &state->msg_len); 335return0; 336} 337 338/** 339 * Saves state->msg in the state directory's "final-commit" file. 340 */ 341static voidwrite_commit_msg(const struct am_state *state) 342{ 343const char*filename =am_path(state,"final-commit"); 344write_file_buf(filename, state->msg, state->msg_len); 345} 346 347/** 348 * Loads state from disk. 349 */ 350static voidam_load(struct am_state *state) 351{ 352struct strbuf sb = STRBUF_INIT; 353 354if(read_state_file(&sb, state,"next",1) <0) 355BUG("state file 'next' does not exist"); 356 state->cur =strtol(sb.buf, NULL,10); 357 358if(read_state_file(&sb, state,"last",1) <0) 359BUG("state file 'last' does not exist"); 360 state->last =strtol(sb.buf, NULL,10); 361 362if(read_am_author_script(state) <0) 363die(_("could not parse author script")); 364 365read_commit_msg(state); 366 367if(read_state_file(&sb, state,"original-commit",1) <0) 368oidclr(&state->orig_commit); 369else if(get_oid_hex(sb.buf, &state->orig_commit) <0) 370die(_("could not parse%s"),am_path(state,"original-commit")); 371 372read_state_file(&sb, state,"threeway",1); 373 state->threeway = !strcmp(sb.buf,"t"); 374 375read_state_file(&sb, state,"quiet",1); 376 state->quiet = !strcmp(sb.buf,"t"); 377 378read_state_file(&sb, state,"sign",1); 379 state->signoff = !strcmp(sb.buf,"t"); 380 381read_state_file(&sb, state,"utf8",1); 382 state->utf8 = !strcmp(sb.buf,"t"); 383 384if(file_exists(am_path(state,"rerere-autoupdate"))) { 385read_state_file(&sb, state,"rerere-autoupdate",1); 386 state->allow_rerere_autoupdate =strcmp(sb.buf,"t") ? 387 RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE; 388}else{ 389 state->allow_rerere_autoupdate =0; 390} 391 392read_state_file(&sb, state,"keep",1); 393if(!strcmp(sb.buf,"t")) 394 state->keep = KEEP_TRUE; 395else if(!strcmp(sb.buf,"b")) 396 state->keep = KEEP_NON_PATCH; 397else 398 state->keep = KEEP_FALSE; 399 400read_state_file(&sb, state,"messageid",1); 401 state->message_id = !strcmp(sb.buf,"t"); 402 403read_state_file(&sb, state,"scissors",1); 404if(!strcmp(sb.buf,"t")) 405 state->scissors = SCISSORS_TRUE; 406else if(!strcmp(sb.buf,"f")) 407 state->scissors = SCISSORS_FALSE; 408else 409 state->scissors = SCISSORS_UNSET; 410 411read_state_file(&sb, state,"apply-opt",1); 412argv_array_clear(&state->git_apply_opts); 413if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 414die(_("could not parse%s"),am_path(state,"apply-opt")); 415 416 state->rebasing = !!file_exists(am_path(state,"rebasing")); 417 418strbuf_release(&sb); 419} 420 421/** 422 * Removes the am_state directory, forcefully terminating the current am 423 * session. 424 */ 425static voidam_destroy(const struct am_state *state) 426{ 427struct strbuf sb = STRBUF_INIT; 428 429strbuf_addstr(&sb, state->dir); 430remove_dir_recursively(&sb,0); 431strbuf_release(&sb); 432} 433 434/** 435 * Runs applypatch-msg hook. Returns its exit code. 436 */ 437static intrun_applypatch_msg_hook(struct am_state *state) 438{ 439int ret; 440 441assert(state->msg); 442 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 443 444if(!ret) { 445FREE_AND_NULL(state->msg); 446if(read_commit_msg(state) <0) 447die(_("'%s' was deleted by the applypatch-msg hook"), 448am_path(state,"final-commit")); 449} 450 451return ret; 452} 453 454/** 455 * Runs post-rewrite hook. Returns it exit code. 456 */ 457static intrun_post_rewrite_hook(const struct am_state *state) 458{ 459struct child_process cp = CHILD_PROCESS_INIT; 460const char*hook =find_hook("post-rewrite"); 461int ret; 462 463if(!hook) 464return0; 465 466argv_array_push(&cp.args, hook); 467argv_array_push(&cp.args,"rebase"); 468 469 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 470 cp.stdout_to_stderr =1; 471 472 ret =run_command(&cp); 473 474close(cp.in); 475return ret; 476} 477 478/** 479 * Reads the state directory's "rewritten" file, and copies notes from the old 480 * commits listed in the file to their rewritten commits. 481 * 482 * Returns 0 on success, -1 on failure. 483 */ 484static intcopy_notes_for_rebase(const struct am_state *state) 485{ 486struct notes_rewrite_cfg *c; 487struct strbuf sb = STRBUF_INIT; 488const char*invalid_line =_("Malformed input line: '%s'."); 489const char*msg ="Notes added by 'git rebase'"; 490FILE*fp; 491int ret =0; 492 493assert(state->rebasing); 494 495 c =init_copy_notes_for_rewrite("rebase"); 496if(!c) 497return0; 498 499 fp =xfopen(am_path(state,"rewritten"),"r"); 500 501while(!strbuf_getline_lf(&sb, fp)) { 502struct object_id from_obj, to_obj; 503 504if(sb.len != GIT_SHA1_HEXSZ *2+1) { 505 ret =error(invalid_line, sb.buf); 506goto finish; 507} 508 509if(get_oid_hex(sb.buf, &from_obj)) { 510 ret =error(invalid_line, sb.buf); 511goto finish; 512} 513 514if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 515 ret =error(invalid_line, sb.buf); 516goto finish; 517} 518 519if(get_oid_hex(sb.buf + GIT_SHA1_HEXSZ +1, &to_obj)) { 520 ret =error(invalid_line, sb.buf); 521goto finish; 522} 523 524if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 525 ret =error(_("Failed to copy notes from '%s' to '%s'"), 526oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 527} 528 529finish: 530finish_copy_notes_for_rewrite(c, msg); 531fclose(fp); 532strbuf_release(&sb); 533return ret; 534} 535 536/** 537 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 538 * non-indented lines and checking if they look like they begin with valid 539 * header field names. 540 * 541 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 542 */ 543static intis_mail(FILE*fp) 544{ 545const char*header_regex ="^[!-9;-~]+:"; 546struct strbuf sb = STRBUF_INIT; 547 regex_t regex; 548int ret =1; 549 550if(fseek(fp,0L, SEEK_SET)) 551die_errno(_("fseek failed")); 552 553if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 554die("invalid pattern:%s", header_regex); 555 556while(!strbuf_getline(&sb, fp)) { 557if(!sb.len) 558break;/* End of header */ 559 560/* Ignore indented folded lines */ 561if(*sb.buf =='\t'|| *sb.buf ==' ') 562continue; 563 564/* It's a header if it matches header_regex */ 565if(regexec(®ex, sb.buf,0, NULL,0)) { 566 ret =0; 567goto done; 568} 569} 570 571done: 572regfree(®ex); 573strbuf_release(&sb); 574return ret; 575} 576 577/** 578 * Attempts to detect the patch_format of the patches contained in `paths`, 579 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 580 * detection fails. 581 */ 582static intdetect_patch_format(const char**paths) 583{ 584enum patch_format ret = PATCH_FORMAT_UNKNOWN; 585struct strbuf l1 = STRBUF_INIT; 586struct strbuf l2 = STRBUF_INIT; 587struct strbuf l3 = STRBUF_INIT; 588FILE*fp; 589 590/* 591 * We default to mbox format if input is from stdin and for directories 592 */ 593if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 594return PATCH_FORMAT_MBOX; 595 596/* 597 * Otherwise, check the first few lines of the first patch, starting 598 * from the first non-blank line, to try to detect its format. 599 */ 600 601 fp =xfopen(*paths,"r"); 602 603while(!strbuf_getline(&l1, fp)) { 604if(l1.len) 605break; 606} 607 608if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 609 ret = PATCH_FORMAT_MBOX; 610goto done; 611} 612 613if(starts_with(l1.buf,"# This series applies on GIT commit")) { 614 ret = PATCH_FORMAT_STGIT_SERIES; 615goto done; 616} 617 618if(!strcmp(l1.buf,"# HG changeset patch")) { 619 ret = PATCH_FORMAT_HG; 620goto done; 621} 622 623strbuf_getline(&l2, fp); 624strbuf_getline(&l3, fp); 625 626/* 627 * If the second line is empty and the third is a From, Author or Date 628 * entry, this is likely an StGit patch. 629 */ 630if(l1.len && !l2.len && 631(starts_with(l3.buf,"From:") || 632starts_with(l3.buf,"Author:") || 633starts_with(l3.buf,"Date:"))) { 634 ret = PATCH_FORMAT_STGIT; 635goto done; 636} 637 638if(l1.len &&is_mail(fp)) { 639 ret = PATCH_FORMAT_MBOX; 640goto done; 641} 642 643done: 644fclose(fp); 645strbuf_release(&l1); 646strbuf_release(&l2); 647strbuf_release(&l3); 648return ret; 649} 650 651/** 652 * Splits out individual email patches from `paths`, where each path is either 653 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 654 */ 655static intsplit_mail_mbox(struct am_state *state,const char**paths, 656int keep_cr,int mboxrd) 657{ 658struct child_process cp = CHILD_PROCESS_INIT; 659struct strbuf last = STRBUF_INIT; 660int ret; 661 662 cp.git_cmd =1; 663argv_array_push(&cp.args,"mailsplit"); 664argv_array_pushf(&cp.args,"-d%d", state->prec); 665argv_array_pushf(&cp.args,"-o%s", state->dir); 666argv_array_push(&cp.args,"-b"); 667if(keep_cr) 668argv_array_push(&cp.args,"--keep-cr"); 669if(mboxrd) 670argv_array_push(&cp.args,"--mboxrd"); 671argv_array_push(&cp.args,"--"); 672argv_array_pushv(&cp.args, paths); 673 674 ret =capture_command(&cp, &last,8); 675if(ret) 676goto exit; 677 678 state->cur =1; 679 state->last =strtol(last.buf, NULL,10); 680 681exit: 682strbuf_release(&last); 683return ret ? -1:0; 684} 685 686/** 687 * Callback signature for split_mail_conv(). The foreign patch should be 688 * read from `in`, and the converted patch (in RFC2822 mail format) should be 689 * written to `out`. Return 0 on success, or -1 on failure. 690 */ 691typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 692 693/** 694 * Calls `fn` for each file in `paths` to convert the foreign patch to the 695 * RFC2822 mail format suitable for parsing with git-mailinfo. 696 * 697 * Returns 0 on success, -1 on failure. 698 */ 699static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 700const char**paths,int keep_cr) 701{ 702static const char*stdin_only[] = {"-", NULL}; 703int i; 704 705if(!*paths) 706 paths = stdin_only; 707 708for(i =0; *paths; paths++, i++) { 709FILE*in, *out; 710const char*mail; 711int ret; 712 713if(!strcmp(*paths,"-")) 714 in = stdin; 715else 716 in =fopen(*paths,"r"); 717 718if(!in) 719returnerror_errno(_("could not open '%s' for reading"), 720*paths); 721 722 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 723 724 out =fopen(mail,"w"); 725if(!out) { 726if(in != stdin) 727fclose(in); 728returnerror_errno(_("could not open '%s' for writing"), 729 mail); 730} 731 732 ret =fn(out, in, keep_cr); 733 734fclose(out); 735if(in != stdin) 736fclose(in); 737 738if(ret) 739returnerror(_("could not parse patch '%s'"), *paths); 740} 741 742 state->cur =1; 743 state->last = i; 744return0; 745} 746 747/** 748 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 749 * message suitable for parsing with git-mailinfo. 750 */ 751static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 752{ 753struct strbuf sb = STRBUF_INIT; 754int subject_printed =0; 755 756while(!strbuf_getline_lf(&sb, in)) { 757const char*str; 758 759if(str_isspace(sb.buf)) 760continue; 761else if(skip_prefix(sb.buf,"Author:", &str)) 762fprintf(out,"From:%s\n", str); 763else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 764fprintf(out,"%s\n", sb.buf); 765else if(!subject_printed) { 766fprintf(out,"Subject:%s\n", sb.buf); 767 subject_printed =1; 768}else{ 769fprintf(out,"\n%s\n", sb.buf); 770break; 771} 772} 773 774strbuf_reset(&sb); 775while(strbuf_fread(&sb,8192, in) >0) { 776fwrite(sb.buf,1, sb.len, out); 777strbuf_reset(&sb); 778} 779 780strbuf_release(&sb); 781return0; 782} 783 784/** 785 * This function only supports a single StGit series file in `paths`. 786 * 787 * Given an StGit series file, converts the StGit patches in the series into 788 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 789 * the state directory. 790 * 791 * Returns 0 on success, -1 on failure. 792 */ 793static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 794int keep_cr) 795{ 796const char*series_dir; 797char*series_dir_buf; 798FILE*fp; 799struct argv_array patches = ARGV_ARRAY_INIT; 800struct strbuf sb = STRBUF_INIT; 801int ret; 802 803if(!paths[0] || paths[1]) 804returnerror(_("Only one StGIT patch series can be applied at once")); 805 806 series_dir_buf =xstrdup(*paths); 807 series_dir =dirname(series_dir_buf); 808 809 fp =fopen(*paths,"r"); 810if(!fp) 811returnerror_errno(_("could not open '%s' for reading"), *paths); 812 813while(!strbuf_getline_lf(&sb, fp)) { 814if(*sb.buf =='#') 815continue;/* skip comment lines */ 816 817argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 818} 819 820fclose(fp); 821strbuf_release(&sb); 822free(series_dir_buf); 823 824 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 825 826argv_array_clear(&patches); 827return ret; 828} 829 830/** 831 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 832 * message suitable for parsing with git-mailinfo. 833 */ 834static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 835{ 836struct strbuf sb = STRBUF_INIT; 837int rc =0; 838 839while(!strbuf_getline_lf(&sb, in)) { 840const char*str; 841 842if(skip_prefix(sb.buf,"# User ", &str)) 843fprintf(out,"From:%s\n", str); 844else if(skip_prefix(sb.buf,"# Date ", &str)) { 845 timestamp_t timestamp; 846long tz, tz2; 847char*end; 848 849 errno =0; 850 timestamp =parse_timestamp(str, &end,10); 851if(errno) { 852 rc =error(_("invalid timestamp")); 853goto exit; 854} 855 856if(!skip_prefix(end," ", &str)) { 857 rc =error(_("invalid Date line")); 858goto exit; 859} 860 861 errno =0; 862 tz =strtol(str, &end,10); 863if(errno) { 864 rc =error(_("invalid timezone offset")); 865goto exit; 866} 867 868if(*end) { 869 rc =error(_("invalid Date line")); 870goto exit; 871} 872 873/* 874 * mercurial's timezone is in seconds west of UTC, 875 * however git's timezone is in hours + minutes east of 876 * UTC. Convert it. 877 */ 878 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 879if(tz >0) 880 tz2 = -tz2; 881 882fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 883}else if(starts_with(sb.buf,"# ")) { 884continue; 885}else{ 886fprintf(out,"\n%s\n", sb.buf); 887break; 888} 889} 890 891strbuf_reset(&sb); 892while(strbuf_fread(&sb,8192, in) >0) { 893fwrite(sb.buf,1, sb.len, out); 894strbuf_reset(&sb); 895} 896exit: 897strbuf_release(&sb); 898return rc; 899} 900 901/** 902 * Splits a list of files/directories into individual email patches. Each path 903 * in `paths` must be a file/directory that is formatted according to 904 * `patch_format`. 905 * 906 * Once split out, the individual email patches will be stored in the state 907 * directory, with each patch's filename being its index, padded to state->prec 908 * digits. 909 * 910 * state->cur will be set to the index of the first mail, and state->last will 911 * be set to the index of the last mail. 912 * 913 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 914 * to disable this behavior, -1 to use the default configured setting. 915 * 916 * Returns 0 on success, -1 on failure. 917 */ 918static intsplit_mail(struct am_state *state,enum patch_format patch_format, 919const char**paths,int keep_cr) 920{ 921if(keep_cr <0) { 922 keep_cr =0; 923git_config_get_bool("am.keepcr", &keep_cr); 924} 925 926switch(patch_format) { 927case PATCH_FORMAT_MBOX: 928returnsplit_mail_mbox(state, paths, keep_cr,0); 929case PATCH_FORMAT_STGIT: 930returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 931case PATCH_FORMAT_STGIT_SERIES: 932returnsplit_mail_stgit_series(state, paths, keep_cr); 933case PATCH_FORMAT_HG: 934returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 935case PATCH_FORMAT_MBOXRD: 936returnsplit_mail_mbox(state, paths, keep_cr,1); 937default: 938BUG("invalid patch_format"); 939} 940return-1; 941} 942 943/** 944 * Setup a new am session for applying patches 945 */ 946static voidam_setup(struct am_state *state,enum patch_format patch_format, 947const char**paths,int keep_cr) 948{ 949struct object_id curr_head; 950const char*str; 951struct strbuf sb = STRBUF_INIT; 952 953if(!patch_format) 954 patch_format =detect_patch_format(paths); 955 956if(!patch_format) { 957fprintf_ln(stderr,_("Patch format detection failed.")); 958exit(128); 959} 960 961if(mkdir(state->dir,0777) <0&& errno != EEXIST) 962die_errno(_("failed to create directory '%s'"), state->dir); 963delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF); 964 965if(split_mail(state, patch_format, paths, keep_cr) <0) { 966am_destroy(state); 967die(_("Failed to split patches.")); 968} 969 970if(state->rebasing) 971 state->threeway =1; 972 973write_state_bool(state,"threeway", state->threeway); 974write_state_bool(state,"quiet", state->quiet); 975write_state_bool(state,"sign", state->signoff); 976write_state_bool(state,"utf8", state->utf8); 977 978if(state->allow_rerere_autoupdate) 979write_state_bool(state,"rerere-autoupdate", 980 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE); 981 982switch(state->keep) { 983case KEEP_FALSE: 984 str ="f"; 985break; 986case KEEP_TRUE: 987 str ="t"; 988break; 989case KEEP_NON_PATCH: 990 str ="b"; 991break; 992default: 993BUG("invalid value for state->keep"); 994} 995 996write_state_text(state,"keep", str); 997write_state_bool(state,"messageid", state->message_id); 998 999switch(state->scissors) {1000case SCISSORS_UNSET:1001 str ="";1002break;1003case SCISSORS_FALSE:1004 str ="f";1005break;1006case SCISSORS_TRUE:1007 str ="t";1008break;1009default:1010BUG("invalid value for state->scissors");1011}1012write_state_text(state,"scissors", str);10131014sq_quote_argv(&sb, state->git_apply_opts.argv);1015write_state_text(state,"apply-opt", sb.buf);10161017if(state->rebasing)1018write_state_text(state,"rebasing","");1019else1020write_state_text(state,"applying","");10211022if(!get_oid("HEAD", &curr_head)) {1023write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1024if(!state->rebasing)1025update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1026 UPDATE_REFS_DIE_ON_ERR);1027}else{1028write_state_text(state,"abort-safety","");1029if(!state->rebasing)1030delete_ref(NULL,"ORIG_HEAD", NULL,0);1031}10321033/*1034 * NOTE: Since the "next" and "last" files determine if an am_state1035 * session is in progress, they should be written last.1036 */10371038write_state_count(state,"next", state->cur);1039write_state_count(state,"last", state->last);10401041strbuf_release(&sb);1042}10431044/**1045 * Increments the patch pointer, and cleans am_state for the application of the1046 * next patch.1047 */1048static voidam_next(struct am_state *state)1049{1050struct object_id head;10511052FREE_AND_NULL(state->author_name);1053FREE_AND_NULL(state->author_email);1054FREE_AND_NULL(state->author_date);1055FREE_AND_NULL(state->msg);1056 state->msg_len =0;10571058unlink(am_path(state,"author-script"));1059unlink(am_path(state,"final-commit"));10601061oidclr(&state->orig_commit);1062unlink(am_path(state,"original-commit"));1063delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10641065if(!get_oid("HEAD", &head))1066write_state_text(state,"abort-safety",oid_to_hex(&head));1067else1068write_state_text(state,"abort-safety","");10691070 state->cur++;1071write_state_count(state,"next", state->cur);1072}10731074/**1075 * Returns the filename of the current patch email.1076 */1077static const char*msgnum(const struct am_state *state)1078{1079static struct strbuf sb = STRBUF_INIT;10801081strbuf_reset(&sb);1082strbuf_addf(&sb,"%0*d", state->prec, state->cur);10831084return sb.buf;1085}10861087/**1088 * Refresh and write index.1089 */1090static voidrefresh_and_write_cache(void)1091{1092struct lock_file lock_file = LOCK_INIT;10931094hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1095refresh_cache(REFRESH_QUIET);1096if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1097die(_("unable to write index file"));1098}10991100/**1101 * Dies with a user-friendly message on how to proceed after resolving the1102 * problem. This message can be overridden with state->resolvemsg.1103 */1104static void NORETURN die_user_resolve(const struct am_state *state)1105{1106if(state->resolvemsg) {1107printf_ln("%s", state->resolvemsg);1108}else{1109const char*cmdline = state->interactive ?"git am -i":"git am";11101111printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1112printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1113printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1114}11151116exit(128);1117}11181119/**1120 * Appends signoff to the "msg" field of the am_state.1121 */1122static voidam_append_signoff(struct am_state *state)1123{1124struct strbuf sb = STRBUF_INIT;11251126strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1127append_signoff(&sb,0,0);1128 state->msg =strbuf_detach(&sb, &state->msg_len);1129}11301131/**1132 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1133 * state->msg will be set to the patch message. state->author_name,1134 * state->author_email and state->author_date will be set to the patch author's1135 * name, email and date respectively. The patch body will be written to the1136 * state directory's "patch" file.1137 *1138 * Returns 1 if the patch should be skipped, 0 otherwise.1139 */1140static intparse_mail(struct am_state *state,const char*mail)1141{1142FILE*fp;1143struct strbuf sb = STRBUF_INIT;1144struct strbuf msg = STRBUF_INIT;1145struct strbuf author_name = STRBUF_INIT;1146struct strbuf author_date = STRBUF_INIT;1147struct strbuf author_email = STRBUF_INIT;1148int ret =0;1149struct mailinfo mi;11501151setup_mailinfo(&mi);11521153if(state->utf8)1154 mi.metainfo_charset =get_commit_output_encoding();1155else1156 mi.metainfo_charset = NULL;11571158switch(state->keep) {1159case KEEP_FALSE:1160break;1161case KEEP_TRUE:1162 mi.keep_subject =1;1163break;1164case KEEP_NON_PATCH:1165 mi.keep_non_patch_brackets_in_subject =1;1166break;1167default:1168BUG("invalid value for state->keep");1169}11701171if(state->message_id)1172 mi.add_message_id =1;11731174switch(state->scissors) {1175case SCISSORS_UNSET:1176break;1177case SCISSORS_FALSE:1178 mi.use_scissors =0;1179break;1180case SCISSORS_TRUE:1181 mi.use_scissors =1;1182break;1183default:1184BUG("invalid value for state->scissors");1185}11861187 mi.input =xfopen(mail,"r");1188 mi.output =xfopen(am_path(state,"info"),"w");1189if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1190die("could not parse patch");11911192fclose(mi.input);1193fclose(mi.output);11941195if(mi.format_flowed)1196warning(_("Patch sent with format=flowed; "1197"space at the end of lines might be lost."));11981199/* Extract message and author information */1200 fp =xfopen(am_path(state,"info"),"r");1201while(!strbuf_getline_lf(&sb, fp)) {1202const char*x;12031204if(skip_prefix(sb.buf,"Subject: ", &x)) {1205if(msg.len)1206strbuf_addch(&msg,'\n');1207strbuf_addstr(&msg, x);1208}else if(skip_prefix(sb.buf,"Author: ", &x))1209strbuf_addstr(&author_name, x);1210else if(skip_prefix(sb.buf,"Email: ", &x))1211strbuf_addstr(&author_email, x);1212else if(skip_prefix(sb.buf,"Date: ", &x))1213strbuf_addstr(&author_date, x);1214}1215fclose(fp);12161217/* Skip pine's internal folder data */1218if(!strcmp(author_name.buf,"Mail System Internal Data")) {1219 ret =1;1220goto finish;1221}12221223if(is_empty_file(am_path(state,"patch"))) {1224printf_ln(_("Patch is empty."));1225die_user_resolve(state);1226}12271228strbuf_addstr(&msg,"\n\n");1229strbuf_addbuf(&msg, &mi.log_message);1230strbuf_stripspace(&msg,0);12311232assert(!state->author_name);1233 state->author_name =strbuf_detach(&author_name, NULL);12341235assert(!state->author_email);1236 state->author_email =strbuf_detach(&author_email, NULL);12371238assert(!state->author_date);1239 state->author_date =strbuf_detach(&author_date, NULL);12401241assert(!state->msg);1242 state->msg =strbuf_detach(&msg, &state->msg_len);12431244finish:1245strbuf_release(&msg);1246strbuf_release(&author_date);1247strbuf_release(&author_email);1248strbuf_release(&author_name);1249strbuf_release(&sb);1250clear_mailinfo(&mi);1251return ret;1252}12531254/**1255 * Sets commit_id to the commit hash where the mail was generated from.1256 * Returns 0 on success, -1 on failure.1257 */1258static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1259{1260struct strbuf sb = STRBUF_INIT;1261FILE*fp =xfopen(mail,"r");1262const char*x;1263int ret =0;12641265if(strbuf_getline_lf(&sb, fp) ||1266!skip_prefix(sb.buf,"From ", &x) ||1267get_oid_hex(x, commit_id) <0)1268 ret = -1;12691270strbuf_release(&sb);1271fclose(fp);1272return ret;1273}12741275/**1276 * Sets state->msg, state->author_name, state->author_email, state->author_date1277 * to the commit's respective info.1278 */1279static voidget_commit_info(struct am_state *state,struct commit *commit)1280{1281const char*buffer, *ident_line, *msg;1282size_t ident_len;1283struct ident_split id;12841285 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());12861287 ident_line =find_commit_header(buffer,"author", &ident_len);12881289if(split_ident_line(&id, ident_line, ident_len) <0)1290die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12911292assert(!state->author_name);1293if(id.name_begin)1294 state->author_name =1295xmemdupz(id.name_begin, id.name_end - id.name_begin);1296else1297 state->author_name =xstrdup("");12981299assert(!state->author_email);1300if(id.mail_begin)1301 state->author_email =1302xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1303else1304 state->author_email =xstrdup("");13051306assert(!state->author_date);1307 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));13081309assert(!state->msg);1310 msg =strstr(buffer,"\n\n");1311if(!msg)1312die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1313 state->msg =xstrdup(msg +2);1314 state->msg_len =strlen(state->msg);1315unuse_commit_buffer(commit, buffer);1316}13171318/**1319 * Writes `commit` as a patch to the state directory's "patch" file.1320 */1321static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1322{1323struct rev_info rev_info;1324FILE*fp;13251326 fp =xfopen(am_path(state,"patch"),"w");1327repo_init_revisions(the_repository, &rev_info, NULL);1328 rev_info.diff =1;1329 rev_info.abbrev =0;1330 rev_info.disable_stdin =1;1331 rev_info.show_root_diff =1;1332 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1333 rev_info.no_commit_id =1;1334 rev_info.diffopt.flags.binary =1;1335 rev_info.diffopt.flags.full_index =1;1336 rev_info.diffopt.use_color =0;1337 rev_info.diffopt.file = fp;1338 rev_info.diffopt.close_file =1;1339add_pending_object(&rev_info, &commit->object,"");1340diff_setup_done(&rev_info.diffopt);1341log_tree_commit(&rev_info, commit);1342}13431344/**1345 * Writes the diff of the index against HEAD as a patch to the state1346 * directory's "patch" file.1347 */1348static voidwrite_index_patch(const struct am_state *state)1349{1350struct tree *tree;1351struct object_id head;1352struct rev_info rev_info;1353FILE*fp;13541355if(!get_oid_tree("HEAD", &head))1356 tree =lookup_tree(the_repository, &head);1357else1358 tree =lookup_tree(the_repository,1359 the_repository->hash_algo->empty_tree);13601361 fp =xfopen(am_path(state,"patch"),"w");1362repo_init_revisions(the_repository, &rev_info, NULL);1363 rev_info.diff =1;1364 rev_info.disable_stdin =1;1365 rev_info.no_commit_id =1;1366 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1367 rev_info.diffopt.use_color =0;1368 rev_info.diffopt.file = fp;1369 rev_info.diffopt.close_file =1;1370add_pending_object(&rev_info, &tree->object,"");1371diff_setup_done(&rev_info.diffopt);1372run_diff_index(&rev_info,1);1373}13741375/**1376 * Like parse_mail(), but parses the mail by looking up its commit ID1377 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1378 * of patches.1379 *1380 * state->orig_commit will be set to the original commit ID.1381 *1382 * Will always return 0 as the patch should never be skipped.1383 */1384static intparse_mail_rebase(struct am_state *state,const char*mail)1385{1386struct commit *commit;1387struct object_id commit_oid;13881389if(get_mail_commit_oid(&commit_oid, mail) <0)1390die(_("could not parse%s"), mail);13911392 commit =lookup_commit_or_die(&commit_oid, mail);13931394get_commit_info(state, commit);13951396write_commit_patch(state, commit);13971398oidcpy(&state->orig_commit, &commit_oid);1399write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1400update_ref("am","REBASE_HEAD", &commit_oid,1401 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);14021403return0;1404}14051406/**1407 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1408 * `index_file` is not NULL, the patch will be applied to that index.1409 */1410static intrun_apply(const struct am_state *state,const char*index_file)1411{1412struct argv_array apply_paths = ARGV_ARRAY_INIT;1413struct argv_array apply_opts = ARGV_ARRAY_INIT;1414struct apply_state apply_state;1415int res, opts_left;1416int force_apply =0;1417int options =0;14181419if(init_apply_state(&apply_state, the_repository, NULL))1420BUG("init_apply_state() failed");14211422argv_array_push(&apply_opts,"apply");1423argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14241425 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1426&apply_state, &force_apply, &options,1427 NULL);14281429if(opts_left !=0)1430die("unknown option passed through to git apply");14311432if(index_file) {1433 apply_state.index_file = index_file;1434 apply_state.cached =1;1435}else1436 apply_state.check_index =1;14371438/*1439 * If we are allowed to fall back on 3-way merge, don't give false1440 * errors during the initial attempt.1441 */1442if(state->threeway && !index_file)1443 apply_state.apply_verbosity = verbosity_silent;14441445if(check_apply_state(&apply_state, force_apply))1446BUG("check_apply_state() failed");14471448argv_array_push(&apply_paths,am_path(state,"patch"));14491450 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14511452argv_array_clear(&apply_paths);1453argv_array_clear(&apply_opts);1454clear_apply_state(&apply_state);14551456if(res)1457return res;14581459if(index_file) {1460/* Reload index as apply_all_patches() will have modified it. */1461discard_cache();1462read_cache_from(index_file);1463}14641465return0;1466}14671468/**1469 * Builds an index that contains just the blobs needed for a 3way merge.1470 */1471static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1472{1473struct child_process cp = CHILD_PROCESS_INIT;14741475 cp.git_cmd =1;1476argv_array_push(&cp.args,"apply");1477argv_array_pushv(&cp.args, state->git_apply_opts.argv);1478argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1479argv_array_push(&cp.args,am_path(state,"patch"));14801481if(run_command(&cp))1482return-1;14831484return0;1485}14861487/**1488 * Attempt a threeway merge, using index_path as the temporary index.1489 */1490static intfall_back_threeway(const struct am_state *state,const char*index_path)1491{1492struct object_id orig_tree, their_tree, our_tree;1493const struct object_id *bases[1] = { &orig_tree };1494struct merge_options o;1495struct commit *result;1496char*their_tree_name;14971498if(get_oid("HEAD", &our_tree) <0)1499oidcpy(&our_tree, the_hash_algo->empty_tree);15001501if(build_fake_ancestor(state, index_path))1502returnerror("could not build fake ancestor");15031504discard_cache();1505read_cache_from(index_path);15061507if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1508returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15091510say(state, stdout,_("Using index info to reconstruct a base tree..."));15111512if(!state->quiet) {1513/*1514 * List paths that needed 3-way fallback, so that the user can1515 * review them with extra care to spot mismerges.1516 */1517struct rev_info rev_info;1518const char*diff_filter_str ="--diff-filter=AM";15191520repo_init_revisions(the_repository, &rev_info, NULL);1521 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1522diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1523add_pending_oid(&rev_info,"HEAD", &our_tree,0);1524diff_setup_done(&rev_info.diffopt);1525run_diff_index(&rev_info,1);1526}15271528if(run_apply(state, index_path))1529returnerror(_("Did you hand edit your patch?\n"1530"It does not apply to blobs recorded in its index."));15311532if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1533returnerror("could not write tree");15341535say(state, stdout,_("Falling back to patching base and 3-way merge..."));15361537discard_cache();1538read_cache();15391540/*1541 * This is not so wrong. Depending on which base we picked, orig_tree1542 * may be wildly different from ours, but their_tree has the same set of1543 * wildly different changes in parts the patch did not touch, so1544 * recursive ends up canceling them, saying that we reverted all those1545 * changes.1546 */15471548init_merge_options(&o);15491550 o.branch1 ="HEAD";1551 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1552 o.branch2 = their_tree_name;1553 o.detect_directory_renames =0;15541555if(state->quiet)1556 o.verbosity =0;15571558if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1559repo_rerere(the_repository, state->allow_rerere_autoupdate);1560free(their_tree_name);1561returnerror(_("Failed to merge in the changes."));1562}15631564free(their_tree_name);1565return0;1566}15671568/**1569 * Commits the current index with state->msg as the commit message and1570 * state->author_name, state->author_email and state->author_date as the author1571 * information.1572 */1573static voiddo_commit(const struct am_state *state)1574{1575struct object_id tree, parent, commit;1576const struct object_id *old_oid;1577struct commit_list *parents = NULL;1578const char*reflog_msg, *author;1579struct strbuf sb = STRBUF_INIT;15801581if(run_hook_le(NULL,"pre-applypatch", NULL))1582exit(1);15831584if(write_cache_as_tree(&tree,0, NULL))1585die(_("git write-tree failed to write a tree"));15861587if(!get_oid_commit("HEAD", &parent)) {1588 old_oid = &parent;1589commit_list_insert(lookup_commit(the_repository, &parent),1590&parents);1591}else{1592 old_oid = NULL;1593say(state, stderr,_("applying to an empty history"));1594}15951596 author =fmt_ident(state->author_name, state->author_email,1597 state->ignore_date ? NULL : state->author_date,1598 IDENT_STRICT);15991600if(state->committer_date_is_author_date)1601setenv("GIT_COMMITTER_DATE",1602 state->ignore_date ?"": state->author_date,1);16031604if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1605 author, state->sign_commit))1606die(_("failed to write commit object"));16071608 reflog_msg =getenv("GIT_REFLOG_ACTION");1609if(!reflog_msg)1610 reflog_msg ="am";16111612strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1613 state->msg);16141615update_ref(sb.buf,"HEAD", &commit, old_oid,0,1616 UPDATE_REFS_DIE_ON_ERR);16171618if(state->rebasing) {1619FILE*fp =xfopen(am_path(state,"rewritten"),"a");16201621assert(!is_null_oid(&state->orig_commit));1622fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1623fprintf(fp,"%s\n",oid_to_hex(&commit));1624fclose(fp);1625}16261627run_hook_le(NULL,"post-applypatch", NULL);16281629strbuf_release(&sb);1630}16311632/**1633 * Validates the am_state for resuming -- the "msg" and authorship fields must1634 * be filled up.1635 */1636static voidvalidate_resume_state(const struct am_state *state)1637{1638if(!state->msg)1639die(_("cannot resume:%sdoes not exist."),1640am_path(state,"final-commit"));16411642if(!state->author_name || !state->author_email || !state->author_date)1643die(_("cannot resume:%sdoes not exist."),1644am_path(state,"author-script"));1645}16461647/**1648 * Interactively prompt the user on whether the current patch should be1649 * applied.1650 *1651 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1652 * skip it.1653 */1654static intdo_interactive(struct am_state *state)1655{1656assert(state->msg);16571658if(!isatty(0))1659die(_("cannot be interactive without stdin connected to a terminal."));16601661for(;;) {1662const char*reply;16631664puts(_("Commit Body is:"));1665puts("--------------------------");1666printf("%s", state->msg);1667puts("--------------------------");16681669/*1670 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1671 * in your translation. The program will only accept English1672 * input at this point.1673 */1674 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);16751676if(!reply) {1677continue;1678}else if(*reply =='y'|| *reply =='Y') {1679return0;1680}else if(*reply =='a'|| *reply =='A') {1681 state->interactive =0;1682return0;1683}else if(*reply =='n'|| *reply =='N') {1684return1;1685}else if(*reply =='e'|| *reply =='E') {1686struct strbuf msg = STRBUF_INIT;16871688if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1689free(state->msg);1690 state->msg =strbuf_detach(&msg, &state->msg_len);1691}1692strbuf_release(&msg);1693}else if(*reply =='v'|| *reply =='V') {1694const char*pager =git_pager(1);1695struct child_process cp = CHILD_PROCESS_INIT;16961697if(!pager)1698 pager ="cat";1699prepare_pager_args(&cp, pager);1700argv_array_push(&cp.args,am_path(state,"patch"));1701run_command(&cp);1702}1703}1704}17051706/**1707 * Applies all queued mail.1708 *1709 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1710 * well as the state directory's "patch" file is used as-is for applying the1711 * patch and committing it.1712 */1713static voidam_run(struct am_state *state,int resume)1714{1715const char*argv_gc_auto[] = {"gc","--auto", NULL};1716struct strbuf sb = STRBUF_INIT;17171718unlink(am_path(state,"dirtyindex"));17191720refresh_and_write_cache();17211722if(index_has_changes(&the_index, NULL, &sb)) {1723write_state_bool(state,"dirtyindex",1);1724die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1725}17261727strbuf_release(&sb);17281729while(state->cur <= state->last) {1730const char*mail =am_path(state,msgnum(state));1731int apply_status;17321733reset_ident_date();17341735if(!file_exists(mail))1736goto next;17371738if(resume) {1739validate_resume_state(state);1740}else{1741int skip;17421743if(state->rebasing)1744 skip =parse_mail_rebase(state, mail);1745else1746 skip =parse_mail(state, mail);17471748if(skip)1749goto next;/* mail should be skipped */17501751if(state->signoff)1752am_append_signoff(state);17531754write_author_script(state);1755write_commit_msg(state);1756}17571758if(state->interactive &&do_interactive(state))1759goto next;17601761if(run_applypatch_msg_hook(state))1762exit(1);17631764say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17651766 apply_status =run_apply(state, NULL);17671768if(apply_status && state->threeway) {1769struct strbuf sb = STRBUF_INIT;17701771strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1772 apply_status =fall_back_threeway(state, sb.buf);1773strbuf_release(&sb);17741775/*1776 * Applying the patch to an earlier tree and merging1777 * the result may have produced the same tree as ours.1778 */1779if(!apply_status &&1780!index_has_changes(&the_index, NULL, NULL)) {1781say(state, stdout,_("No changes -- Patch already applied."));1782goto next;1783}1784}17851786if(apply_status) {1787printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1788linelen(state->msg), state->msg);17891790if(advice_amworkdir)1791advise(_("Use 'git am --show-current-patch' to see the failed patch"));17921793die_user_resolve(state);1794}17951796do_commit(state);17971798next:1799am_next(state);18001801if(resume)1802am_load(state);1803 resume =0;1804}18051806if(!is_empty_file(am_path(state,"rewritten"))) {1807assert(state->rebasing);1808copy_notes_for_rebase(state);1809run_post_rewrite_hook(state);1810}18111812/*1813 * In rebasing mode, it's up to the caller to take care of1814 * housekeeping.1815 */1816if(!state->rebasing) {1817am_destroy(state);1818close_all_packs(the_repository->objects);1819run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1820}1821}18221823/**1824 * Resume the current am session after patch application failure. The user did1825 * all the hard work, and we do not have to do any patch application. Just1826 * trust and commit what the user has in the index and working tree.1827 */1828static voidam_resolve(struct am_state *state)1829{1830validate_resume_state(state);18311832say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18331834if(!index_has_changes(&the_index, NULL, NULL)) {1835printf_ln(_("No changes - did you forget to use 'git add'?\n"1836"If there is nothing left to stage, chances are that something else\n"1837"already introduced the same changes; you might want to skip this patch."));1838die_user_resolve(state);1839}18401841if(unmerged_cache()) {1842printf_ln(_("You still have unmerged paths in your index.\n"1843"You should 'git add' each file with resolved conflicts to mark them as such.\n"1844"You might run `git rm` on a file to accept\"deleted by them\"for it."));1845die_user_resolve(state);1846}18471848if(state->interactive) {1849write_index_patch(state);1850if(do_interactive(state))1851goto next;1852}18531854repo_rerere(the_repository,0);18551856do_commit(state);18571858next:1859am_next(state);1860am_load(state);1861am_run(state,0);1862}18631864/**1865 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1866 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1867 * failure.1868 */1869static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1870{1871struct lock_file lock_file = LOCK_INIT;1872struct unpack_trees_options opts;1873struct tree_desc t[2];18741875if(parse_tree(head) ||parse_tree(remote))1876return-1;18771878hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18791880refresh_cache(REFRESH_QUIET);18811882memset(&opts,0,sizeof(opts));1883 opts.head_idx =1;1884 opts.src_index = &the_index;1885 opts.dst_index = &the_index;1886 opts.update =1;1887 opts.merge =1;1888 opts.reset = reset;1889 opts.fn = twoway_merge;1890init_tree_desc(&t[0], head->buffer, head->size);1891init_tree_desc(&t[1], remote->buffer, remote->size);18921893if(unpack_trees(2, t, &opts)) {1894rollback_lock_file(&lock_file);1895return-1;1896}18971898if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1899die(_("unable to write new index file"));19001901return0;1902}19031904/**1905 * Merges a tree into the index. The index's stat info will take precedence1906 * over the merged tree's. Returns 0 on success, -1 on failure.1907 */1908static intmerge_tree(struct tree *tree)1909{1910struct lock_file lock_file = LOCK_INIT;1911struct unpack_trees_options opts;1912struct tree_desc t[1];19131914if(parse_tree(tree))1915return-1;19161917hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19181919memset(&opts,0,sizeof(opts));1920 opts.head_idx =1;1921 opts.src_index = &the_index;1922 opts.dst_index = &the_index;1923 opts.merge =1;1924 opts.fn = oneway_merge;1925init_tree_desc(&t[0], tree->buffer, tree->size);19261927if(unpack_trees(1, t, &opts)) {1928rollback_lock_file(&lock_file);1929return-1;1930}19311932if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1933die(_("unable to write new index file"));19341935return0;1936}19371938/**1939 * Clean the index without touching entries that are not modified between1940 * `head` and `remote`.1941 */1942static intclean_index(const struct object_id *head,const struct object_id *remote)1943{1944struct tree *head_tree, *remote_tree, *index_tree;1945struct object_id index;19461947 head_tree =parse_tree_indirect(head);1948if(!head_tree)1949returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19501951 remote_tree =parse_tree_indirect(remote);1952if(!remote_tree)1953returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19541955read_cache_unmerged();19561957if(fast_forward_to(head_tree, head_tree,1))1958return-1;19591960if(write_cache_as_tree(&index,0, NULL))1961return-1;19621963 index_tree =parse_tree_indirect(&index);1964if(!index_tree)1965returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19661967if(fast_forward_to(index_tree, remote_tree,0))1968return-1;19691970if(merge_tree(remote_tree))1971return-1;19721973remove_branch_state();19741975return0;1976}19771978/**1979 * Resets rerere's merge resolution metadata.1980 */1981static voidam_rerere_clear(void)1982{1983struct string_list merge_rr = STRING_LIST_INIT_DUP;1984rerere_clear(&merge_rr);1985string_list_clear(&merge_rr,1);1986}19871988/**1989 * Resume the current am session by skipping the current patch.1990 */1991static voidam_skip(struct am_state *state)1992{1993struct object_id head;19941995am_rerere_clear();19961997if(get_oid("HEAD", &head))1998oidcpy(&head, the_hash_algo->empty_tree);19992000if(clean_index(&head, &head))2001die(_("failed to clean index"));20022003am_next(state);2004am_load(state);2005am_run(state,0);2006}20072008/**2009 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2010 *2011 * It is not safe to reset HEAD when:2012 * 1. git-am previously failed because the index was dirty.2013 * 2. HEAD has moved since git-am previously failed.2014 */2015static intsafe_to_abort(const struct am_state *state)2016{2017struct strbuf sb = STRBUF_INIT;2018struct object_id abort_safety, head;20192020if(file_exists(am_path(state,"dirtyindex")))2021return0;20222023if(read_state_file(&sb, state,"abort-safety",1) >0) {2024if(get_oid_hex(sb.buf, &abort_safety))2025die(_("could not parse%s"),am_path(state,"abort-safety"));2026}else2027oidclr(&abort_safety);2028strbuf_release(&sb);20292030if(get_oid("HEAD", &head))2031oidclr(&head);20322033if(oideq(&head, &abort_safety))2034return1;20352036warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2037"Not rewinding to ORIG_HEAD"));20382039return0;2040}20412042/**2043 * Aborts the current am session if it is safe to do so.2044 */2045static voidam_abort(struct am_state *state)2046{2047struct object_id curr_head, orig_head;2048int has_curr_head, has_orig_head;2049char*curr_branch;20502051if(!safe_to_abort(state)) {2052am_destroy(state);2053return;2054}20552056am_rerere_clear();20572058 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2059 has_curr_head = curr_branch && !is_null_oid(&curr_head);2060if(!has_curr_head)2061oidcpy(&curr_head, the_hash_algo->empty_tree);20622063 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2064if(!has_orig_head)2065oidcpy(&orig_head, the_hash_algo->empty_tree);20662067clean_index(&curr_head, &orig_head);20682069if(has_orig_head)2070update_ref("am --abort","HEAD", &orig_head,2071 has_curr_head ? &curr_head : NULL,0,2072 UPDATE_REFS_DIE_ON_ERR);2073else if(curr_branch)2074delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20752076free(curr_branch);2077am_destroy(state);2078}20792080static intshow_patch(struct am_state *state)2081{2082struct strbuf sb = STRBUF_INIT;2083const char*patch_path;2084int len;20852086if(!is_null_oid(&state->orig_commit)) {2087const char*av[4] = {"show", NULL,"--", NULL };2088char*new_oid_str;2089int ret;20902091 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2092 ret =run_command_v_opt(av, RUN_GIT_CMD);2093free(new_oid_str);2094return ret;2095}20962097 patch_path =am_path(state,msgnum(state));2098 len =strbuf_read_file(&sb, patch_path,0);2099if(len <0)2100die_errno(_("failed to read '%s'"), patch_path);21012102setup_pager();2103write_in_full(1, sb.buf, sb.len);2104strbuf_release(&sb);2105return0;2106}21072108/**2109 * parse_options() callback that validates and sets opt->value to the2110 * PATCH_FORMAT_* enum value corresponding to `arg`.2111 */2112static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2113{2114int*opt_value = opt->value;21152116if(unset)2117*opt_value = PATCH_FORMAT_UNKNOWN;2118else if(!strcmp(arg,"mbox"))2119*opt_value = PATCH_FORMAT_MBOX;2120else if(!strcmp(arg,"stgit"))2121*opt_value = PATCH_FORMAT_STGIT;2122else if(!strcmp(arg,"stgit-series"))2123*opt_value = PATCH_FORMAT_STGIT_SERIES;2124else if(!strcmp(arg,"hg"))2125*opt_value = PATCH_FORMAT_HG;2126else if(!strcmp(arg,"mboxrd"))2127*opt_value = PATCH_FORMAT_MBOXRD;2128else2129returnerror(_("Invalid value for --patch-format:%s"), arg);2130return0;2131}21322133enum resume_mode {2134 RESUME_FALSE =0,2135 RESUME_APPLY,2136 RESUME_RESOLVED,2137 RESUME_SKIP,2138 RESUME_ABORT,2139 RESUME_QUIT,2140 RESUME_SHOW_PATCH2141};21422143static intgit_am_config(const char*k,const char*v,void*cb)2144{2145int status;21462147 status =git_gpg_config(k, v, NULL);2148if(status)2149return status;21502151returngit_default_config(k, v, NULL);2152}21532154intcmd_am(int argc,const char**argv,const char*prefix)2155{2156struct am_state state;2157int binary = -1;2158int keep_cr = -1;2159int patch_format = PATCH_FORMAT_UNKNOWN;2160enum resume_mode resume = RESUME_FALSE;2161int in_progress;2162int ret =0;21632164const char*const usage[] = {2165N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2166N_("git am [<options>] (--continue | --skip | --abort)"),2167 NULL2168};21692170struct option options[] = {2171OPT_BOOL('i',"interactive", &state.interactive,2172N_("run interactively")),2173OPT_HIDDEN_BOOL('b',"binary", &binary,2174N_("historical option -- no-op")),2175OPT_BOOL('3',"3way", &state.threeway,2176N_("allow fall back on 3way merging if needed")),2177OPT__QUIET(&state.quiet,N_("be quiet")),2178OPT_SET_INT('s',"signoff", &state.signoff,2179N_("add a Signed-off-by line to the commit message"),2180 SIGNOFF_EXPLICIT),2181OPT_BOOL('u',"utf8", &state.utf8,2182N_("recode into utf8 (default)")),2183OPT_SET_INT('k',"keep", &state.keep,2184N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2185OPT_SET_INT(0,"keep-non-patch", &state.keep,2186N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2187OPT_BOOL('m',"message-id", &state.message_id,2188N_("pass -m flag to git-mailinfo")),2189OPT_SET_INT_F(0,"keep-cr", &keep_cr,2190N_("pass --keep-cr flag to git-mailsplit for mbox format"),21911, PARSE_OPT_NONEG),2192OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2193N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21940, PARSE_OPT_NONEG),2195OPT_BOOL('c',"scissors", &state.scissors,2196N_("strip everything before a scissors line")),2197OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2198N_("pass it through git-apply"),21990),2200OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2201N_("pass it through git-apply"),2202 PARSE_OPT_NOARG),2203OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2204N_("pass it through git-apply"),2205 PARSE_OPT_NOARG),2206OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2207N_("pass it through git-apply"),22080),2209OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2210N_("pass it through git-apply"),22110),2212OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2213N_("pass it through git-apply"),22140),2215OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2216N_("pass it through git-apply"),22170),2218OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2219N_("pass it through git-apply"),22200),2221OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2222N_("format the patch(es) are in"),2223 parse_opt_patchformat),2224OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2225N_("pass it through git-apply"),2226 PARSE_OPT_NOARG),2227OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2228N_("override error message when patch failure occurs")),2229OPT_CMDMODE(0,"continue", &resume,2230N_("continue applying patches after resolving a conflict"),2231 RESUME_RESOLVED),2232OPT_CMDMODE('r',"resolved", &resume,2233N_("synonyms for --continue"),2234 RESUME_RESOLVED),2235OPT_CMDMODE(0,"skip", &resume,2236N_("skip the current patch"),2237 RESUME_SKIP),2238OPT_CMDMODE(0,"abort", &resume,2239N_("restore the original branch and abort the patching operation."),2240 RESUME_ABORT),2241OPT_CMDMODE(0,"quit", &resume,2242N_("abort the patching operation but keep HEAD where it is."),2243 RESUME_QUIT),2244OPT_CMDMODE(0,"show-current-patch", &resume,2245N_("show the patch being applied."),2246 RESUME_SHOW_PATCH),2247OPT_BOOL(0,"committer-date-is-author-date",2248&state.committer_date_is_author_date,2249N_("lie about committer date")),2250OPT_BOOL(0,"ignore-date", &state.ignore_date,2251N_("use current timestamp for author date")),2252OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2253{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2254N_("GPG-sign commits"),2255 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2256OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2257N_("(internal use for git-rebase)")),2258OPT_END()2259};22602261if(argc ==2&& !strcmp(argv[1],"-h"))2262usage_with_options(usage, options);22632264git_config(git_am_config, NULL);22652266am_state_init(&state);22672268 in_progress =am_in_progress(&state);2269if(in_progress)2270am_load(&state);22712272 argc =parse_options(argc, argv, prefix, options, usage,0);22732274if(binary >=0)2275fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2276"it will be removed. Please do not use it anymore."));22772278/* Ensure a valid committer ident can be constructed */2279git_committer_info(IDENT_STRICT);22802281if(read_index_preload(&the_index, NULL,0) <0)2282die(_("failed to read the index"));22832284if(in_progress) {2285/*2286 * Catch user error to feed us patches when there is a session2287 * in progress:2288 *2289 * 1. mbox path(s) are provided on the command-line.2290 * 2. stdin is not a tty: the user is trying to feed us a patch2291 * from standard input. This is somewhat unreliable -- stdin2292 * could be /dev/null for example and the caller did not2293 * intend to feed us a patch but wanted to continue2294 * unattended.2295 */2296if(argc || (resume == RESUME_FALSE && !isatty(0)))2297die(_("previous rebase directory%sstill exists but mbox given."),2298 state.dir);22992300if(resume == RESUME_FALSE)2301 resume = RESUME_APPLY;23022303if(state.signoff == SIGNOFF_EXPLICIT)2304am_append_signoff(&state);2305}else{2306struct argv_array paths = ARGV_ARRAY_INIT;2307int i;23082309/*2310 * Handle stray state directory in the independent-run case. In2311 * the --rebasing case, it is up to the caller to take care of2312 * stray directories.2313 */2314if(file_exists(state.dir) && !state.rebasing) {2315if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2316am_destroy(&state);2317am_state_release(&state);2318return0;2319}23202321die(_("Stray%sdirectory found.\n"2322"Use\"git am --abort\"to remove it."),2323 state.dir);2324}23252326if(resume)2327die(_("Resolve operation not in progress, we are not resuming."));23282329for(i =0; i < argc; i++) {2330if(is_absolute_path(argv[i]) || !prefix)2331argv_array_push(&paths, argv[i]);2332else2333argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2334}23352336am_setup(&state, patch_format, paths.argv, keep_cr);23372338argv_array_clear(&paths);2339}23402341switch(resume) {2342case RESUME_FALSE:2343am_run(&state,0);2344break;2345case RESUME_APPLY:2346am_run(&state,1);2347break;2348case RESUME_RESOLVED:2349am_resolve(&state);2350break;2351case RESUME_SKIP:2352am_skip(&state);2353break;2354case RESUME_ABORT:2355am_abort(&state);2356break;2357case RESUME_QUIT:2358am_rerere_clear();2359am_destroy(&state);2360break;2361case RESUME_SHOW_PATCH:2362 ret =show_patch(&state);2363break;2364default:2365BUG("invalid resume value");2366}23672368am_state_release(&state);23692370return ret;2371}