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);1275if(!ident_line)1276die(_("missing author line in commit%s"),1277oid_to_hex(&commit->object.oid));1278if(split_ident_line(&id, ident_line, ident_len) <0)1279die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12801281assert(!state->author_name);1282if(id.name_begin)1283 state->author_name =1284xmemdupz(id.name_begin, id.name_end - id.name_begin);1285else1286 state->author_name =xstrdup("");12871288assert(!state->author_email);1289if(id.mail_begin)1290 state->author_email =1291xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1292else1293 state->author_email =xstrdup("");12941295assert(!state->author_date);1296 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));12971298assert(!state->msg);1299 msg =strstr(buffer,"\n\n");1300if(!msg)1301die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1302 state->msg =xstrdup(msg +2);1303 state->msg_len =strlen(state->msg);1304unuse_commit_buffer(commit, buffer);1305}13061307/**1308 * Writes `commit` as a patch to the state directory's "patch" file.1309 */1310static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1311{1312struct rev_info rev_info;1313FILE*fp;13141315 fp =xfopen(am_path(state,"patch"),"w");1316repo_init_revisions(the_repository, &rev_info, NULL);1317 rev_info.diff =1;1318 rev_info.abbrev =0;1319 rev_info.disable_stdin =1;1320 rev_info.show_root_diff =1;1321 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1322 rev_info.no_commit_id =1;1323 rev_info.diffopt.flags.binary =1;1324 rev_info.diffopt.flags.full_index =1;1325 rev_info.diffopt.use_color =0;1326 rev_info.diffopt.file = fp;1327 rev_info.diffopt.close_file =1;1328add_pending_object(&rev_info, &commit->object,"");1329diff_setup_done(&rev_info.diffopt);1330log_tree_commit(&rev_info, commit);1331}13321333/**1334 * Writes the diff of the index against HEAD as a patch to the state1335 * directory's "patch" file.1336 */1337static voidwrite_index_patch(const struct am_state *state)1338{1339struct tree *tree;1340struct object_id head;1341struct rev_info rev_info;1342FILE*fp;13431344if(!get_oid("HEAD", &head)) {1345struct commit *commit =lookup_commit_or_die(&head,"HEAD");1346 tree =get_commit_tree(commit);1347}else1348 tree =lookup_tree(the_repository,1349 the_repository->hash_algo->empty_tree);13501351 fp =xfopen(am_path(state,"patch"),"w");1352repo_init_revisions(the_repository, &rev_info, NULL);1353 rev_info.diff =1;1354 rev_info.disable_stdin =1;1355 rev_info.no_commit_id =1;1356 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1357 rev_info.diffopt.use_color =0;1358 rev_info.diffopt.file = fp;1359 rev_info.diffopt.close_file =1;1360add_pending_object(&rev_info, &tree->object,"");1361diff_setup_done(&rev_info.diffopt);1362run_diff_index(&rev_info,1);1363}13641365/**1366 * Like parse_mail(), but parses the mail by looking up its commit ID1367 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1368 * of patches.1369 *1370 * state->orig_commit will be set to the original commit ID.1371 *1372 * Will always return 0 as the patch should never be skipped.1373 */1374static intparse_mail_rebase(struct am_state *state,const char*mail)1375{1376struct commit *commit;1377struct object_id commit_oid;13781379if(get_mail_commit_oid(&commit_oid, mail) <0)1380die(_("could not parse%s"), mail);13811382 commit =lookup_commit_or_die(&commit_oid, mail);13831384get_commit_info(state, commit);13851386write_commit_patch(state, commit);13871388oidcpy(&state->orig_commit, &commit_oid);1389write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1390update_ref("am","REBASE_HEAD", &commit_oid,1391 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);13921393return0;1394}13951396/**1397 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1398 * `index_file` is not NULL, the patch will be applied to that index.1399 */1400static intrun_apply(const struct am_state *state,const char*index_file)1401{1402struct argv_array apply_paths = ARGV_ARRAY_INIT;1403struct argv_array apply_opts = ARGV_ARRAY_INIT;1404struct apply_state apply_state;1405int res, opts_left;1406int force_apply =0;1407int options =0;14081409if(init_apply_state(&apply_state, the_repository, NULL))1410BUG("init_apply_state() failed");14111412argv_array_push(&apply_opts,"apply");1413argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14141415 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1416&apply_state, &force_apply, &options,1417 NULL);14181419if(opts_left !=0)1420die("unknown option passed through to git apply");14211422if(index_file) {1423 apply_state.index_file = index_file;1424 apply_state.cached =1;1425}else1426 apply_state.check_index =1;14271428/*1429 * If we are allowed to fall back on 3-way merge, don't give false1430 * errors during the initial attempt.1431 */1432if(state->threeway && !index_file)1433 apply_state.apply_verbosity = verbosity_silent;14341435if(check_apply_state(&apply_state, force_apply))1436BUG("check_apply_state() failed");14371438argv_array_push(&apply_paths,am_path(state,"patch"));14391440 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14411442argv_array_clear(&apply_paths);1443argv_array_clear(&apply_opts);1444clear_apply_state(&apply_state);14451446if(res)1447return res;14481449if(index_file) {1450/* Reload index as apply_all_patches() will have modified it. */1451discard_cache();1452read_cache_from(index_file);1453}14541455return0;1456}14571458/**1459 * Builds an index that contains just the blobs needed for a 3way merge.1460 */1461static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1462{1463struct child_process cp = CHILD_PROCESS_INIT;14641465 cp.git_cmd =1;1466argv_array_push(&cp.args,"apply");1467argv_array_pushv(&cp.args, state->git_apply_opts.argv);1468argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1469argv_array_push(&cp.args,am_path(state,"patch"));14701471if(run_command(&cp))1472return-1;14731474return0;1475}14761477/**1478 * Attempt a threeway merge, using index_path as the temporary index.1479 */1480static intfall_back_threeway(const struct am_state *state,const char*index_path)1481{1482struct object_id orig_tree, their_tree, our_tree;1483const struct object_id *bases[1] = { &orig_tree };1484struct merge_options o;1485struct commit *result;1486char*their_tree_name;14871488if(get_oid("HEAD", &our_tree) <0)1489oidcpy(&our_tree, the_hash_algo->empty_tree);14901491if(build_fake_ancestor(state, index_path))1492returnerror("could not build fake ancestor");14931494discard_cache();1495read_cache_from(index_path);14961497if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1498returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));14991500say(state, stdout,_("Using index info to reconstruct a base tree..."));15011502if(!state->quiet) {1503/*1504 * List paths that needed 3-way fallback, so that the user can1505 * review them with extra care to spot mismerges.1506 */1507struct rev_info rev_info;15081509repo_init_revisions(the_repository, &rev_info, NULL);1510 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1511 rev_info.diffopt.filter |=diff_filter_bit('A');1512 rev_info.diffopt.filter |=diff_filter_bit('M');1513add_pending_oid(&rev_info,"HEAD", &our_tree,0);1514diff_setup_done(&rev_info.diffopt);1515run_diff_index(&rev_info,1);1516}15171518if(run_apply(state, index_path))1519returnerror(_("Did you hand edit your patch?\n"1520"It does not apply to blobs recorded in its index."));15211522if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1523returnerror("could not write tree");15241525say(state, stdout,_("Falling back to patching base and 3-way merge..."));15261527discard_cache();1528read_cache();15291530/*1531 * This is not so wrong. Depending on which base we picked, orig_tree1532 * may be wildly different from ours, but their_tree has the same set of1533 * wildly different changes in parts the patch did not touch, so1534 * recursive ends up canceling them, saying that we reverted all those1535 * changes.1536 */15371538init_merge_options(&o, the_repository);15391540 o.branch1 ="HEAD";1541 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1542 o.branch2 = their_tree_name;1543 o.detect_directory_renames =0;15441545if(state->quiet)1546 o.verbosity =0;15471548if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1549repo_rerere(the_repository, state->allow_rerere_autoupdate);1550free(their_tree_name);1551returnerror(_("Failed to merge in the changes."));1552}15531554free(their_tree_name);1555return0;1556}15571558/**1559 * Commits the current index with state->msg as the commit message and1560 * state->author_name, state->author_email and state->author_date as the author1561 * information.1562 */1563static voiddo_commit(const struct am_state *state)1564{1565struct object_id tree, parent, commit;1566const struct object_id *old_oid;1567struct commit_list *parents = NULL;1568const char*reflog_msg, *author;1569struct strbuf sb = STRBUF_INIT;15701571if(run_hook_le(NULL,"pre-applypatch", NULL))1572exit(1);15731574if(write_cache_as_tree(&tree,0, NULL))1575die(_("git write-tree failed to write a tree"));15761577if(!get_oid_commit("HEAD", &parent)) {1578 old_oid = &parent;1579commit_list_insert(lookup_commit(the_repository, &parent),1580&parents);1581}else{1582 old_oid = NULL;1583say(state, stderr,_("applying to an empty history"));1584}15851586 author =fmt_ident(state->author_name, state->author_email,1587 WANT_AUTHOR_IDENT,1588 state->ignore_date ? NULL : state->author_date,1589 IDENT_STRICT);15901591if(state->committer_date_is_author_date)1592setenv("GIT_COMMITTER_DATE",1593 state->ignore_date ?"": state->author_date,1);15941595if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1596 author, state->sign_commit))1597die(_("failed to write commit object"));15981599 reflog_msg =getenv("GIT_REFLOG_ACTION");1600if(!reflog_msg)1601 reflog_msg ="am";16021603strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1604 state->msg);16051606update_ref(sb.buf,"HEAD", &commit, old_oid,0,1607 UPDATE_REFS_DIE_ON_ERR);16081609if(state->rebasing) {1610FILE*fp =xfopen(am_path(state,"rewritten"),"a");16111612assert(!is_null_oid(&state->orig_commit));1613fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1614fprintf(fp,"%s\n",oid_to_hex(&commit));1615fclose(fp);1616}16171618run_hook_le(NULL,"post-applypatch", NULL);16191620strbuf_release(&sb);1621}16221623/**1624 * Validates the am_state for resuming -- the "msg" and authorship fields must1625 * be filled up.1626 */1627static voidvalidate_resume_state(const struct am_state *state)1628{1629if(!state->msg)1630die(_("cannot resume:%sdoes not exist."),1631am_path(state,"final-commit"));16321633if(!state->author_name || !state->author_email || !state->author_date)1634die(_("cannot resume:%sdoes not exist."),1635am_path(state,"author-script"));1636}16371638/**1639 * Interactively prompt the user on whether the current patch should be1640 * applied.1641 *1642 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1643 * skip it.1644 */1645static intdo_interactive(struct am_state *state)1646{1647assert(state->msg);16481649for(;;) {1650char reply[64];16511652puts(_("Commit Body is:"));1653puts("--------------------------");1654printf("%s", state->msg);1655puts("--------------------------");16561657/*1658 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1659 * in your translation. The program will only accept English1660 * input at this point.1661 */1662printf(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "));1663if(!fgets(reply,sizeof(reply), stdin))1664die("unable to read from stdin; aborting");16651666if(*reply =='y'|| *reply =='Y') {1667return0;1668}else if(*reply =='a'|| *reply =='A') {1669 state->interactive =0;1670return0;1671}else if(*reply =='n'|| *reply =='N') {1672return1;1673}else if(*reply =='e'|| *reply =='E') {1674struct strbuf msg = STRBUF_INIT;16751676if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1677free(state->msg);1678 state->msg =strbuf_detach(&msg, &state->msg_len);1679}1680strbuf_release(&msg);1681}else if(*reply =='v'|| *reply =='V') {1682const char*pager =git_pager(1);1683struct child_process cp = CHILD_PROCESS_INIT;16841685if(!pager)1686 pager ="cat";1687prepare_pager_args(&cp, pager);1688argv_array_push(&cp.args,am_path(state,"patch"));1689run_command(&cp);1690}1691}1692}16931694/**1695 * Applies all queued mail.1696 *1697 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1698 * well as the state directory's "patch" file is used as-is for applying the1699 * patch and committing it.1700 */1701static voidam_run(struct am_state *state,int resume)1702{1703const char*argv_gc_auto[] = {"gc","--auto", NULL};1704struct strbuf sb = STRBUF_INIT;17051706unlink(am_path(state,"dirtyindex"));17071708refresh_and_write_cache();17091710if(repo_index_has_changes(the_repository, NULL, &sb)) {1711write_state_bool(state,"dirtyindex",1);1712die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1713}17141715strbuf_release(&sb);17161717while(state->cur <= state->last) {1718const char*mail =am_path(state,msgnum(state));1719int apply_status;17201721reset_ident_date();17221723if(!file_exists(mail))1724goto next;17251726if(resume) {1727validate_resume_state(state);1728}else{1729int skip;17301731if(state->rebasing)1732 skip =parse_mail_rebase(state, mail);1733else1734 skip =parse_mail(state, mail);17351736if(skip)1737goto next;/* mail should be skipped */17381739if(state->signoff)1740am_append_signoff(state);17411742write_author_script(state);1743write_commit_msg(state);1744}17451746if(state->interactive &&do_interactive(state))1747goto next;17481749if(run_applypatch_msg_hook(state))1750exit(1);17511752say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17531754 apply_status =run_apply(state, NULL);17551756if(apply_status && state->threeway) {1757struct strbuf sb = STRBUF_INIT;17581759strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1760 apply_status =fall_back_threeway(state, sb.buf);1761strbuf_release(&sb);17621763/*1764 * Applying the patch to an earlier tree and merging1765 * the result may have produced the same tree as ours.1766 */1767if(!apply_status &&1768!repo_index_has_changes(the_repository, NULL, NULL)) {1769say(state, stdout,_("No changes -- Patch already applied."));1770goto next;1771}1772}17731774if(apply_status) {1775printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1776linelen(state->msg), state->msg);17771778if(advice_amworkdir)1779advise(_("Use 'git am --show-current-patch' to see the failed patch"));17801781die_user_resolve(state);1782}17831784do_commit(state);17851786next:1787am_next(state);17881789if(resume)1790am_load(state);1791 resume =0;1792}17931794if(!is_empty_or_missing_file(am_path(state,"rewritten"))) {1795assert(state->rebasing);1796copy_notes_for_rebase(state);1797run_post_rewrite_hook(state);1798}17991800/*1801 * In rebasing mode, it's up to the caller to take care of1802 * housekeeping.1803 */1804if(!state->rebasing) {1805am_destroy(state);1806close_object_store(the_repository->objects);1807run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1808}1809}18101811/**1812 * Resume the current am session after patch application failure. The user did1813 * all the hard work, and we do not have to do any patch application. Just1814 * trust and commit what the user has in the index and working tree.1815 */1816static voidam_resolve(struct am_state *state)1817{1818validate_resume_state(state);18191820say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18211822if(!repo_index_has_changes(the_repository, NULL, NULL)) {1823printf_ln(_("No changes - did you forget to use 'git add'?\n"1824"If there is nothing left to stage, chances are that something else\n"1825"already introduced the same changes; you might want to skip this patch."));1826die_user_resolve(state);1827}18281829if(unmerged_cache()) {1830printf_ln(_("You still have unmerged paths in your index.\n"1831"You should 'git add' each file with resolved conflicts to mark them as such.\n"1832"You might run `git rm` on a file to accept\"deleted by them\"for it."));1833die_user_resolve(state);1834}18351836if(state->interactive) {1837write_index_patch(state);1838if(do_interactive(state))1839goto next;1840}18411842repo_rerere(the_repository,0);18431844do_commit(state);18451846next:1847am_next(state);1848am_load(state);1849am_run(state,0);1850}18511852/**1853 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1854 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1855 * failure.1856 */1857static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1858{1859struct lock_file lock_file = LOCK_INIT;1860struct unpack_trees_options opts;1861struct tree_desc t[2];18621863if(parse_tree(head) ||parse_tree(remote))1864return-1;18651866hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18671868refresh_cache(REFRESH_QUIET);18691870memset(&opts,0,sizeof(opts));1871 opts.head_idx =1;1872 opts.src_index = &the_index;1873 opts.dst_index = &the_index;1874 opts.update =1;1875 opts.merge =1;1876 opts.reset = reset;1877 opts.fn = twoway_merge;1878init_tree_desc(&t[0], head->buffer, head->size);1879init_tree_desc(&t[1], remote->buffer, remote->size);18801881if(unpack_trees(2, t, &opts)) {1882rollback_lock_file(&lock_file);1883return-1;1884}18851886if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1887die(_("unable to write new index file"));18881889return0;1890}18911892/**1893 * Merges a tree into the index. The index's stat info will take precedence1894 * over the merged tree's. Returns 0 on success, -1 on failure.1895 */1896static intmerge_tree(struct tree *tree)1897{1898struct lock_file lock_file = LOCK_INIT;1899struct unpack_trees_options opts;1900struct tree_desc t[1];19011902if(parse_tree(tree))1903return-1;19041905hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19061907memset(&opts,0,sizeof(opts));1908 opts.head_idx =1;1909 opts.src_index = &the_index;1910 opts.dst_index = &the_index;1911 opts.merge =1;1912 opts.fn = oneway_merge;1913init_tree_desc(&t[0], tree->buffer, tree->size);19141915if(unpack_trees(1, t, &opts)) {1916rollback_lock_file(&lock_file);1917return-1;1918}19191920if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1921die(_("unable to write new index file"));19221923return0;1924}19251926/**1927 * Clean the index without touching entries that are not modified between1928 * `head` and `remote`.1929 */1930static intclean_index(const struct object_id *head,const struct object_id *remote)1931{1932struct tree *head_tree, *remote_tree, *index_tree;1933struct object_id index;19341935 head_tree =parse_tree_indirect(head);1936if(!head_tree)1937returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19381939 remote_tree =parse_tree_indirect(remote);1940if(!remote_tree)1941returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19421943read_cache_unmerged();19441945if(fast_forward_to(head_tree, head_tree,1))1946return-1;19471948if(write_cache_as_tree(&index,0, NULL))1949return-1;19501951 index_tree =parse_tree_indirect(&index);1952if(!index_tree)1953returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19541955if(fast_forward_to(index_tree, remote_tree,0))1956return-1;19571958if(merge_tree(remote_tree))1959return-1;19601961remove_branch_state(the_repository,0);19621963return0;1964}19651966/**1967 * Resets rerere's merge resolution metadata.1968 */1969static voidam_rerere_clear(void)1970{1971struct string_list merge_rr = STRING_LIST_INIT_DUP;1972rerere_clear(the_repository, &merge_rr);1973string_list_clear(&merge_rr,1);1974}19751976/**1977 * Resume the current am session by skipping the current patch.1978 */1979static voidam_skip(struct am_state *state)1980{1981struct object_id head;19821983am_rerere_clear();19841985if(get_oid("HEAD", &head))1986oidcpy(&head, the_hash_algo->empty_tree);19871988if(clean_index(&head, &head))1989die(_("failed to clean index"));19901991if(state->rebasing) {1992FILE*fp =xfopen(am_path(state,"rewritten"),"a");19931994assert(!is_null_oid(&state->orig_commit));1995fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1996fprintf(fp,"%s\n",oid_to_hex(&head));1997fclose(fp);1998}19992000am_next(state);2001am_load(state);2002am_run(state,0);2003}20042005/**2006 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2007 *2008 * It is not safe to reset HEAD when:2009 * 1. git-am previously failed because the index was dirty.2010 * 2. HEAD has moved since git-am previously failed.2011 */2012static intsafe_to_abort(const struct am_state *state)2013{2014struct strbuf sb = STRBUF_INIT;2015struct object_id abort_safety, head;20162017if(file_exists(am_path(state,"dirtyindex")))2018return0;20192020if(read_state_file(&sb, state,"abort-safety",1) >0) {2021if(get_oid_hex(sb.buf, &abort_safety))2022die(_("could not parse%s"),am_path(state,"abort-safety"));2023}else2024oidclr(&abort_safety);2025strbuf_release(&sb);20262027if(get_oid("HEAD", &head))2028oidclr(&head);20292030if(oideq(&head, &abort_safety))2031return1;20322033warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2034"Not rewinding to ORIG_HEAD"));20352036return0;2037}20382039/**2040 * Aborts the current am session if it is safe to do so.2041 */2042static voidam_abort(struct am_state *state)2043{2044struct object_id curr_head, orig_head;2045int has_curr_head, has_orig_head;2046char*curr_branch;20472048if(!safe_to_abort(state)) {2049am_destroy(state);2050return;2051}20522053am_rerere_clear();20542055 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2056 has_curr_head = curr_branch && !is_null_oid(&curr_head);2057if(!has_curr_head)2058oidcpy(&curr_head, the_hash_algo->empty_tree);20592060 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2061if(!has_orig_head)2062oidcpy(&orig_head, the_hash_algo->empty_tree);20632064clean_index(&curr_head, &orig_head);20652066if(has_orig_head)2067update_ref("am --abort","HEAD", &orig_head,2068 has_curr_head ? &curr_head : NULL,0,2069 UPDATE_REFS_DIE_ON_ERR);2070else if(curr_branch)2071delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20722073free(curr_branch);2074am_destroy(state);2075}20762077static intshow_patch(struct am_state *state)2078{2079struct strbuf sb = STRBUF_INIT;2080const char*patch_path;2081int len;20822083if(!is_null_oid(&state->orig_commit)) {2084const char*av[4] = {"show", NULL,"--", NULL };2085char*new_oid_str;2086int ret;20872088 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2089 ret =run_command_v_opt(av, RUN_GIT_CMD);2090free(new_oid_str);2091return ret;2092}20932094 patch_path =am_path(state,msgnum(state));2095 len =strbuf_read_file(&sb, patch_path,0);2096if(len <0)2097die_errno(_("failed to read '%s'"), patch_path);20982099setup_pager();2100write_in_full(1, sb.buf, sb.len);2101strbuf_release(&sb);2102return0;2103}21042105/**2106 * parse_options() callback that validates and sets opt->value to the2107 * PATCH_FORMAT_* enum value corresponding to `arg`.2108 */2109static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2110{2111int*opt_value = opt->value;21122113if(unset)2114*opt_value = PATCH_FORMAT_UNKNOWN;2115else if(!strcmp(arg,"mbox"))2116*opt_value = PATCH_FORMAT_MBOX;2117else if(!strcmp(arg,"stgit"))2118*opt_value = PATCH_FORMAT_STGIT;2119else if(!strcmp(arg,"stgit-series"))2120*opt_value = PATCH_FORMAT_STGIT_SERIES;2121else if(!strcmp(arg,"hg"))2122*opt_value = PATCH_FORMAT_HG;2123else if(!strcmp(arg,"mboxrd"))2124*opt_value = PATCH_FORMAT_MBOXRD;2125/*2126 * Please update $__git_patchformat in git-completion.bash2127 * when you add new options2128 */2129else2130returnerror(_("Invalid value for --patch-format:%s"), arg);2131return0;2132}21332134enum resume_mode {2135 RESUME_FALSE =0,2136 RESUME_APPLY,2137 RESUME_RESOLVED,2138 RESUME_SKIP,2139 RESUME_ABORT,2140 RESUME_QUIT,2141 RESUME_SHOW_PATCH2142};21432144static intgit_am_config(const char*k,const char*v,void*cb)2145{2146int status;21472148 status =git_gpg_config(k, v, NULL);2149if(status)2150return status;21512152returngit_default_config(k, v, NULL);2153}21542155intcmd_am(int argc,const char**argv,const char*prefix)2156{2157struct am_state state;2158int binary = -1;2159int keep_cr = -1;2160int patch_format = PATCH_FORMAT_UNKNOWN;2161enum resume_mode resume = RESUME_FALSE;2162int in_progress;2163int ret =0;21642165const char*const usage[] = {2166N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2167N_("git am [<options>] (--continue | --skip | --abort)"),2168 NULL2169};21702171struct option options[] = {2172OPT_BOOL('i',"interactive", &state.interactive,2173N_("run interactively")),2174OPT_HIDDEN_BOOL('b',"binary", &binary,2175N_("historical option -- no-op")),2176OPT_BOOL('3',"3way", &state.threeway,2177N_("allow fall back on 3way merging if needed")),2178OPT__QUIET(&state.quiet,N_("be quiet")),2179OPT_SET_INT('s',"signoff", &state.signoff,2180N_("add a Signed-off-by line to the commit message"),2181 SIGNOFF_EXPLICIT),2182OPT_BOOL('u',"utf8", &state.utf8,2183N_("recode into utf8 (default)")),2184OPT_SET_INT('k',"keep", &state.keep,2185N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2186OPT_SET_INT(0,"keep-non-patch", &state.keep,2187N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2188OPT_BOOL('m',"message-id", &state.message_id,2189N_("pass -m flag to git-mailinfo")),2190OPT_SET_INT_F(0,"keep-cr", &keep_cr,2191N_("pass --keep-cr flag to git-mailsplit for mbox format"),21921, PARSE_OPT_NONEG),2193OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2194N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21950, PARSE_OPT_NONEG),2196OPT_BOOL('c',"scissors", &state.scissors,2197N_("strip everything before a scissors line")),2198OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2199N_("pass it through git-apply"),22000),2201OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2202N_("pass it through git-apply"),2203 PARSE_OPT_NOARG),2204OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2205N_("pass it through git-apply"),2206 PARSE_OPT_NOARG),2207OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2208N_("pass it through git-apply"),22090),2210OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2211N_("pass it through git-apply"),22120),2213OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2214N_("pass it through git-apply"),22150),2216OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2217N_("pass it through git-apply"),22180),2219OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2220N_("pass it through git-apply"),22210),2222OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2223N_("format the patch(es) are in"),2224 parse_opt_patchformat),2225OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2226N_("pass it through git-apply"),2227 PARSE_OPT_NOARG),2228OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2229N_("override error message when patch failure occurs")),2230OPT_CMDMODE(0,"continue", &resume,2231N_("continue applying patches after resolving a conflict"),2232 RESUME_RESOLVED),2233OPT_CMDMODE('r',"resolved", &resume,2234N_("synonyms for --continue"),2235 RESUME_RESOLVED),2236OPT_CMDMODE(0,"skip", &resume,2237N_("skip the current patch"),2238 RESUME_SKIP),2239OPT_CMDMODE(0,"abort", &resume,2240N_("restore the original branch and abort the patching operation."),2241 RESUME_ABORT),2242OPT_CMDMODE(0,"quit", &resume,2243N_("abort the patching operation but keep HEAD where it is."),2244 RESUME_QUIT),2245OPT_CMDMODE(0,"show-current-patch", &resume,2246N_("show the patch being applied."),2247 RESUME_SHOW_PATCH),2248OPT_BOOL(0,"committer-date-is-author-date",2249&state.committer_date_is_author_date,2250N_("lie about committer date")),2251OPT_BOOL(0,"ignore-date", &state.ignore_date,2252N_("use current timestamp for author date")),2253OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2254{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2255N_("GPG-sign commits"),2256 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2257OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2258N_("(internal use for git-rebase)")),2259OPT_END()2260};22612262if(argc ==2&& !strcmp(argv[1],"-h"))2263usage_with_options(usage, options);22642265git_config(git_am_config, NULL);22662267am_state_init(&state);22682269 in_progress =am_in_progress(&state);2270if(in_progress)2271am_load(&state);22722273 argc =parse_options(argc, argv, prefix, options, usage,0);22742275if(binary >=0)2276fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2277"it will be removed. Please do not use it anymore."));22782279/* Ensure a valid committer ident can be constructed */2280git_committer_info(IDENT_STRICT);22812282if(repo_read_index_preload(the_repository, NULL,0) <0)2283die(_("failed to read the index"));22842285if(in_progress) {2286/*2287 * Catch user error to feed us patches when there is a session2288 * in progress:2289 *2290 * 1. mbox path(s) are provided on the command-line.2291 * 2. stdin is not a tty: the user is trying to feed us a patch2292 * from standard input. This is somewhat unreliable -- stdin2293 * could be /dev/null for example and the caller did not2294 * intend to feed us a patch but wanted to continue2295 * unattended.2296 */2297if(argc || (resume == RESUME_FALSE && !isatty(0)))2298die(_("previous rebase directory%sstill exists but mbox given."),2299 state.dir);23002301if(resume == RESUME_FALSE)2302 resume = RESUME_APPLY;23032304if(state.signoff == SIGNOFF_EXPLICIT)2305am_append_signoff(&state);2306}else{2307struct argv_array paths = ARGV_ARRAY_INIT;2308int i;23092310/*2311 * Handle stray state directory in the independent-run case. In2312 * the --rebasing case, it is up to the caller to take care of2313 * stray directories.2314 */2315if(file_exists(state.dir) && !state.rebasing) {2316if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2317am_destroy(&state);2318am_state_release(&state);2319return0;2320}23212322die(_("Stray%sdirectory found.\n"2323"Use\"git am --abort\"to remove it."),2324 state.dir);2325}23262327if(resume)2328die(_("Resolve operation not in progress, we are not resuming."));23292330for(i =0; i < argc; i++) {2331if(is_absolute_path(argv[i]) || !prefix)2332argv_array_push(&paths, argv[i]);2333else2334argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2335}23362337if(state.interactive && !paths.argc)2338die(_("interactive mode requires patches on the command line"));23392340am_setup(&state, patch_format, paths.argv, keep_cr);23412342argv_array_clear(&paths);2343}23442345switch(resume) {2346case RESUME_FALSE:2347am_run(&state,0);2348break;2349case RESUME_APPLY:2350am_run(&state,1);2351break;2352case RESUME_RESOLVED:2353am_resolve(&state);2354break;2355case RESUME_SKIP:2356am_skip(&state);2357break;2358case RESUME_ABORT:2359am_abort(&state);2360break;2361case RESUME_QUIT:2362am_rerere_clear();2363am_destroy(&state);2364break;2365case RESUME_SHOW_PATCH:2366 ret =show_patch(&state);2367break;2368default:2369BUG("invalid resume value");2370}23712372am_state_release(&state);23732374return ret;2375}