1/* 2 * Builtin "git am" 3 * 4 * Based on git-am.sh by Junio C Hamano. 5 */ 6#define USE_THE_INDEX_COMPATIBILITY_MACROS 7#include"cache.h" 8#include"config.h" 9#include"builtin.h" 10#include"exec-cmd.h" 11#include"parse-options.h" 12#include"dir.h" 13#include"run-command.h" 14#include"quote.h" 15#include"tempfile.h" 16#include"lockfile.h" 17#include"cache-tree.h" 18#include"refs.h" 19#include"commit.h" 20#include"diff.h" 21#include"diffcore.h" 22#include"unpack-trees.h" 23#include"branch.h" 24#include"sequencer.h" 25#include"revision.h" 26#include"merge-recursive.h" 27#include"revision.h" 28#include"log-tree.h" 29#include"notes-utils.h" 30#include"rerere.h" 31#include"prompt.h" 32#include"mailinfo.h" 33#include"apply.h" 34#include"string-list.h" 35#include"packfile.h" 36#include"repository.h" 37 38/** 39 * Returns the length of the first line of msg. 40 */ 41static intlinelen(const char*msg) 42{ 43returnstrchrnul(msg,'\n') - msg; 44} 45 46/** 47 * Returns true if `str` consists of only whitespace, false otherwise. 48 */ 49static intstr_isspace(const char*str) 50{ 51for(; *str; str++) 52if(!isspace(*str)) 53return0; 54 55return1; 56} 57 58enum patch_format { 59 PATCH_FORMAT_UNKNOWN =0, 60 PATCH_FORMAT_MBOX, 61 PATCH_FORMAT_STGIT, 62 PATCH_FORMAT_STGIT_SERIES, 63 PATCH_FORMAT_HG, 64 PATCH_FORMAT_MBOXRD 65}; 66 67enum keep_type { 68 KEEP_FALSE =0, 69 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 70 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 71}; 72 73enum scissors_type { 74 SCISSORS_UNSET = -1, 75 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 76 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 77}; 78 79enum signoff_type { 80 SIGNOFF_FALSE =0, 81 SIGNOFF_TRUE =1, 82 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 83}; 84 85struct am_state { 86/* state directory path */ 87char*dir; 88 89/* current and last patch numbers, 1-indexed */ 90int cur; 91int last; 92 93/* commit metadata and message */ 94char*author_name; 95char*author_email; 96char*author_date; 97char*msg; 98size_t msg_len; 99 100/* when --rebasing, records the original commit the patch came from */ 101struct object_id orig_commit; 102 103/* number of digits in patch filename */ 104int prec; 105 106/* various operating modes and command line options */ 107int interactive; 108int threeway; 109int quiet; 110int signoff;/* enum signoff_type */ 111int utf8; 112int keep;/* enum keep_type */ 113int message_id; 114int scissors;/* enum scissors_type */ 115struct argv_array git_apply_opts; 116const char*resolvemsg; 117int committer_date_is_author_date; 118int ignore_date; 119int allow_rerere_autoupdate; 120const char*sign_commit; 121int rebasing; 122}; 123 124/** 125 * Initializes am_state with the default values. 126 */ 127static voidam_state_init(struct am_state *state) 128{ 129int gpgsign; 130 131memset(state,0,sizeof(*state)); 132 133 state->dir =git_pathdup("rebase-apply"); 134 135 state->prec =4; 136 137git_config_get_bool("am.threeway", &state->threeway); 138 139 state->utf8 =1; 140 141git_config_get_bool("am.messageid", &state->message_id); 142 143 state->scissors = SCISSORS_UNSET; 144 145argv_array_init(&state->git_apply_opts); 146 147if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 148 state->sign_commit = gpgsign ?"": NULL; 149} 150 151/** 152 * Releases memory allocated by an am_state. 153 */ 154static voidam_state_release(struct am_state *state) 155{ 156free(state->dir); 157free(state->author_name); 158free(state->author_email); 159free(state->author_date); 160free(state->msg); 161argv_array_clear(&state->git_apply_opts); 162} 163 164/** 165 * Returns path relative to the am_state directory. 166 */ 167staticinlineconst char*am_path(const struct am_state *state,const char*path) 168{ 169returnmkpath("%s/%s", state->dir, path); 170} 171 172/** 173 * For convenience to call write_file() 174 */ 175static voidwrite_state_text(const struct am_state *state, 176const char*name,const char*string) 177{ 178write_file(am_path(state, name),"%s", string); 179} 180 181static voidwrite_state_count(const struct am_state *state, 182const char*name,int value) 183{ 184write_file(am_path(state, name),"%d", value); 185} 186 187static voidwrite_state_bool(const struct am_state *state, 188const char*name,int value) 189{ 190write_state_text(state, name, value ?"t":"f"); 191} 192 193/** 194 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 195 * at the end. 196 */ 197static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 198{ 199va_list ap; 200 201va_start(ap, fmt); 202if(!state->quiet) { 203vfprintf(fp, fmt, ap); 204putc('\n', fp); 205} 206va_end(ap); 207} 208 209/** 210 * Returns 1 if there is an am session in progress, 0 otherwise. 211 */ 212static intam_in_progress(const struct am_state *state) 213{ 214struct stat st; 215 216if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 217return0; 218if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 219return0; 220if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 221return0; 222return1; 223} 224 225/** 226 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 227 * number of bytes read on success, -1 if the file does not exist. If `trim` is 228 * set, trailing whitespace will be removed. 229 */ 230static intread_state_file(struct strbuf *sb,const struct am_state *state, 231const char*file,int trim) 232{ 233strbuf_reset(sb); 234 235if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 236if(trim) 237strbuf_trim(sb); 238 239return sb->len; 240} 241 242if(errno == ENOENT) 243return-1; 244 245die_errno(_("could not read '%s'"),am_path(state, file)); 246} 247 248/** 249 * Reads and parses the state directory's "author-script" file, and sets 250 * state->author_name, state->author_email and state->author_date accordingly. 251 * Returns 0 on success, -1 if the file could not be parsed. 252 * 253 * The author script is of the format: 254 * 255 * GIT_AUTHOR_NAME='$author_name' 256 * GIT_AUTHOR_EMAIL='$author_email' 257 * GIT_AUTHOR_DATE='$author_date' 258 * 259 * where $author_name, $author_email and $author_date are quoted. We are strict 260 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 261 * script, and thus if the file differs from what this function expects, it is 262 * better to bail out than to do something that the user does not expect. 263 */ 264static intread_am_author_script(struct am_state *state) 265{ 266const char*filename =am_path(state,"author-script"); 267 268assert(!state->author_name); 269assert(!state->author_email); 270assert(!state->author_date); 271 272returnread_author_script(filename, &state->author_name, 273&state->author_email, &state->author_date,1); 274} 275 276/** 277 * Saves state->author_name, state->author_email and state->author_date in the 278 * state directory's "author-script" file. 279 */ 280static voidwrite_author_script(const struct am_state *state) 281{ 282struct strbuf sb = STRBUF_INIT; 283 284strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 285sq_quote_buf(&sb, state->author_name); 286strbuf_addch(&sb,'\n'); 287 288strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 289sq_quote_buf(&sb, state->author_email); 290strbuf_addch(&sb,'\n'); 291 292strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 293sq_quote_buf(&sb, state->author_date); 294strbuf_addch(&sb,'\n'); 295 296write_state_text(state,"author-script", sb.buf); 297 298strbuf_release(&sb); 299} 300 301/** 302 * Reads the commit message from the state directory's "final-commit" file, 303 * setting state->msg to its contents and state->msg_len to the length of its 304 * contents in bytes. 305 * 306 * Returns 0 on success, -1 if the file does not exist. 307 */ 308static intread_commit_msg(struct am_state *state) 309{ 310struct strbuf sb = STRBUF_INIT; 311 312assert(!state->msg); 313 314if(read_state_file(&sb, state,"final-commit",0) <0) { 315strbuf_release(&sb); 316return-1; 317} 318 319 state->msg =strbuf_detach(&sb, &state->msg_len); 320return0; 321} 322 323/** 324 * Saves state->msg in the state directory's "final-commit" file. 325 */ 326static voidwrite_commit_msg(const struct am_state *state) 327{ 328const char*filename =am_path(state,"final-commit"); 329write_file_buf(filename, state->msg, state->msg_len); 330} 331 332/** 333 * Loads state from disk. 334 */ 335static voidam_load(struct am_state *state) 336{ 337struct strbuf sb = STRBUF_INIT; 338 339if(read_state_file(&sb, state,"next",1) <0) 340BUG("state file 'next' does not exist"); 341 state->cur =strtol(sb.buf, NULL,10); 342 343if(read_state_file(&sb, state,"last",1) <0) 344BUG("state file 'last' does not exist"); 345 state->last =strtol(sb.buf, NULL,10); 346 347if(read_am_author_script(state) <0) 348die(_("could not parse author script")); 349 350read_commit_msg(state); 351 352if(read_state_file(&sb, state,"original-commit",1) <0) 353oidclr(&state->orig_commit); 354else if(get_oid_hex(sb.buf, &state->orig_commit) <0) 355die(_("could not parse%s"),am_path(state,"original-commit")); 356 357read_state_file(&sb, state,"threeway",1); 358 state->threeway = !strcmp(sb.buf,"t"); 359 360read_state_file(&sb, state,"quiet",1); 361 state->quiet = !strcmp(sb.buf,"t"); 362 363read_state_file(&sb, state,"sign",1); 364 state->signoff = !strcmp(sb.buf,"t"); 365 366read_state_file(&sb, state,"utf8",1); 367 state->utf8 = !strcmp(sb.buf,"t"); 368 369if(file_exists(am_path(state,"rerere-autoupdate"))) { 370read_state_file(&sb, state,"rerere-autoupdate",1); 371 state->allow_rerere_autoupdate =strcmp(sb.buf,"t") ? 372 RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE; 373}else{ 374 state->allow_rerere_autoupdate =0; 375} 376 377read_state_file(&sb, state,"keep",1); 378if(!strcmp(sb.buf,"t")) 379 state->keep = KEEP_TRUE; 380else if(!strcmp(sb.buf,"b")) 381 state->keep = KEEP_NON_PATCH; 382else 383 state->keep = KEEP_FALSE; 384 385read_state_file(&sb, state,"messageid",1); 386 state->message_id = !strcmp(sb.buf,"t"); 387 388read_state_file(&sb, state,"scissors",1); 389if(!strcmp(sb.buf,"t")) 390 state->scissors = SCISSORS_TRUE; 391else if(!strcmp(sb.buf,"f")) 392 state->scissors = SCISSORS_FALSE; 393else 394 state->scissors = SCISSORS_UNSET; 395 396read_state_file(&sb, state,"apply-opt",1); 397argv_array_clear(&state->git_apply_opts); 398if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 399die(_("could not parse%s"),am_path(state,"apply-opt")); 400 401 state->rebasing = !!file_exists(am_path(state,"rebasing")); 402 403strbuf_release(&sb); 404} 405 406/** 407 * Removes the am_state directory, forcefully terminating the current am 408 * session. 409 */ 410static voidam_destroy(const struct am_state *state) 411{ 412struct strbuf sb = STRBUF_INIT; 413 414strbuf_addstr(&sb, state->dir); 415remove_dir_recursively(&sb,0); 416strbuf_release(&sb); 417} 418 419/** 420 * Runs applypatch-msg hook. Returns its exit code. 421 */ 422static intrun_applypatch_msg_hook(struct am_state *state) 423{ 424int ret; 425 426assert(state->msg); 427 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 428 429if(!ret) { 430FREE_AND_NULL(state->msg); 431if(read_commit_msg(state) <0) 432die(_("'%s' was deleted by the applypatch-msg hook"), 433am_path(state,"final-commit")); 434} 435 436return ret; 437} 438 439/** 440 * Runs post-rewrite hook. Returns it exit code. 441 */ 442static intrun_post_rewrite_hook(const struct am_state *state) 443{ 444struct child_process cp = CHILD_PROCESS_INIT; 445const char*hook =find_hook("post-rewrite"); 446int ret; 447 448if(!hook) 449return0; 450 451argv_array_push(&cp.args, hook); 452argv_array_push(&cp.args,"rebase"); 453 454 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 455 cp.stdout_to_stderr =1; 456 cp.trace2_hook_name ="post-rewrite"; 457 458 ret =run_command(&cp); 459 460close(cp.in); 461return ret; 462} 463 464/** 465 * Reads the state directory's "rewritten" file, and copies notes from the old 466 * commits listed in the file to their rewritten commits. 467 * 468 * Returns 0 on success, -1 on failure. 469 */ 470static intcopy_notes_for_rebase(const struct am_state *state) 471{ 472struct notes_rewrite_cfg *c; 473struct strbuf sb = STRBUF_INIT; 474const char*invalid_line =_("Malformed input line: '%s'."); 475const char*msg ="Notes added by 'git rebase'"; 476FILE*fp; 477int ret =0; 478 479assert(state->rebasing); 480 481 c =init_copy_notes_for_rewrite("rebase"); 482if(!c) 483return0; 484 485 fp =xfopen(am_path(state,"rewritten"),"r"); 486 487while(!strbuf_getline_lf(&sb, fp)) { 488struct object_id from_obj, to_obj; 489const char*p; 490 491if(sb.len != the_hash_algo->hexsz *2+1) { 492 ret =error(invalid_line, sb.buf); 493goto finish; 494} 495 496if(parse_oid_hex(sb.buf, &from_obj, &p)) { 497 ret =error(invalid_line, sb.buf); 498goto finish; 499} 500 501if(*p !=' ') { 502 ret =error(invalid_line, sb.buf); 503goto finish; 504} 505 506if(get_oid_hex(p +1, &to_obj)) { 507 ret =error(invalid_line, sb.buf); 508goto finish; 509} 510 511if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 512 ret =error(_("Failed to copy notes from '%s' to '%s'"), 513oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 514} 515 516finish: 517finish_copy_notes_for_rewrite(the_repository, c, msg); 518fclose(fp); 519strbuf_release(&sb); 520return ret; 521} 522 523/** 524 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 525 * non-indented lines and checking if they look like they begin with valid 526 * header field names. 527 * 528 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 529 */ 530static intis_mail(FILE*fp) 531{ 532const char*header_regex ="^[!-9;-~]+:"; 533struct strbuf sb = STRBUF_INIT; 534 regex_t regex; 535int ret =1; 536 537if(fseek(fp,0L, SEEK_SET)) 538die_errno(_("fseek failed")); 539 540if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 541die("invalid pattern:%s", header_regex); 542 543while(!strbuf_getline(&sb, fp)) { 544if(!sb.len) 545break;/* End of header */ 546 547/* Ignore indented folded lines */ 548if(*sb.buf =='\t'|| *sb.buf ==' ') 549continue; 550 551/* It's a header if it matches header_regex */ 552if(regexec(®ex, sb.buf,0, NULL,0)) { 553 ret =0; 554goto done; 555} 556} 557 558done: 559regfree(®ex); 560strbuf_release(&sb); 561return ret; 562} 563 564/** 565 * Attempts to detect the patch_format of the patches contained in `paths`, 566 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 567 * detection fails. 568 */ 569static intdetect_patch_format(const char**paths) 570{ 571enum patch_format ret = PATCH_FORMAT_UNKNOWN; 572struct strbuf l1 = STRBUF_INIT; 573struct strbuf l2 = STRBUF_INIT; 574struct strbuf l3 = STRBUF_INIT; 575FILE*fp; 576 577/* 578 * We default to mbox format if input is from stdin and for directories 579 */ 580if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 581return PATCH_FORMAT_MBOX; 582 583/* 584 * Otherwise, check the first few lines of the first patch, starting 585 * from the first non-blank line, to try to detect its format. 586 */ 587 588 fp =xfopen(*paths,"r"); 589 590while(!strbuf_getline(&l1, fp)) { 591if(l1.len) 592break; 593} 594 595if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 596 ret = PATCH_FORMAT_MBOX; 597goto done; 598} 599 600if(starts_with(l1.buf,"# This series applies on GIT commit")) { 601 ret = PATCH_FORMAT_STGIT_SERIES; 602goto done; 603} 604 605if(!strcmp(l1.buf,"# HG changeset patch")) { 606 ret = PATCH_FORMAT_HG; 607goto done; 608} 609 610strbuf_getline(&l2, fp); 611strbuf_getline(&l3, fp); 612 613/* 614 * If the second line is empty and the third is a From, Author or Date 615 * entry, this is likely an StGit patch. 616 */ 617if(l1.len && !l2.len && 618(starts_with(l3.buf,"From:") || 619starts_with(l3.buf,"Author:") || 620starts_with(l3.buf,"Date:"))) { 621 ret = PATCH_FORMAT_STGIT; 622goto done; 623} 624 625if(l1.len &&is_mail(fp)) { 626 ret = PATCH_FORMAT_MBOX; 627goto done; 628} 629 630done: 631fclose(fp); 632strbuf_release(&l1); 633strbuf_release(&l2); 634strbuf_release(&l3); 635return ret; 636} 637 638/** 639 * Splits out individual email patches from `paths`, where each path is either 640 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 641 */ 642static intsplit_mail_mbox(struct am_state *state,const char**paths, 643int keep_cr,int mboxrd) 644{ 645struct child_process cp = CHILD_PROCESS_INIT; 646struct strbuf last = STRBUF_INIT; 647int ret; 648 649 cp.git_cmd =1; 650argv_array_push(&cp.args,"mailsplit"); 651argv_array_pushf(&cp.args,"-d%d", state->prec); 652argv_array_pushf(&cp.args,"-o%s", state->dir); 653argv_array_push(&cp.args,"-b"); 654if(keep_cr) 655argv_array_push(&cp.args,"--keep-cr"); 656if(mboxrd) 657argv_array_push(&cp.args,"--mboxrd"); 658argv_array_push(&cp.args,"--"); 659argv_array_pushv(&cp.args, paths); 660 661 ret =capture_command(&cp, &last,8); 662if(ret) 663goto exit; 664 665 state->cur =1; 666 state->last =strtol(last.buf, NULL,10); 667 668exit: 669strbuf_release(&last); 670return ret ? -1:0; 671} 672 673/** 674 * Callback signature for split_mail_conv(). The foreign patch should be 675 * read from `in`, and the converted patch (in RFC2822 mail format) should be 676 * written to `out`. Return 0 on success, or -1 on failure. 677 */ 678typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 679 680/** 681 * Calls `fn` for each file in `paths` to convert the foreign patch to the 682 * RFC2822 mail format suitable for parsing with git-mailinfo. 683 * 684 * Returns 0 on success, -1 on failure. 685 */ 686static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 687const char**paths,int keep_cr) 688{ 689static const char*stdin_only[] = {"-", NULL}; 690int i; 691 692if(!*paths) 693 paths = stdin_only; 694 695for(i =0; *paths; paths++, i++) { 696FILE*in, *out; 697const char*mail; 698int ret; 699 700if(!strcmp(*paths,"-")) 701 in = stdin; 702else 703 in =fopen(*paths,"r"); 704 705if(!in) 706returnerror_errno(_("could not open '%s' for reading"), 707*paths); 708 709 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 710 711 out =fopen(mail,"w"); 712if(!out) { 713if(in != stdin) 714fclose(in); 715returnerror_errno(_("could not open '%s' for writing"), 716 mail); 717} 718 719 ret =fn(out, in, keep_cr); 720 721fclose(out); 722if(in != stdin) 723fclose(in); 724 725if(ret) 726returnerror(_("could not parse patch '%s'"), *paths); 727} 728 729 state->cur =1; 730 state->last = i; 731return0; 732} 733 734/** 735 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 736 * message suitable for parsing with git-mailinfo. 737 */ 738static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 739{ 740struct strbuf sb = STRBUF_INIT; 741int subject_printed =0; 742 743while(!strbuf_getline_lf(&sb, in)) { 744const char*str; 745 746if(str_isspace(sb.buf)) 747continue; 748else if(skip_prefix(sb.buf,"Author:", &str)) 749fprintf(out,"From:%s\n", str); 750else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 751fprintf(out,"%s\n", sb.buf); 752else if(!subject_printed) { 753fprintf(out,"Subject:%s\n", sb.buf); 754 subject_printed =1; 755}else{ 756fprintf(out,"\n%s\n", sb.buf); 757break; 758} 759} 760 761strbuf_reset(&sb); 762while(strbuf_fread(&sb,8192, in) >0) { 763fwrite(sb.buf,1, sb.len, out); 764strbuf_reset(&sb); 765} 766 767strbuf_release(&sb); 768return0; 769} 770 771/** 772 * This function only supports a single StGit series file in `paths`. 773 * 774 * Given an StGit series file, converts the StGit patches in the series into 775 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 776 * the state directory. 777 * 778 * Returns 0 on success, -1 on failure. 779 */ 780static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 781int keep_cr) 782{ 783const char*series_dir; 784char*series_dir_buf; 785FILE*fp; 786struct argv_array patches = ARGV_ARRAY_INIT; 787struct strbuf sb = STRBUF_INIT; 788int ret; 789 790if(!paths[0] || paths[1]) 791returnerror(_("Only one StGIT patch series can be applied at once")); 792 793 series_dir_buf =xstrdup(*paths); 794 series_dir =dirname(series_dir_buf); 795 796 fp =fopen(*paths,"r"); 797if(!fp) 798returnerror_errno(_("could not open '%s' for reading"), *paths); 799 800while(!strbuf_getline_lf(&sb, fp)) { 801if(*sb.buf =='#') 802continue;/* skip comment lines */ 803 804argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 805} 806 807fclose(fp); 808strbuf_release(&sb); 809free(series_dir_buf); 810 811 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 812 813argv_array_clear(&patches); 814return ret; 815} 816 817/** 818 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 819 * message suitable for parsing with git-mailinfo. 820 */ 821static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 822{ 823struct strbuf sb = STRBUF_INIT; 824int rc =0; 825 826while(!strbuf_getline_lf(&sb, in)) { 827const char*str; 828 829if(skip_prefix(sb.buf,"# User ", &str)) 830fprintf(out,"From:%s\n", str); 831else if(skip_prefix(sb.buf,"# Date ", &str)) { 832 timestamp_t timestamp; 833long tz, tz2; 834char*end; 835 836 errno =0; 837 timestamp =parse_timestamp(str, &end,10); 838if(errno) { 839 rc =error(_("invalid timestamp")); 840goto exit; 841} 842 843if(!skip_prefix(end," ", &str)) { 844 rc =error(_("invalid Date line")); 845goto exit; 846} 847 848 errno =0; 849 tz =strtol(str, &end,10); 850if(errno) { 851 rc =error(_("invalid timezone offset")); 852goto exit; 853} 854 855if(*end) { 856 rc =error(_("invalid Date line")); 857goto exit; 858} 859 860/* 861 * mercurial's timezone is in seconds west of UTC, 862 * however git's timezone is in hours + minutes east of 863 * UTC. Convert it. 864 */ 865 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 866if(tz >0) 867 tz2 = -tz2; 868 869fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 870}else if(starts_with(sb.buf,"# ")) { 871continue; 872}else{ 873fprintf(out,"\n%s\n", sb.buf); 874break; 875} 876} 877 878strbuf_reset(&sb); 879while(strbuf_fread(&sb,8192, in) >0) { 880fwrite(sb.buf,1, sb.len, out); 881strbuf_reset(&sb); 882} 883exit: 884strbuf_release(&sb); 885return rc; 886} 887 888/** 889 * Splits a list of files/directories into individual email patches. Each path 890 * in `paths` must be a file/directory that is formatted according to 891 * `patch_format`. 892 * 893 * Once split out, the individual email patches will be stored in the state 894 * directory, with each patch's filename being its index, padded to state->prec 895 * digits. 896 * 897 * state->cur will be set to the index of the first mail, and state->last will 898 * be set to the index of the last mail. 899 * 900 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 901 * to disable this behavior, -1 to use the default configured setting. 902 * 903 * Returns 0 on success, -1 on failure. 904 */ 905static intsplit_mail(struct am_state *state,enum patch_format patch_format, 906const char**paths,int keep_cr) 907{ 908if(keep_cr <0) { 909 keep_cr =0; 910git_config_get_bool("am.keepcr", &keep_cr); 911} 912 913switch(patch_format) { 914case PATCH_FORMAT_MBOX: 915returnsplit_mail_mbox(state, paths, keep_cr,0); 916case PATCH_FORMAT_STGIT: 917returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 918case PATCH_FORMAT_STGIT_SERIES: 919returnsplit_mail_stgit_series(state, paths, keep_cr); 920case PATCH_FORMAT_HG: 921returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 922case PATCH_FORMAT_MBOXRD: 923returnsplit_mail_mbox(state, paths, keep_cr,1); 924default: 925BUG("invalid patch_format"); 926} 927return-1; 928} 929 930/** 931 * Setup a new am session for applying patches 932 */ 933static voidam_setup(struct am_state *state,enum patch_format patch_format, 934const char**paths,int keep_cr) 935{ 936struct object_id curr_head; 937const char*str; 938struct strbuf sb = STRBUF_INIT; 939 940if(!patch_format) 941 patch_format =detect_patch_format(paths); 942 943if(!patch_format) { 944fprintf_ln(stderr,_("Patch format detection failed.")); 945exit(128); 946} 947 948if(mkdir(state->dir,0777) <0&& errno != EEXIST) 949die_errno(_("failed to create directory '%s'"), state->dir); 950delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF); 951 952if(split_mail(state, patch_format, paths, keep_cr) <0) { 953am_destroy(state); 954die(_("Failed to split patches.")); 955} 956 957if(state->rebasing) 958 state->threeway =1; 959 960write_state_bool(state,"threeway", state->threeway); 961write_state_bool(state,"quiet", state->quiet); 962write_state_bool(state,"sign", state->signoff); 963write_state_bool(state,"utf8", state->utf8); 964 965if(state->allow_rerere_autoupdate) 966write_state_bool(state,"rerere-autoupdate", 967 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE); 968 969switch(state->keep) { 970case KEEP_FALSE: 971 str ="f"; 972break; 973case KEEP_TRUE: 974 str ="t"; 975break; 976case KEEP_NON_PATCH: 977 str ="b"; 978break; 979default: 980BUG("invalid value for state->keep"); 981} 982 983write_state_text(state,"keep", str); 984write_state_bool(state,"messageid", state->message_id); 985 986switch(state->scissors) { 987case SCISSORS_UNSET: 988 str =""; 989break; 990case SCISSORS_FALSE: 991 str ="f"; 992break; 993case SCISSORS_TRUE: 994 str ="t"; 995break; 996default: 997BUG("invalid value for state->scissors"); 998} 999write_state_text(state,"scissors", str);10001001sq_quote_argv(&sb, state->git_apply_opts.argv);1002write_state_text(state,"apply-opt", sb.buf);10031004if(state->rebasing)1005write_state_text(state,"rebasing","");1006else1007write_state_text(state,"applying","");10081009if(!get_oid("HEAD", &curr_head)) {1010write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1011if(!state->rebasing)1012update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1013 UPDATE_REFS_DIE_ON_ERR);1014}else{1015write_state_text(state,"abort-safety","");1016if(!state->rebasing)1017delete_ref(NULL,"ORIG_HEAD", NULL,0);1018}10191020/*1021 * NOTE: Since the "next" and "last" files determine if an am_state1022 * session is in progress, they should be written last.1023 */10241025write_state_count(state,"next", state->cur);1026write_state_count(state,"last", state->last);10271028strbuf_release(&sb);1029}10301031/**1032 * Increments the patch pointer, and cleans am_state for the application of the1033 * next patch.1034 */1035static voidam_next(struct am_state *state)1036{1037struct object_id head;10381039FREE_AND_NULL(state->author_name);1040FREE_AND_NULL(state->author_email);1041FREE_AND_NULL(state->author_date);1042FREE_AND_NULL(state->msg);1043 state->msg_len =0;10441045unlink(am_path(state,"author-script"));1046unlink(am_path(state,"final-commit"));10471048oidclr(&state->orig_commit);1049unlink(am_path(state,"original-commit"));1050delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10511052if(!get_oid("HEAD", &head))1053write_state_text(state,"abort-safety",oid_to_hex(&head));1054else1055write_state_text(state,"abort-safety","");10561057 state->cur++;1058write_state_count(state,"next", state->cur);1059}10601061/**1062 * Returns the filename of the current patch email.1063 */1064static const char*msgnum(const struct am_state *state)1065{1066static struct strbuf sb = STRBUF_INIT;10671068strbuf_reset(&sb);1069strbuf_addf(&sb,"%0*d", state->prec, state->cur);10701071return sb.buf;1072}10731074/**1075 * Refresh and write index.1076 */1077static voidrefresh_and_write_cache(void)1078{1079struct lock_file lock_file = LOCK_INIT;10801081hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1082refresh_cache(REFRESH_QUIET);1083if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1084die(_("unable to write index file"));1085}10861087/**1088 * Dies with a user-friendly message on how to proceed after resolving the1089 * problem. This message can be overridden with state->resolvemsg.1090 */1091static void NORETURN die_user_resolve(const struct am_state *state)1092{1093if(state->resolvemsg) {1094printf_ln("%s", state->resolvemsg);1095}else{1096const char*cmdline = state->interactive ?"git am -i":"git am";10971098printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1099printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1100printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1101}11021103exit(128);1104}11051106/**1107 * Appends signoff to the "msg" field of the am_state.1108 */1109static voidam_append_signoff(struct am_state *state)1110{1111struct strbuf sb = STRBUF_INIT;11121113strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1114append_signoff(&sb,0,0);1115 state->msg =strbuf_detach(&sb, &state->msg_len);1116}11171118/**1119 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1120 * state->msg will be set to the patch message. state->author_name,1121 * state->author_email and state->author_date will be set to the patch author's1122 * name, email and date respectively. The patch body will be written to the1123 * state directory's "patch" file.1124 *1125 * Returns 1 if the patch should be skipped, 0 otherwise.1126 */1127static intparse_mail(struct am_state *state,const char*mail)1128{1129FILE*fp;1130struct strbuf sb = STRBUF_INIT;1131struct strbuf msg = STRBUF_INIT;1132struct strbuf author_name = STRBUF_INIT;1133struct strbuf author_date = STRBUF_INIT;1134struct strbuf author_email = STRBUF_INIT;1135int ret =0;1136struct mailinfo mi;11371138setup_mailinfo(&mi);11391140if(state->utf8)1141 mi.metainfo_charset =get_commit_output_encoding();1142else1143 mi.metainfo_charset = NULL;11441145switch(state->keep) {1146case KEEP_FALSE:1147break;1148case KEEP_TRUE:1149 mi.keep_subject =1;1150break;1151case KEEP_NON_PATCH:1152 mi.keep_non_patch_brackets_in_subject =1;1153break;1154default:1155BUG("invalid value for state->keep");1156}11571158if(state->message_id)1159 mi.add_message_id =1;11601161switch(state->scissors) {1162case SCISSORS_UNSET:1163break;1164case SCISSORS_FALSE:1165 mi.use_scissors =0;1166break;1167case SCISSORS_TRUE:1168 mi.use_scissors =1;1169break;1170default:1171BUG("invalid value for state->scissors");1172}11731174 mi.input =xfopen(mail,"r");1175 mi.output =xfopen(am_path(state,"info"),"w");1176if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1177die("could not parse patch");11781179fclose(mi.input);1180fclose(mi.output);11811182if(mi.format_flowed)1183warning(_("Patch sent with format=flowed; "1184"space at the end of lines might be lost."));11851186/* Extract message and author information */1187 fp =xfopen(am_path(state,"info"),"r");1188while(!strbuf_getline_lf(&sb, fp)) {1189const char*x;11901191if(skip_prefix(sb.buf,"Subject: ", &x)) {1192if(msg.len)1193strbuf_addch(&msg,'\n');1194strbuf_addstr(&msg, x);1195}else if(skip_prefix(sb.buf,"Author: ", &x))1196strbuf_addstr(&author_name, x);1197else if(skip_prefix(sb.buf,"Email: ", &x))1198strbuf_addstr(&author_email, x);1199else if(skip_prefix(sb.buf,"Date: ", &x))1200strbuf_addstr(&author_date, x);1201}1202fclose(fp);12031204/* Skip pine's internal folder data */1205if(!strcmp(author_name.buf,"Mail System Internal Data")) {1206 ret =1;1207goto finish;1208}12091210if(is_empty_or_missing_file(am_path(state,"patch"))) {1211printf_ln(_("Patch is empty."));1212die_user_resolve(state);1213}12141215strbuf_addstr(&msg,"\n\n");1216strbuf_addbuf(&msg, &mi.log_message);1217strbuf_stripspace(&msg,0);12181219assert(!state->author_name);1220 state->author_name =strbuf_detach(&author_name, NULL);12211222assert(!state->author_email);1223 state->author_email =strbuf_detach(&author_email, NULL);12241225assert(!state->author_date);1226 state->author_date =strbuf_detach(&author_date, NULL);12271228assert(!state->msg);1229 state->msg =strbuf_detach(&msg, &state->msg_len);12301231finish:1232strbuf_release(&msg);1233strbuf_release(&author_date);1234strbuf_release(&author_email);1235strbuf_release(&author_name);1236strbuf_release(&sb);1237clear_mailinfo(&mi);1238return ret;1239}12401241/**1242 * Sets commit_id to the commit hash where the mail was generated from.1243 * Returns 0 on success, -1 on failure.1244 */1245static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1246{1247struct strbuf sb = STRBUF_INIT;1248FILE*fp =xfopen(mail,"r");1249const char*x;1250int ret =0;12511252if(strbuf_getline_lf(&sb, fp) ||1253!skip_prefix(sb.buf,"From ", &x) ||1254get_oid_hex(x, commit_id) <0)1255 ret = -1;12561257strbuf_release(&sb);1258fclose(fp);1259return ret;1260}12611262/**1263 * Sets state->msg, state->author_name, state->author_email, state->author_date1264 * to the commit's respective info.1265 */1266static voidget_commit_info(struct am_state *state,struct commit *commit)1267{1268const char*buffer, *ident_line, *msg;1269size_t ident_len;1270struct ident_split id;12711272 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());12731274 ident_line =find_commit_header(buffer,"author", &ident_len);12751276if(split_ident_line(&id, ident_line, ident_len) <0)1277die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12781279assert(!state->author_name);1280if(id.name_begin)1281 state->author_name =1282xmemdupz(id.name_begin, id.name_end - id.name_begin);1283else1284 state->author_name =xstrdup("");12851286assert(!state->author_email);1287if(id.mail_begin)1288 state->author_email =1289xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1290else1291 state->author_email =xstrdup("");12921293assert(!state->author_date);1294 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));12951296assert(!state->msg);1297 msg =strstr(buffer,"\n\n");1298if(!msg)1299die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1300 state->msg =xstrdup(msg +2);1301 state->msg_len =strlen(state->msg);1302unuse_commit_buffer(commit, buffer);1303}13041305/**1306 * Writes `commit` as a patch to the state directory's "patch" file.1307 */1308static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1309{1310struct rev_info rev_info;1311FILE*fp;13121313 fp =xfopen(am_path(state,"patch"),"w");1314repo_init_revisions(the_repository, &rev_info, NULL);1315 rev_info.diff =1;1316 rev_info.abbrev =0;1317 rev_info.disable_stdin =1;1318 rev_info.show_root_diff =1;1319 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1320 rev_info.no_commit_id =1;1321 rev_info.diffopt.flags.binary =1;1322 rev_info.diffopt.flags.full_index =1;1323 rev_info.diffopt.use_color =0;1324 rev_info.diffopt.file = fp;1325 rev_info.diffopt.close_file =1;1326add_pending_object(&rev_info, &commit->object,"");1327diff_setup_done(&rev_info.diffopt);1328log_tree_commit(&rev_info, commit);1329}13301331/**1332 * Writes the diff of the index against HEAD as a patch to the state1333 * directory's "patch" file.1334 */1335static voidwrite_index_patch(const struct am_state *state)1336{1337struct tree *tree;1338struct object_id head;1339struct rev_info rev_info;1340FILE*fp;13411342if(!get_oid("HEAD", &head)) {1343struct commit *commit =lookup_commit_or_die(&head,"HEAD");1344 tree =get_commit_tree(commit);1345}else1346 tree =lookup_tree(the_repository,1347 the_repository->hash_algo->empty_tree);13481349 fp =xfopen(am_path(state,"patch"),"w");1350repo_init_revisions(the_repository, &rev_info, NULL);1351 rev_info.diff =1;1352 rev_info.disable_stdin =1;1353 rev_info.no_commit_id =1;1354 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1355 rev_info.diffopt.use_color =0;1356 rev_info.diffopt.file = fp;1357 rev_info.diffopt.close_file =1;1358add_pending_object(&rev_info, &tree->object,"");1359diff_setup_done(&rev_info.diffopt);1360run_diff_index(&rev_info,1);1361}13621363/**1364 * Like parse_mail(), but parses the mail by looking up its commit ID1365 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1366 * of patches.1367 *1368 * state->orig_commit will be set to the original commit ID.1369 *1370 * Will always return 0 as the patch should never be skipped.1371 */1372static intparse_mail_rebase(struct am_state *state,const char*mail)1373{1374struct commit *commit;1375struct object_id commit_oid;13761377if(get_mail_commit_oid(&commit_oid, mail) <0)1378die(_("could not parse%s"), mail);13791380 commit =lookup_commit_or_die(&commit_oid, mail);13811382get_commit_info(state, commit);13831384write_commit_patch(state, commit);13851386oidcpy(&state->orig_commit, &commit_oid);1387write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1388update_ref("am","REBASE_HEAD", &commit_oid,1389 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);13901391return0;1392}13931394/**1395 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1396 * `index_file` is not NULL, the patch will be applied to that index.1397 */1398static intrun_apply(const struct am_state *state,const char*index_file)1399{1400struct argv_array apply_paths = ARGV_ARRAY_INIT;1401struct argv_array apply_opts = ARGV_ARRAY_INIT;1402struct apply_state apply_state;1403int res, opts_left;1404int force_apply =0;1405int options =0;14061407if(init_apply_state(&apply_state, the_repository, NULL))1408BUG("init_apply_state() failed");14091410argv_array_push(&apply_opts,"apply");1411argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14121413 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1414&apply_state, &force_apply, &options,1415 NULL);14161417if(opts_left !=0)1418die("unknown option passed through to git apply");14191420if(index_file) {1421 apply_state.index_file = index_file;1422 apply_state.cached =1;1423}else1424 apply_state.check_index =1;14251426/*1427 * If we are allowed to fall back on 3-way merge, don't give false1428 * errors during the initial attempt.1429 */1430if(state->threeway && !index_file)1431 apply_state.apply_verbosity = verbosity_silent;14321433if(check_apply_state(&apply_state, force_apply))1434BUG("check_apply_state() failed");14351436argv_array_push(&apply_paths,am_path(state,"patch"));14371438 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14391440argv_array_clear(&apply_paths);1441argv_array_clear(&apply_opts);1442clear_apply_state(&apply_state);14431444if(res)1445return res;14461447if(index_file) {1448/* Reload index as apply_all_patches() will have modified it. */1449discard_cache();1450read_cache_from(index_file);1451}14521453return0;1454}14551456/**1457 * Builds an index that contains just the blobs needed for a 3way merge.1458 */1459static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1460{1461struct child_process cp = CHILD_PROCESS_INIT;14621463 cp.git_cmd =1;1464argv_array_push(&cp.args,"apply");1465argv_array_pushv(&cp.args, state->git_apply_opts.argv);1466argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1467argv_array_push(&cp.args,am_path(state,"patch"));14681469if(run_command(&cp))1470return-1;14711472return0;1473}14741475/**1476 * Attempt a threeway merge, using index_path as the temporary index.1477 */1478static intfall_back_threeway(const struct am_state *state,const char*index_path)1479{1480struct object_id orig_tree, their_tree, our_tree;1481const struct object_id *bases[1] = { &orig_tree };1482struct merge_options o;1483struct commit *result;1484char*their_tree_name;14851486if(get_oid("HEAD", &our_tree) <0)1487oidcpy(&our_tree, the_hash_algo->empty_tree);14881489if(build_fake_ancestor(state, index_path))1490returnerror("could not build fake ancestor");14911492discard_cache();1493read_cache_from(index_path);14941495if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1496returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));14971498say(state, stdout,_("Using index info to reconstruct a base tree..."));14991500if(!state->quiet) {1501/*1502 * List paths that needed 3-way fallback, so that the user can1503 * review them with extra care to spot mismerges.1504 */1505struct rev_info rev_info;15061507repo_init_revisions(the_repository, &rev_info, NULL);1508 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1509 rev_info.diffopt.filter |=diff_filter_bit('A');1510 rev_info.diffopt.filter |=diff_filter_bit('M');1511add_pending_oid(&rev_info,"HEAD", &our_tree,0);1512diff_setup_done(&rev_info.diffopt);1513run_diff_index(&rev_info,1);1514}15151516if(run_apply(state, index_path))1517returnerror(_("Did you hand edit your patch?\n"1518"It does not apply to blobs recorded in its index."));15191520if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1521returnerror("could not write tree");15221523say(state, stdout,_("Falling back to patching base and 3-way merge..."));15241525discard_cache();1526read_cache();15271528/*1529 * This is not so wrong. Depending on which base we picked, orig_tree1530 * may be wildly different from ours, but their_tree has the same set of1531 * wildly different changes in parts the patch did not touch, so1532 * recursive ends up canceling them, saying that we reverted all those1533 * changes.1534 */15351536init_merge_options(&o, the_repository);15371538 o.branch1 ="HEAD";1539 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1540 o.branch2 = their_tree_name;1541 o.detect_directory_renames =0;15421543if(state->quiet)1544 o.verbosity =0;15451546if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1547repo_rerere(the_repository, state->allow_rerere_autoupdate);1548free(their_tree_name);1549returnerror(_("Failed to merge in the changes."));1550}15511552free(their_tree_name);1553return0;1554}15551556/**1557 * Commits the current index with state->msg as the commit message and1558 * state->author_name, state->author_email and state->author_date as the author1559 * information.1560 */1561static voiddo_commit(const struct am_state *state)1562{1563struct object_id tree, parent, commit;1564const struct object_id *old_oid;1565struct commit_list *parents = NULL;1566const char*reflog_msg, *author;1567struct strbuf sb = STRBUF_INIT;15681569if(run_hook_le(NULL,"pre-applypatch", NULL))1570exit(1);15711572if(write_cache_as_tree(&tree,0, NULL))1573die(_("git write-tree failed to write a tree"));15741575if(!get_oid_commit("HEAD", &parent)) {1576 old_oid = &parent;1577commit_list_insert(lookup_commit(the_repository, &parent),1578&parents);1579}else{1580 old_oid = NULL;1581say(state, stderr,_("applying to an empty history"));1582}15831584 author =fmt_ident(state->author_name, state->author_email,1585 WANT_AUTHOR_IDENT,1586 state->ignore_date ? NULL : state->author_date,1587 IDENT_STRICT);15881589if(state->committer_date_is_author_date)1590setenv("GIT_COMMITTER_DATE",1591 state->ignore_date ?"": state->author_date,1);15921593if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1594 author, state->sign_commit))1595die(_("failed to write commit object"));15961597 reflog_msg =getenv("GIT_REFLOG_ACTION");1598if(!reflog_msg)1599 reflog_msg ="am";16001601strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1602 state->msg);16031604update_ref(sb.buf,"HEAD", &commit, old_oid,0,1605 UPDATE_REFS_DIE_ON_ERR);16061607if(state->rebasing) {1608FILE*fp =xfopen(am_path(state,"rewritten"),"a");16091610assert(!is_null_oid(&state->orig_commit));1611fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1612fprintf(fp,"%s\n",oid_to_hex(&commit));1613fclose(fp);1614}16151616run_hook_le(NULL,"post-applypatch", NULL);16171618strbuf_release(&sb);1619}16201621/**1622 * Validates the am_state for resuming -- the "msg" and authorship fields must1623 * be filled up.1624 */1625static voidvalidate_resume_state(const struct am_state *state)1626{1627if(!state->msg)1628die(_("cannot resume:%sdoes not exist."),1629am_path(state,"final-commit"));16301631if(!state->author_name || !state->author_email || !state->author_date)1632die(_("cannot resume:%sdoes not exist."),1633am_path(state,"author-script"));1634}16351636/**1637 * Interactively prompt the user on whether the current patch should be1638 * applied.1639 *1640 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1641 * skip it.1642 */1643static intdo_interactive(struct am_state *state)1644{1645assert(state->msg);16461647for(;;) {1648char reply[64];16491650puts(_("Commit Body is:"));1651puts("--------------------------");1652printf("%s", state->msg);1653puts("--------------------------");16541655/*1656 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1657 * in your translation. The program will only accept English1658 * input at this point.1659 */1660printf(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "));1661if(!fgets(reply,sizeof(reply), stdin))1662die("unable to read from stdin; aborting");16631664if(*reply =='y'|| *reply =='Y') {1665return0;1666}else if(*reply =='a'|| *reply =='A') {1667 state->interactive =0;1668return0;1669}else if(*reply =='n'|| *reply =='N') {1670return1;1671}else if(*reply =='e'|| *reply =='E') {1672struct strbuf msg = STRBUF_INIT;16731674if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1675free(state->msg);1676 state->msg =strbuf_detach(&msg, &state->msg_len);1677}1678strbuf_release(&msg);1679}else if(*reply =='v'|| *reply =='V') {1680const char*pager =git_pager(1);1681struct child_process cp = CHILD_PROCESS_INIT;16821683if(!pager)1684 pager ="cat";1685prepare_pager_args(&cp, pager);1686argv_array_push(&cp.args,am_path(state,"patch"));1687run_command(&cp);1688}1689}1690}16911692/**1693 * Applies all queued mail.1694 *1695 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1696 * well as the state directory's "patch" file is used as-is for applying the1697 * patch and committing it.1698 */1699static voidam_run(struct am_state *state,int resume)1700{1701const char*argv_gc_auto[] = {"gc","--auto", NULL};1702struct strbuf sb = STRBUF_INIT;17031704unlink(am_path(state,"dirtyindex"));17051706refresh_and_write_cache();17071708if(repo_index_has_changes(the_repository, NULL, &sb)) {1709write_state_bool(state,"dirtyindex",1);1710die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1711}17121713strbuf_release(&sb);17141715while(state->cur <= state->last) {1716const char*mail =am_path(state,msgnum(state));1717int apply_status;17181719reset_ident_date();17201721if(!file_exists(mail))1722goto next;17231724if(resume) {1725validate_resume_state(state);1726}else{1727int skip;17281729if(state->rebasing)1730 skip =parse_mail_rebase(state, mail);1731else1732 skip =parse_mail(state, mail);17331734if(skip)1735goto next;/* mail should be skipped */17361737if(state->signoff)1738am_append_signoff(state);17391740write_author_script(state);1741write_commit_msg(state);1742}17431744if(state->interactive &&do_interactive(state))1745goto next;17461747if(run_applypatch_msg_hook(state))1748exit(1);17491750say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17511752 apply_status =run_apply(state, NULL);17531754if(apply_status && state->threeway) {1755struct strbuf sb = STRBUF_INIT;17561757strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1758 apply_status =fall_back_threeway(state, sb.buf);1759strbuf_release(&sb);17601761/*1762 * Applying the patch to an earlier tree and merging1763 * the result may have produced the same tree as ours.1764 */1765if(!apply_status &&1766!repo_index_has_changes(the_repository, NULL, NULL)) {1767say(state, stdout,_("No changes -- Patch already applied."));1768goto next;1769}1770}17711772if(apply_status) {1773printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1774linelen(state->msg), state->msg);17751776if(advice_amworkdir)1777advise(_("Use 'git am --show-current-patch' to see the failed patch"));17781779die_user_resolve(state);1780}17811782do_commit(state);17831784next:1785am_next(state);17861787if(resume)1788am_load(state);1789 resume =0;1790}17911792if(!is_empty_or_missing_file(am_path(state,"rewritten"))) {1793assert(state->rebasing);1794copy_notes_for_rebase(state);1795run_post_rewrite_hook(state);1796}17971798/*1799 * In rebasing mode, it's up to the caller to take care of1800 * housekeeping.1801 */1802if(!state->rebasing) {1803am_destroy(state);1804close_all_packs(the_repository->objects);1805run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1806}1807}18081809/**1810 * Resume the current am session after patch application failure. The user did1811 * all the hard work, and we do not have to do any patch application. Just1812 * trust and commit what the user has in the index and working tree.1813 */1814static voidam_resolve(struct am_state *state)1815{1816validate_resume_state(state);18171818say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18191820if(!repo_index_has_changes(the_repository, NULL, NULL)) {1821printf_ln(_("No changes - did you forget to use 'git add'?\n"1822"If there is nothing left to stage, chances are that something else\n"1823"already introduced the same changes; you might want to skip this patch."));1824die_user_resolve(state);1825}18261827if(unmerged_cache()) {1828printf_ln(_("You still have unmerged paths in your index.\n"1829"You should 'git add' each file with resolved conflicts to mark them as such.\n"1830"You might run `git rm` on a file to accept\"deleted by them\"for it."));1831die_user_resolve(state);1832}18331834if(state->interactive) {1835write_index_patch(state);1836if(do_interactive(state))1837goto next;1838}18391840repo_rerere(the_repository,0);18411842do_commit(state);18431844next:1845am_next(state);1846am_load(state);1847am_run(state,0);1848}18491850/**1851 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1852 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1853 * failure.1854 */1855static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1856{1857struct lock_file lock_file = LOCK_INIT;1858struct unpack_trees_options opts;1859struct tree_desc t[2];18601861if(parse_tree(head) ||parse_tree(remote))1862return-1;18631864hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18651866refresh_cache(REFRESH_QUIET);18671868memset(&opts,0,sizeof(opts));1869 opts.head_idx =1;1870 opts.src_index = &the_index;1871 opts.dst_index = &the_index;1872 opts.update =1;1873 opts.merge =1;1874 opts.reset = reset;1875 opts.fn = twoway_merge;1876init_tree_desc(&t[0], head->buffer, head->size);1877init_tree_desc(&t[1], remote->buffer, remote->size);18781879if(unpack_trees(2, t, &opts)) {1880rollback_lock_file(&lock_file);1881return-1;1882}18831884if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1885die(_("unable to write new index file"));18861887return0;1888}18891890/**1891 * Merges a tree into the index. The index's stat info will take precedence1892 * over the merged tree's. Returns 0 on success, -1 on failure.1893 */1894static intmerge_tree(struct tree *tree)1895{1896struct lock_file lock_file = LOCK_INIT;1897struct unpack_trees_options opts;1898struct tree_desc t[1];18991900if(parse_tree(tree))1901return-1;19021903hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19041905memset(&opts,0,sizeof(opts));1906 opts.head_idx =1;1907 opts.src_index = &the_index;1908 opts.dst_index = &the_index;1909 opts.merge =1;1910 opts.fn = oneway_merge;1911init_tree_desc(&t[0], tree->buffer, tree->size);19121913if(unpack_trees(1, t, &opts)) {1914rollback_lock_file(&lock_file);1915return-1;1916}19171918if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1919die(_("unable to write new index file"));19201921return0;1922}19231924/**1925 * Clean the index without touching entries that are not modified between1926 * `head` and `remote`.1927 */1928static intclean_index(const struct object_id *head,const struct object_id *remote)1929{1930struct tree *head_tree, *remote_tree, *index_tree;1931struct object_id index;19321933 head_tree =parse_tree_indirect(head);1934if(!head_tree)1935returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19361937 remote_tree =parse_tree_indirect(remote);1938if(!remote_tree)1939returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19401941read_cache_unmerged();19421943if(fast_forward_to(head_tree, head_tree,1))1944return-1;19451946if(write_cache_as_tree(&index,0, NULL))1947return-1;19481949 index_tree =parse_tree_indirect(&index);1950if(!index_tree)1951returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19521953if(fast_forward_to(index_tree, remote_tree,0))1954return-1;19551956if(merge_tree(remote_tree))1957return-1;19581959remove_branch_state(the_repository);19601961return0;1962}19631964/**1965 * Resets rerere's merge resolution metadata.1966 */1967static voidam_rerere_clear(void)1968{1969struct string_list merge_rr = STRING_LIST_INIT_DUP;1970rerere_clear(the_repository, &merge_rr);1971string_list_clear(&merge_rr,1);1972}19731974/**1975 * Resume the current am session by skipping the current patch.1976 */1977static voidam_skip(struct am_state *state)1978{1979struct object_id head;19801981am_rerere_clear();19821983if(get_oid("HEAD", &head))1984oidcpy(&head, the_hash_algo->empty_tree);19851986if(clean_index(&head, &head))1987die(_("failed to clean index"));19881989if(state->rebasing) {1990FILE*fp =xfopen(am_path(state,"rewritten"),"a");19911992assert(!is_null_oid(&state->orig_commit));1993fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1994fprintf(fp,"%s\n",oid_to_hex(&head));1995fclose(fp);1996}19971998am_next(state);1999am_load(state);2000am_run(state,0);2001}20022003/**2004 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2005 *2006 * It is not safe to reset HEAD when:2007 * 1. git-am previously failed because the index was dirty.2008 * 2. HEAD has moved since git-am previously failed.2009 */2010static intsafe_to_abort(const struct am_state *state)2011{2012struct strbuf sb = STRBUF_INIT;2013struct object_id abort_safety, head;20142015if(file_exists(am_path(state,"dirtyindex")))2016return0;20172018if(read_state_file(&sb, state,"abort-safety",1) >0) {2019if(get_oid_hex(sb.buf, &abort_safety))2020die(_("could not parse%s"),am_path(state,"abort-safety"));2021}else2022oidclr(&abort_safety);2023strbuf_release(&sb);20242025if(get_oid("HEAD", &head))2026oidclr(&head);20272028if(oideq(&head, &abort_safety))2029return1;20302031warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2032"Not rewinding to ORIG_HEAD"));20332034return0;2035}20362037/**2038 * Aborts the current am session if it is safe to do so.2039 */2040static voidam_abort(struct am_state *state)2041{2042struct object_id curr_head, orig_head;2043int has_curr_head, has_orig_head;2044char*curr_branch;20452046if(!safe_to_abort(state)) {2047am_destroy(state);2048return;2049}20502051am_rerere_clear();20522053 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2054 has_curr_head = curr_branch && !is_null_oid(&curr_head);2055if(!has_curr_head)2056oidcpy(&curr_head, the_hash_algo->empty_tree);20572058 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2059if(!has_orig_head)2060oidcpy(&orig_head, the_hash_algo->empty_tree);20612062clean_index(&curr_head, &orig_head);20632064if(has_orig_head)2065update_ref("am --abort","HEAD", &orig_head,2066 has_curr_head ? &curr_head : NULL,0,2067 UPDATE_REFS_DIE_ON_ERR);2068else if(curr_branch)2069delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20702071free(curr_branch);2072am_destroy(state);2073}20742075static intshow_patch(struct am_state *state)2076{2077struct strbuf sb = STRBUF_INIT;2078const char*patch_path;2079int len;20802081if(!is_null_oid(&state->orig_commit)) {2082const char*av[4] = {"show", NULL,"--", NULL };2083char*new_oid_str;2084int ret;20852086 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2087 ret =run_command_v_opt(av, RUN_GIT_CMD);2088free(new_oid_str);2089return ret;2090}20912092 patch_path =am_path(state,msgnum(state));2093 len =strbuf_read_file(&sb, patch_path,0);2094if(len <0)2095die_errno(_("failed to read '%s'"), patch_path);20962097setup_pager();2098write_in_full(1, sb.buf, sb.len);2099strbuf_release(&sb);2100return0;2101}21022103/**2104 * parse_options() callback that validates and sets opt->value to the2105 * PATCH_FORMAT_* enum value corresponding to `arg`.2106 */2107static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2108{2109int*opt_value = opt->value;21102111if(unset)2112*opt_value = PATCH_FORMAT_UNKNOWN;2113else if(!strcmp(arg,"mbox"))2114*opt_value = PATCH_FORMAT_MBOX;2115else if(!strcmp(arg,"stgit"))2116*opt_value = PATCH_FORMAT_STGIT;2117else if(!strcmp(arg,"stgit-series"))2118*opt_value = PATCH_FORMAT_STGIT_SERIES;2119else if(!strcmp(arg,"hg"))2120*opt_value = PATCH_FORMAT_HG;2121else if(!strcmp(arg,"mboxrd"))2122*opt_value = PATCH_FORMAT_MBOXRD;2123/*2124 * Please update $__git_patchformat in git-completion.bash2125 * when you add new options2126 */2127else2128returnerror(_("Invalid value for --patch-format:%s"), arg);2129return0;2130}21312132enum resume_mode {2133 RESUME_FALSE =0,2134 RESUME_APPLY,2135 RESUME_RESOLVED,2136 RESUME_SKIP,2137 RESUME_ABORT,2138 RESUME_QUIT,2139 RESUME_SHOW_PATCH2140};21412142static intgit_am_config(const char*k,const char*v,void*cb)2143{2144int status;21452146 status =git_gpg_config(k, v, NULL);2147if(status)2148return status;21492150returngit_default_config(k, v, NULL);2151}21522153intcmd_am(int argc,const char**argv,const char*prefix)2154{2155struct am_state state;2156int binary = -1;2157int keep_cr = -1;2158int patch_format = PATCH_FORMAT_UNKNOWN;2159enum resume_mode resume = RESUME_FALSE;2160int in_progress;2161int ret =0;21622163const char*const usage[] = {2164N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2165N_("git am [<options>] (--continue | --skip | --abort)"),2166 NULL2167};21682169struct option options[] = {2170OPT_BOOL('i',"interactive", &state.interactive,2171N_("run interactively")),2172OPT_HIDDEN_BOOL('b',"binary", &binary,2173N_("historical option -- no-op")),2174OPT_BOOL('3',"3way", &state.threeway,2175N_("allow fall back on 3way merging if needed")),2176OPT__QUIET(&state.quiet,N_("be quiet")),2177OPT_SET_INT('s',"signoff", &state.signoff,2178N_("add a Signed-off-by line to the commit message"),2179 SIGNOFF_EXPLICIT),2180OPT_BOOL('u',"utf8", &state.utf8,2181N_("recode into utf8 (default)")),2182OPT_SET_INT('k',"keep", &state.keep,2183N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2184OPT_SET_INT(0,"keep-non-patch", &state.keep,2185N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2186OPT_BOOL('m',"message-id", &state.message_id,2187N_("pass -m flag to git-mailinfo")),2188OPT_SET_INT_F(0,"keep-cr", &keep_cr,2189N_("pass --keep-cr flag to git-mailsplit for mbox format"),21901, PARSE_OPT_NONEG),2191OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2192N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21930, PARSE_OPT_NONEG),2194OPT_BOOL('c',"scissors", &state.scissors,2195N_("strip everything before a scissors line")),2196OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2197N_("pass it through git-apply"),21980),2199OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2200N_("pass it through git-apply"),2201 PARSE_OPT_NOARG),2202OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2203N_("pass it through git-apply"),2204 PARSE_OPT_NOARG),2205OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2206N_("pass it through git-apply"),22070),2208OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2209N_("pass it through git-apply"),22100),2211OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2212N_("pass it through git-apply"),22130),2214OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2215N_("pass it through git-apply"),22160),2217OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2218N_("pass it through git-apply"),22190),2220OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2221N_("format the patch(es) are in"),2222 parse_opt_patchformat),2223OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2224N_("pass it through git-apply"),2225 PARSE_OPT_NOARG),2226OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2227N_("override error message when patch failure occurs")),2228OPT_CMDMODE(0,"continue", &resume,2229N_("continue applying patches after resolving a conflict"),2230 RESUME_RESOLVED),2231OPT_CMDMODE('r',"resolved", &resume,2232N_("synonyms for --continue"),2233 RESUME_RESOLVED),2234OPT_CMDMODE(0,"skip", &resume,2235N_("skip the current patch"),2236 RESUME_SKIP),2237OPT_CMDMODE(0,"abort", &resume,2238N_("restore the original branch and abort the patching operation."),2239 RESUME_ABORT),2240OPT_CMDMODE(0,"quit", &resume,2241N_("abort the patching operation but keep HEAD where it is."),2242 RESUME_QUIT),2243OPT_CMDMODE(0,"show-current-patch", &resume,2244N_("show the patch being applied."),2245 RESUME_SHOW_PATCH),2246OPT_BOOL(0,"committer-date-is-author-date",2247&state.committer_date_is_author_date,2248N_("lie about committer date")),2249OPT_BOOL(0,"ignore-date", &state.ignore_date,2250N_("use current timestamp for author date")),2251OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2252{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2253N_("GPG-sign commits"),2254 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2255OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2256N_("(internal use for git-rebase)")),2257OPT_END()2258};22592260if(argc ==2&& !strcmp(argv[1],"-h"))2261usage_with_options(usage, options);22622263git_config(git_am_config, NULL);22642265am_state_init(&state);22662267 in_progress =am_in_progress(&state);2268if(in_progress)2269am_load(&state);22702271 argc =parse_options(argc, argv, prefix, options, usage,0);22722273if(binary >=0)2274fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2275"it will be removed. Please do not use it anymore."));22762277/* Ensure a valid committer ident can be constructed */2278git_committer_info(IDENT_STRICT);22792280if(repo_read_index_preload(the_repository, NULL,0) <0)2281die(_("failed to read the index"));22822283if(in_progress) {2284/*2285 * Catch user error to feed us patches when there is a session2286 * in progress:2287 *2288 * 1. mbox path(s) are provided on the command-line.2289 * 2. stdin is not a tty: the user is trying to feed us a patch2290 * from standard input. This is somewhat unreliable -- stdin2291 * could be /dev/null for example and the caller did not2292 * intend to feed us a patch but wanted to continue2293 * unattended.2294 */2295if(argc || (resume == RESUME_FALSE && !isatty(0)))2296die(_("previous rebase directory%sstill exists but mbox given."),2297 state.dir);22982299if(resume == RESUME_FALSE)2300 resume = RESUME_APPLY;23012302if(state.signoff == SIGNOFF_EXPLICIT)2303am_append_signoff(&state);2304}else{2305struct argv_array paths = ARGV_ARRAY_INIT;2306int i;23072308/*2309 * Handle stray state directory in the independent-run case. In2310 * the --rebasing case, it is up to the caller to take care of2311 * stray directories.2312 */2313if(file_exists(state.dir) && !state.rebasing) {2314if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2315am_destroy(&state);2316am_state_release(&state);2317return0;2318}23192320die(_("Stray%sdirectory found.\n"2321"Use\"git am --abort\"to remove it."),2322 state.dir);2323}23242325if(resume)2326die(_("Resolve operation not in progress, we are not resuming."));23272328for(i =0; i < argc; i++) {2329if(is_absolute_path(argv[i]) || !prefix)2330argv_array_push(&paths, argv[i]);2331else2332argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2333}23342335if(state.interactive && !paths.argc)2336die(_("interactive mode requires patches on the command line"));23372338am_setup(&state, patch_format, paths.argv, keep_cr);23392340argv_array_clear(&paths);2341}23422343switch(resume) {2344case RESUME_FALSE:2345am_run(&state,0);2346break;2347case RESUME_APPLY:2348am_run(&state,1);2349break;2350case RESUME_RESOLVED:2351am_resolve(&state);2352break;2353case RESUME_SKIP:2354am_skip(&state);2355break;2356case RESUME_ABORT:2357am_abort(&state);2358break;2359case RESUME_QUIT:2360am_rerere_clear();2361am_destroy(&state);2362break;2363case RESUME_SHOW_PATCH:2364 ret =show_patch(&state);2365break;2366default:2367BUG("invalid resume value");2368}23692370am_state_release(&state);23712372return ret;2373}