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; 489 490if(sb.len != GIT_SHA1_HEXSZ *2+1) { 491 ret =error(invalid_line, sb.buf); 492goto finish; 493} 494 495if(get_oid_hex(sb.buf, &from_obj)) { 496 ret =error(invalid_line, sb.buf); 497goto finish; 498} 499 500if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 501 ret =error(invalid_line, sb.buf); 502goto finish; 503} 504 505if(get_oid_hex(sb.buf + GIT_SHA1_HEXSZ +1, &to_obj)) { 506 ret =error(invalid_line, sb.buf); 507goto finish; 508} 509 510if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 511 ret =error(_("Failed to copy notes from '%s' to '%s'"), 512oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 513} 514 515finish: 516finish_copy_notes_for_rewrite(the_repository, c, msg); 517fclose(fp); 518strbuf_release(&sb); 519return ret; 520} 521 522/** 523 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 524 * non-indented lines and checking if they look like they begin with valid 525 * header field names. 526 * 527 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 528 */ 529static intis_mail(FILE*fp) 530{ 531const char*header_regex ="^[!-9;-~]+:"; 532struct strbuf sb = STRBUF_INIT; 533 regex_t regex; 534int ret =1; 535 536if(fseek(fp,0L, SEEK_SET)) 537die_errno(_("fseek failed")); 538 539if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 540die("invalid pattern:%s", header_regex); 541 542while(!strbuf_getline(&sb, fp)) { 543if(!sb.len) 544break;/* End of header */ 545 546/* Ignore indented folded lines */ 547if(*sb.buf =='\t'|| *sb.buf ==' ') 548continue; 549 550/* It's a header if it matches header_regex */ 551if(regexec(®ex, sb.buf,0, NULL,0)) { 552 ret =0; 553goto done; 554} 555} 556 557done: 558regfree(®ex); 559strbuf_release(&sb); 560return ret; 561} 562 563/** 564 * Attempts to detect the patch_format of the patches contained in `paths`, 565 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 566 * detection fails. 567 */ 568static intdetect_patch_format(const char**paths) 569{ 570enum patch_format ret = PATCH_FORMAT_UNKNOWN; 571struct strbuf l1 = STRBUF_INIT; 572struct strbuf l2 = STRBUF_INIT; 573struct strbuf l3 = STRBUF_INIT; 574FILE*fp; 575 576/* 577 * We default to mbox format if input is from stdin and for directories 578 */ 579if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 580return PATCH_FORMAT_MBOX; 581 582/* 583 * Otherwise, check the first few lines of the first patch, starting 584 * from the first non-blank line, to try to detect its format. 585 */ 586 587 fp =xfopen(*paths,"r"); 588 589while(!strbuf_getline(&l1, fp)) { 590if(l1.len) 591break; 592} 593 594if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 595 ret = PATCH_FORMAT_MBOX; 596goto done; 597} 598 599if(starts_with(l1.buf,"# This series applies on GIT commit")) { 600 ret = PATCH_FORMAT_STGIT_SERIES; 601goto done; 602} 603 604if(!strcmp(l1.buf,"# HG changeset patch")) { 605 ret = PATCH_FORMAT_HG; 606goto done; 607} 608 609strbuf_getline(&l2, fp); 610strbuf_getline(&l3, fp); 611 612/* 613 * If the second line is empty and the third is a From, Author or Date 614 * entry, this is likely an StGit patch. 615 */ 616if(l1.len && !l2.len && 617(starts_with(l3.buf,"From:") || 618starts_with(l3.buf,"Author:") || 619starts_with(l3.buf,"Date:"))) { 620 ret = PATCH_FORMAT_STGIT; 621goto done; 622} 623 624if(l1.len &&is_mail(fp)) { 625 ret = PATCH_FORMAT_MBOX; 626goto done; 627} 628 629done: 630fclose(fp); 631strbuf_release(&l1); 632strbuf_release(&l2); 633strbuf_release(&l3); 634return ret; 635} 636 637/** 638 * Splits out individual email patches from `paths`, where each path is either 639 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 640 */ 641static intsplit_mail_mbox(struct am_state *state,const char**paths, 642int keep_cr,int mboxrd) 643{ 644struct child_process cp = CHILD_PROCESS_INIT; 645struct strbuf last = STRBUF_INIT; 646int ret; 647 648 cp.git_cmd =1; 649argv_array_push(&cp.args,"mailsplit"); 650argv_array_pushf(&cp.args,"-d%d", state->prec); 651argv_array_pushf(&cp.args,"-o%s", state->dir); 652argv_array_push(&cp.args,"-b"); 653if(keep_cr) 654argv_array_push(&cp.args,"--keep-cr"); 655if(mboxrd) 656argv_array_push(&cp.args,"--mboxrd"); 657argv_array_push(&cp.args,"--"); 658argv_array_pushv(&cp.args, paths); 659 660 ret =capture_command(&cp, &last,8); 661if(ret) 662goto exit; 663 664 state->cur =1; 665 state->last =strtol(last.buf, NULL,10); 666 667exit: 668strbuf_release(&last); 669return ret ? -1:0; 670} 671 672/** 673 * Callback signature for split_mail_conv(). The foreign patch should be 674 * read from `in`, and the converted patch (in RFC2822 mail format) should be 675 * written to `out`. Return 0 on success, or -1 on failure. 676 */ 677typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 678 679/** 680 * Calls `fn` for each file in `paths` to convert the foreign patch to the 681 * RFC2822 mail format suitable for parsing with git-mailinfo. 682 * 683 * Returns 0 on success, -1 on failure. 684 */ 685static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 686const char**paths,int keep_cr) 687{ 688static const char*stdin_only[] = {"-", NULL}; 689int i; 690 691if(!*paths) 692 paths = stdin_only; 693 694for(i =0; *paths; paths++, i++) { 695FILE*in, *out; 696const char*mail; 697int ret; 698 699if(!strcmp(*paths,"-")) 700 in = stdin; 701else 702 in =fopen(*paths,"r"); 703 704if(!in) 705returnerror_errno(_("could not open '%s' for reading"), 706*paths); 707 708 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 709 710 out =fopen(mail,"w"); 711if(!out) { 712if(in != stdin) 713fclose(in); 714returnerror_errno(_("could not open '%s' for writing"), 715 mail); 716} 717 718 ret =fn(out, in, keep_cr); 719 720fclose(out); 721if(in != stdin) 722fclose(in); 723 724if(ret) 725returnerror(_("could not parse patch '%s'"), *paths); 726} 727 728 state->cur =1; 729 state->last = i; 730return0; 731} 732 733/** 734 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 735 * message suitable for parsing with git-mailinfo. 736 */ 737static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 738{ 739struct strbuf sb = STRBUF_INIT; 740int subject_printed =0; 741 742while(!strbuf_getline_lf(&sb, in)) { 743const char*str; 744 745if(str_isspace(sb.buf)) 746continue; 747else if(skip_prefix(sb.buf,"Author:", &str)) 748fprintf(out,"From:%s\n", str); 749else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 750fprintf(out,"%s\n", sb.buf); 751else if(!subject_printed) { 752fprintf(out,"Subject:%s\n", sb.buf); 753 subject_printed =1; 754}else{ 755fprintf(out,"\n%s\n", sb.buf); 756break; 757} 758} 759 760strbuf_reset(&sb); 761while(strbuf_fread(&sb,8192, in) >0) { 762fwrite(sb.buf,1, sb.len, out); 763strbuf_reset(&sb); 764} 765 766strbuf_release(&sb); 767return0; 768} 769 770/** 771 * This function only supports a single StGit series file in `paths`. 772 * 773 * Given an StGit series file, converts the StGit patches in the series into 774 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 775 * the state directory. 776 * 777 * Returns 0 on success, -1 on failure. 778 */ 779static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 780int keep_cr) 781{ 782const char*series_dir; 783char*series_dir_buf; 784FILE*fp; 785struct argv_array patches = ARGV_ARRAY_INIT; 786struct strbuf sb = STRBUF_INIT; 787int ret; 788 789if(!paths[0] || paths[1]) 790returnerror(_("Only one StGIT patch series can be applied at once")); 791 792 series_dir_buf =xstrdup(*paths); 793 series_dir =dirname(series_dir_buf); 794 795 fp =fopen(*paths,"r"); 796if(!fp) 797returnerror_errno(_("could not open '%s' for reading"), *paths); 798 799while(!strbuf_getline_lf(&sb, fp)) { 800if(*sb.buf =='#') 801continue;/* skip comment lines */ 802 803argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 804} 805 806fclose(fp); 807strbuf_release(&sb); 808free(series_dir_buf); 809 810 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 811 812argv_array_clear(&patches); 813return ret; 814} 815 816/** 817 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 818 * message suitable for parsing with git-mailinfo. 819 */ 820static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 821{ 822struct strbuf sb = STRBUF_INIT; 823int rc =0; 824 825while(!strbuf_getline_lf(&sb, in)) { 826const char*str; 827 828if(skip_prefix(sb.buf,"# User ", &str)) 829fprintf(out,"From:%s\n", str); 830else if(skip_prefix(sb.buf,"# Date ", &str)) { 831 timestamp_t timestamp; 832long tz, tz2; 833char*end; 834 835 errno =0; 836 timestamp =parse_timestamp(str, &end,10); 837if(errno) { 838 rc =error(_("invalid timestamp")); 839goto exit; 840} 841 842if(!skip_prefix(end," ", &str)) { 843 rc =error(_("invalid Date line")); 844goto exit; 845} 846 847 errno =0; 848 tz =strtol(str, &end,10); 849if(errno) { 850 rc =error(_("invalid timezone offset")); 851goto exit; 852} 853 854if(*end) { 855 rc =error(_("invalid Date line")); 856goto exit; 857} 858 859/* 860 * mercurial's timezone is in seconds west of UTC, 861 * however git's timezone is in hours + minutes east of 862 * UTC. Convert it. 863 */ 864 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 865if(tz >0) 866 tz2 = -tz2; 867 868fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 869}else if(starts_with(sb.buf,"# ")) { 870continue; 871}else{ 872fprintf(out,"\n%s\n", sb.buf); 873break; 874} 875} 876 877strbuf_reset(&sb); 878while(strbuf_fread(&sb,8192, in) >0) { 879fwrite(sb.buf,1, sb.len, out); 880strbuf_reset(&sb); 881} 882exit: 883strbuf_release(&sb); 884return rc; 885} 886 887/** 888 * Splits a list of files/directories into individual email patches. Each path 889 * in `paths` must be a file/directory that is formatted according to 890 * `patch_format`. 891 * 892 * Once split out, the individual email patches will be stored in the state 893 * directory, with each patch's filename being its index, padded to state->prec 894 * digits. 895 * 896 * state->cur will be set to the index of the first mail, and state->last will 897 * be set to the index of the last mail. 898 * 899 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 900 * to disable this behavior, -1 to use the default configured setting. 901 * 902 * Returns 0 on success, -1 on failure. 903 */ 904static intsplit_mail(struct am_state *state,enum patch_format patch_format, 905const char**paths,int keep_cr) 906{ 907if(keep_cr <0) { 908 keep_cr =0; 909git_config_get_bool("am.keepcr", &keep_cr); 910} 911 912switch(patch_format) { 913case PATCH_FORMAT_MBOX: 914returnsplit_mail_mbox(state, paths, keep_cr,0); 915case PATCH_FORMAT_STGIT: 916returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 917case PATCH_FORMAT_STGIT_SERIES: 918returnsplit_mail_stgit_series(state, paths, keep_cr); 919case PATCH_FORMAT_HG: 920returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 921case PATCH_FORMAT_MBOXRD: 922returnsplit_mail_mbox(state, paths, keep_cr,1); 923default: 924BUG("invalid patch_format"); 925} 926return-1; 927} 928 929/** 930 * Setup a new am session for applying patches 931 */ 932static voidam_setup(struct am_state *state,enum patch_format patch_format, 933const char**paths,int keep_cr) 934{ 935struct object_id curr_head; 936const char*str; 937struct strbuf sb = STRBUF_INIT; 938 939if(!patch_format) 940 patch_format =detect_patch_format(paths); 941 942if(!patch_format) { 943fprintf_ln(stderr,_("Patch format detection failed.")); 944exit(128); 945} 946 947if(mkdir(state->dir,0777) <0&& errno != EEXIST) 948die_errno(_("failed to create directory '%s'"), state->dir); 949delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF); 950 951if(split_mail(state, patch_format, paths, keep_cr) <0) { 952am_destroy(state); 953die(_("Failed to split patches.")); 954} 955 956if(state->rebasing) 957 state->threeway =1; 958 959write_state_bool(state,"threeway", state->threeway); 960write_state_bool(state,"quiet", state->quiet); 961write_state_bool(state,"sign", state->signoff); 962write_state_bool(state,"utf8", state->utf8); 963 964if(state->allow_rerere_autoupdate) 965write_state_bool(state,"rerere-autoupdate", 966 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE); 967 968switch(state->keep) { 969case KEEP_FALSE: 970 str ="f"; 971break; 972case KEEP_TRUE: 973 str ="t"; 974break; 975case KEEP_NON_PATCH: 976 str ="b"; 977break; 978default: 979BUG("invalid value for state->keep"); 980} 981 982write_state_text(state,"keep", str); 983write_state_bool(state,"messageid", state->message_id); 984 985switch(state->scissors) { 986case SCISSORS_UNSET: 987 str =""; 988break; 989case SCISSORS_FALSE: 990 str ="f"; 991break; 992case SCISSORS_TRUE: 993 str ="t"; 994break; 995default: 996BUG("invalid value for state->scissors"); 997} 998write_state_text(state,"scissors", str); 9991000sq_quote_argv(&sb, state->git_apply_opts.argv);1001write_state_text(state,"apply-opt", sb.buf);10021003if(state->rebasing)1004write_state_text(state,"rebasing","");1005else1006write_state_text(state,"applying","");10071008if(!get_oid("HEAD", &curr_head)) {1009write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1010if(!state->rebasing)1011update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1012 UPDATE_REFS_DIE_ON_ERR);1013}else{1014write_state_text(state,"abort-safety","");1015if(!state->rebasing)1016delete_ref(NULL,"ORIG_HEAD", NULL,0);1017}10181019/*1020 * NOTE: Since the "next" and "last" files determine if an am_state1021 * session is in progress, they should be written last.1022 */10231024write_state_count(state,"next", state->cur);1025write_state_count(state,"last", state->last);10261027strbuf_release(&sb);1028}10291030/**1031 * Increments the patch pointer, and cleans am_state for the application of the1032 * next patch.1033 */1034static voidam_next(struct am_state *state)1035{1036struct object_id head;10371038FREE_AND_NULL(state->author_name);1039FREE_AND_NULL(state->author_email);1040FREE_AND_NULL(state->author_date);1041FREE_AND_NULL(state->msg);1042 state->msg_len =0;10431044unlink(am_path(state,"author-script"));1045unlink(am_path(state,"final-commit"));10461047oidclr(&state->orig_commit);1048unlink(am_path(state,"original-commit"));1049delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10501051if(!get_oid("HEAD", &head))1052write_state_text(state,"abort-safety",oid_to_hex(&head));1053else1054write_state_text(state,"abort-safety","");10551056 state->cur++;1057write_state_count(state,"next", state->cur);1058}10591060/**1061 * Returns the filename of the current patch email.1062 */1063static const char*msgnum(const struct am_state *state)1064{1065static struct strbuf sb = STRBUF_INIT;10661067strbuf_reset(&sb);1068strbuf_addf(&sb,"%0*d", state->prec, state->cur);10691070return sb.buf;1071}10721073/**1074 * Refresh and write index.1075 */1076static voidrefresh_and_write_cache(void)1077{1078struct lock_file lock_file = LOCK_INIT;10791080hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1081refresh_cache(REFRESH_QUIET);1082if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1083die(_("unable to write index file"));1084}10851086/**1087 * Dies with a user-friendly message on how to proceed after resolving the1088 * problem. This message can be overridden with state->resolvemsg.1089 */1090static void NORETURN die_user_resolve(const struct am_state *state)1091{1092if(state->resolvemsg) {1093printf_ln("%s", state->resolvemsg);1094}else{1095const char*cmdline = state->interactive ?"git am -i":"git am";10961097printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1098printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1099printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1100}11011102exit(128);1103}11041105/**1106 * Appends signoff to the "msg" field of the am_state.1107 */1108static voidam_append_signoff(struct am_state *state)1109{1110struct strbuf sb = STRBUF_INIT;11111112strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1113append_signoff(&sb,0,0);1114 state->msg =strbuf_detach(&sb, &state->msg_len);1115}11161117/**1118 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1119 * state->msg will be set to the patch message. state->author_name,1120 * state->author_email and state->author_date will be set to the patch author's1121 * name, email and date respectively. The patch body will be written to the1122 * state directory's "patch" file.1123 *1124 * Returns 1 if the patch should be skipped, 0 otherwise.1125 */1126static intparse_mail(struct am_state *state,const char*mail)1127{1128FILE*fp;1129struct strbuf sb = STRBUF_INIT;1130struct strbuf msg = STRBUF_INIT;1131struct strbuf author_name = STRBUF_INIT;1132struct strbuf author_date = STRBUF_INIT;1133struct strbuf author_email = STRBUF_INIT;1134int ret =0;1135struct mailinfo mi;11361137setup_mailinfo(&mi);11381139if(state->utf8)1140 mi.metainfo_charset =get_commit_output_encoding();1141else1142 mi.metainfo_charset = NULL;11431144switch(state->keep) {1145case KEEP_FALSE:1146break;1147case KEEP_TRUE:1148 mi.keep_subject =1;1149break;1150case KEEP_NON_PATCH:1151 mi.keep_non_patch_brackets_in_subject =1;1152break;1153default:1154BUG("invalid value for state->keep");1155}11561157if(state->message_id)1158 mi.add_message_id =1;11591160switch(state->scissors) {1161case SCISSORS_UNSET:1162break;1163case SCISSORS_FALSE:1164 mi.use_scissors =0;1165break;1166case SCISSORS_TRUE:1167 mi.use_scissors =1;1168break;1169default:1170BUG("invalid value for state->scissors");1171}11721173 mi.input =xfopen(mail,"r");1174 mi.output =xfopen(am_path(state,"info"),"w");1175if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1176die("could not parse patch");11771178fclose(mi.input);1179fclose(mi.output);11801181if(mi.format_flowed)1182warning(_("Patch sent with format=flowed; "1183"space at the end of lines might be lost."));11841185/* Extract message and author information */1186 fp =xfopen(am_path(state,"info"),"r");1187while(!strbuf_getline_lf(&sb, fp)) {1188const char*x;11891190if(skip_prefix(sb.buf,"Subject: ", &x)) {1191if(msg.len)1192strbuf_addch(&msg,'\n');1193strbuf_addstr(&msg, x);1194}else if(skip_prefix(sb.buf,"Author: ", &x))1195strbuf_addstr(&author_name, x);1196else if(skip_prefix(sb.buf,"Email: ", &x))1197strbuf_addstr(&author_email, x);1198else if(skip_prefix(sb.buf,"Date: ", &x))1199strbuf_addstr(&author_date, x);1200}1201fclose(fp);12021203/* Skip pine's internal folder data */1204if(!strcmp(author_name.buf,"Mail System Internal Data")) {1205 ret =1;1206goto finish;1207}12081209if(is_empty_or_missing_file(am_path(state,"patch"))) {1210printf_ln(_("Patch is empty."));1211die_user_resolve(state);1212}12131214strbuf_addstr(&msg,"\n\n");1215strbuf_addbuf(&msg, &mi.log_message);1216strbuf_stripspace(&msg,0);12171218assert(!state->author_name);1219 state->author_name =strbuf_detach(&author_name, NULL);12201221assert(!state->author_email);1222 state->author_email =strbuf_detach(&author_email, NULL);12231224assert(!state->author_date);1225 state->author_date =strbuf_detach(&author_date, NULL);12261227assert(!state->msg);1228 state->msg =strbuf_detach(&msg, &state->msg_len);12291230finish:1231strbuf_release(&msg);1232strbuf_release(&author_date);1233strbuf_release(&author_email);1234strbuf_release(&author_name);1235strbuf_release(&sb);1236clear_mailinfo(&mi);1237return ret;1238}12391240/**1241 * Sets commit_id to the commit hash where the mail was generated from.1242 * Returns 0 on success, -1 on failure.1243 */1244static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1245{1246struct strbuf sb = STRBUF_INIT;1247FILE*fp =xfopen(mail,"r");1248const char*x;1249int ret =0;12501251if(strbuf_getline_lf(&sb, fp) ||1252!skip_prefix(sb.buf,"From ", &x) ||1253get_oid_hex(x, commit_id) <0)1254 ret = -1;12551256strbuf_release(&sb);1257fclose(fp);1258return ret;1259}12601261/**1262 * Sets state->msg, state->author_name, state->author_email, state->author_date1263 * to the commit's respective info.1264 */1265static voidget_commit_info(struct am_state *state,struct commit *commit)1266{1267const char*buffer, *ident_line, *msg;1268size_t ident_len;1269struct ident_split id;12701271 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());12721273 ident_line =find_commit_header(buffer,"author", &ident_len);12741275if(split_ident_line(&id, ident_line, ident_len) <0)1276die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12771278assert(!state->author_name);1279if(id.name_begin)1280 state->author_name =1281xmemdupz(id.name_begin, id.name_end - id.name_begin);1282else1283 state->author_name =xstrdup("");12841285assert(!state->author_email);1286if(id.mail_begin)1287 state->author_email =1288xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1289else1290 state->author_email =xstrdup("");12911292assert(!state->author_date);1293 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));12941295assert(!state->msg);1296 msg =strstr(buffer,"\n\n");1297if(!msg)1298die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1299 state->msg =xstrdup(msg +2);1300 state->msg_len =strlen(state->msg);1301unuse_commit_buffer(commit, buffer);1302}13031304/**1305 * Writes `commit` as a patch to the state directory's "patch" file.1306 */1307static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1308{1309struct rev_info rev_info;1310FILE*fp;13111312 fp =xfopen(am_path(state,"patch"),"w");1313repo_init_revisions(the_repository, &rev_info, NULL);1314 rev_info.diff =1;1315 rev_info.abbrev =0;1316 rev_info.disable_stdin =1;1317 rev_info.show_root_diff =1;1318 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1319 rev_info.no_commit_id =1;1320 rev_info.diffopt.flags.binary =1;1321 rev_info.diffopt.flags.full_index =1;1322 rev_info.diffopt.use_color =0;1323 rev_info.diffopt.file = fp;1324 rev_info.diffopt.close_file =1;1325add_pending_object(&rev_info, &commit->object,"");1326diff_setup_done(&rev_info.diffopt);1327log_tree_commit(&rev_info, commit);1328}13291330/**1331 * Writes the diff of the index against HEAD as a patch to the state1332 * directory's "patch" file.1333 */1334static voidwrite_index_patch(const struct am_state *state)1335{1336struct tree *tree;1337struct object_id head;1338struct rev_info rev_info;1339FILE*fp;13401341if(!get_oid_tree("HEAD", &head))1342 tree =lookup_tree(the_repository, &head);1343else1344 tree =lookup_tree(the_repository,1345 the_repository->hash_algo->empty_tree);13461347 fp =xfopen(am_path(state,"patch"),"w");1348repo_init_revisions(the_repository, &rev_info, NULL);1349 rev_info.diff =1;1350 rev_info.disable_stdin =1;1351 rev_info.no_commit_id =1;1352 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1353 rev_info.diffopt.use_color =0;1354 rev_info.diffopt.file = fp;1355 rev_info.diffopt.close_file =1;1356add_pending_object(&rev_info, &tree->object,"");1357diff_setup_done(&rev_info.diffopt);1358run_diff_index(&rev_info,1);1359}13601361/**1362 * Like parse_mail(), but parses the mail by looking up its commit ID1363 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1364 * of patches.1365 *1366 * state->orig_commit will be set to the original commit ID.1367 *1368 * Will always return 0 as the patch should never be skipped.1369 */1370static intparse_mail_rebase(struct am_state *state,const char*mail)1371{1372struct commit *commit;1373struct object_id commit_oid;13741375if(get_mail_commit_oid(&commit_oid, mail) <0)1376die(_("could not parse%s"), mail);13771378 commit =lookup_commit_or_die(&commit_oid, mail);13791380get_commit_info(state, commit);13811382write_commit_patch(state, commit);13831384oidcpy(&state->orig_commit, &commit_oid);1385write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1386update_ref("am","REBASE_HEAD", &commit_oid,1387 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);13881389return0;1390}13911392/**1393 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1394 * `index_file` is not NULL, the patch will be applied to that index.1395 */1396static intrun_apply(const struct am_state *state,const char*index_file)1397{1398struct argv_array apply_paths = ARGV_ARRAY_INIT;1399struct argv_array apply_opts = ARGV_ARRAY_INIT;1400struct apply_state apply_state;1401int res, opts_left;1402int force_apply =0;1403int options =0;14041405if(init_apply_state(&apply_state, the_repository, NULL))1406BUG("init_apply_state() failed");14071408argv_array_push(&apply_opts,"apply");1409argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14101411 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1412&apply_state, &force_apply, &options,1413 NULL);14141415if(opts_left !=0)1416die("unknown option passed through to git apply");14171418if(index_file) {1419 apply_state.index_file = index_file;1420 apply_state.cached =1;1421}else1422 apply_state.check_index =1;14231424/*1425 * If we are allowed to fall back on 3-way merge, don't give false1426 * errors during the initial attempt.1427 */1428if(state->threeway && !index_file)1429 apply_state.apply_verbosity = verbosity_silent;14301431if(check_apply_state(&apply_state, force_apply))1432BUG("check_apply_state() failed");14331434argv_array_push(&apply_paths,am_path(state,"patch"));14351436 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14371438argv_array_clear(&apply_paths);1439argv_array_clear(&apply_opts);1440clear_apply_state(&apply_state);14411442if(res)1443return res;14441445if(index_file) {1446/* Reload index as apply_all_patches() will have modified it. */1447discard_cache();1448read_cache_from(index_file);1449}14501451return0;1452}14531454/**1455 * Builds an index that contains just the blobs needed for a 3way merge.1456 */1457static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1458{1459struct child_process cp = CHILD_PROCESS_INIT;14601461 cp.git_cmd =1;1462argv_array_push(&cp.args,"apply");1463argv_array_pushv(&cp.args, state->git_apply_opts.argv);1464argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1465argv_array_push(&cp.args,am_path(state,"patch"));14661467if(run_command(&cp))1468return-1;14691470return0;1471}14721473/**1474 * Attempt a threeway merge, using index_path as the temporary index.1475 */1476static intfall_back_threeway(const struct am_state *state,const char*index_path)1477{1478struct object_id orig_tree, their_tree, our_tree;1479const struct object_id *bases[1] = { &orig_tree };1480struct merge_options o;1481struct commit *result;1482char*their_tree_name;14831484if(get_oid("HEAD", &our_tree) <0)1485oidcpy(&our_tree, the_hash_algo->empty_tree);14861487if(build_fake_ancestor(state, index_path))1488returnerror("could not build fake ancestor");14891490discard_cache();1491read_cache_from(index_path);14921493if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1494returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));14951496say(state, stdout,_("Using index info to reconstruct a base tree..."));14971498if(!state->quiet) {1499/*1500 * List paths that needed 3-way fallback, so that the user can1501 * review them with extra care to spot mismerges.1502 */1503struct rev_info rev_info;1504const char*diff_filter_str ="--diff-filter=AM";15051506repo_init_revisions(the_repository, &rev_info, NULL);1507 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1508diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1509add_pending_oid(&rev_info,"HEAD", &our_tree,0);1510diff_setup_done(&rev_info.diffopt);1511run_diff_index(&rev_info,1);1512}15131514if(run_apply(state, index_path))1515returnerror(_("Did you hand edit your patch?\n"1516"It does not apply to blobs recorded in its index."));15171518if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1519returnerror("could not write tree");15201521say(state, stdout,_("Falling back to patching base and 3-way merge..."));15221523discard_cache();1524read_cache();15251526/*1527 * This is not so wrong. Depending on which base we picked, orig_tree1528 * may be wildly different from ours, but their_tree has the same set of1529 * wildly different changes in parts the patch did not touch, so1530 * recursive ends up canceling them, saying that we reverted all those1531 * changes.1532 */15331534init_merge_options(&o, the_repository);15351536 o.branch1 ="HEAD";1537 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1538 o.branch2 = their_tree_name;1539 o.detect_directory_renames =0;15401541if(state->quiet)1542 o.verbosity =0;15431544if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1545repo_rerere(the_repository, state->allow_rerere_autoupdate);1546free(their_tree_name);1547returnerror(_("Failed to merge in the changes."));1548}15491550free(their_tree_name);1551return0;1552}15531554/**1555 * Commits the current index with state->msg as the commit message and1556 * state->author_name, state->author_email and state->author_date as the author1557 * information.1558 */1559static voiddo_commit(const struct am_state *state)1560{1561struct object_id tree, parent, commit;1562const struct object_id *old_oid;1563struct commit_list *parents = NULL;1564const char*reflog_msg, *author;1565struct strbuf sb = STRBUF_INIT;15661567if(run_hook_le(NULL,"pre-applypatch", NULL))1568exit(1);15691570if(write_cache_as_tree(&tree,0, NULL))1571die(_("git write-tree failed to write a tree"));15721573if(!get_oid_commit("HEAD", &parent)) {1574 old_oid = &parent;1575commit_list_insert(lookup_commit(the_repository, &parent),1576&parents);1577}else{1578 old_oid = NULL;1579say(state, stderr,_("applying to an empty history"));1580}15811582 author =fmt_ident(state->author_name, state->author_email,1583 WANT_AUTHOR_IDENT,1584 state->ignore_date ? NULL : state->author_date,1585 IDENT_STRICT);15861587if(state->committer_date_is_author_date)1588setenv("GIT_COMMITTER_DATE",1589 state->ignore_date ?"": state->author_date,1);15901591if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1592 author, state->sign_commit))1593die(_("failed to write commit object"));15941595 reflog_msg =getenv("GIT_REFLOG_ACTION");1596if(!reflog_msg)1597 reflog_msg ="am";15981599strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1600 state->msg);16011602update_ref(sb.buf,"HEAD", &commit, old_oid,0,1603 UPDATE_REFS_DIE_ON_ERR);16041605if(state->rebasing) {1606FILE*fp =xfopen(am_path(state,"rewritten"),"a");16071608assert(!is_null_oid(&state->orig_commit));1609fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1610fprintf(fp,"%s\n",oid_to_hex(&commit));1611fclose(fp);1612}16131614run_hook_le(NULL,"post-applypatch", NULL);16151616strbuf_release(&sb);1617}16181619/**1620 * Validates the am_state for resuming -- the "msg" and authorship fields must1621 * be filled up.1622 */1623static voidvalidate_resume_state(const struct am_state *state)1624{1625if(!state->msg)1626die(_("cannot resume:%sdoes not exist."),1627am_path(state,"final-commit"));16281629if(!state->author_name || !state->author_email || !state->author_date)1630die(_("cannot resume:%sdoes not exist."),1631am_path(state,"author-script"));1632}16331634/**1635 * Interactively prompt the user on whether the current patch should be1636 * applied.1637 *1638 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1639 * skip it.1640 */1641static intdo_interactive(struct am_state *state)1642{1643assert(state->msg);16441645if(!isatty(0))1646die(_("cannot be interactive without stdin connected to a terminal."));16471648for(;;) {1649const char*reply;16501651puts(_("Commit Body is:"));1652puts("--------------------------");1653printf("%s", state->msg);1654puts("--------------------------");16551656/*1657 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1658 * in your translation. The program will only accept English1659 * input at this point.1660 */1661 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);16621663if(!reply) {1664continue;1665}else if(*reply =='y'|| *reply =='Y') {1666return0;1667}else if(*reply =='a'|| *reply =='A') {1668 state->interactive =0;1669return0;1670}else if(*reply =='n'|| *reply =='N') {1671return1;1672}else if(*reply =='e'|| *reply =='E') {1673struct strbuf msg = STRBUF_INIT;16741675if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1676free(state->msg);1677 state->msg =strbuf_detach(&msg, &state->msg_len);1678}1679strbuf_release(&msg);1680}else if(*reply =='v'|| *reply =='V') {1681const char*pager =git_pager(1);1682struct child_process cp = CHILD_PROCESS_INIT;16831684if(!pager)1685 pager ="cat";1686prepare_pager_args(&cp, pager);1687argv_array_push(&cp.args,am_path(state,"patch"));1688run_command(&cp);1689}1690}1691}16921693/**1694 * Applies all queued mail.1695 *1696 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1697 * well as the state directory's "patch" file is used as-is for applying the1698 * patch and committing it.1699 */1700static voidam_run(struct am_state *state,int resume)1701{1702const char*argv_gc_auto[] = {"gc","--auto", NULL};1703struct strbuf sb = STRBUF_INIT;17041705unlink(am_path(state,"dirtyindex"));17061707refresh_and_write_cache();17081709if(repo_index_has_changes(the_repository, NULL, &sb)) {1710write_state_bool(state,"dirtyindex",1);1711die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1712}17131714strbuf_release(&sb);17151716while(state->cur <= state->last) {1717const char*mail =am_path(state,msgnum(state));1718int apply_status;17191720reset_ident_date();17211722if(!file_exists(mail))1723goto next;17241725if(resume) {1726validate_resume_state(state);1727}else{1728int skip;17291730if(state->rebasing)1731 skip =parse_mail_rebase(state, mail);1732else1733 skip =parse_mail(state, mail);17341735if(skip)1736goto next;/* mail should be skipped */17371738if(state->signoff)1739am_append_signoff(state);17401741write_author_script(state);1742write_commit_msg(state);1743}17441745if(state->interactive &&do_interactive(state))1746goto next;17471748if(run_applypatch_msg_hook(state))1749exit(1);17501751say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17521753 apply_status =run_apply(state, NULL);17541755if(apply_status && state->threeway) {1756struct strbuf sb = STRBUF_INIT;17571758strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1759 apply_status =fall_back_threeway(state, sb.buf);1760strbuf_release(&sb);17611762/*1763 * Applying the patch to an earlier tree and merging1764 * the result may have produced the same tree as ours.1765 */1766if(!apply_status &&1767!repo_index_has_changes(the_repository, NULL, NULL)) {1768say(state, stdout,_("No changes -- Patch already applied."));1769goto next;1770}1771}17721773if(apply_status) {1774printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1775linelen(state->msg), state->msg);17761777if(advice_amworkdir)1778advise(_("Use 'git am --show-current-patch' to see the failed patch"));17791780die_user_resolve(state);1781}17821783do_commit(state);17841785next:1786am_next(state);17871788if(resume)1789am_load(state);1790 resume =0;1791}17921793if(!is_empty_or_missing_file(am_path(state,"rewritten"))) {1794assert(state->rebasing);1795copy_notes_for_rebase(state);1796run_post_rewrite_hook(state);1797}17981799/*1800 * In rebasing mode, it's up to the caller to take care of1801 * housekeeping.1802 */1803if(!state->rebasing) {1804am_destroy(state);1805close_all_packs(the_repository->objects);1806run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1807}1808}18091810/**1811 * Resume the current am session after patch application failure. The user did1812 * all the hard work, and we do not have to do any patch application. Just1813 * trust and commit what the user has in the index and working tree.1814 */1815static voidam_resolve(struct am_state *state)1816{1817validate_resume_state(state);18181819say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18201821if(!repo_index_has_changes(the_repository, NULL, NULL)) {1822printf_ln(_("No changes - did you forget to use 'git add'?\n"1823"If there is nothing left to stage, chances are that something else\n"1824"already introduced the same changes; you might want to skip this patch."));1825die_user_resolve(state);1826}18271828if(unmerged_cache()) {1829printf_ln(_("You still have unmerged paths in your index.\n"1830"You should 'git add' each file with resolved conflicts to mark them as such.\n"1831"You might run `git rm` on a file to accept\"deleted by them\"for it."));1832die_user_resolve(state);1833}18341835if(state->interactive) {1836write_index_patch(state);1837if(do_interactive(state))1838goto next;1839}18401841repo_rerere(the_repository,0);18421843do_commit(state);18441845next:1846am_next(state);1847am_load(state);1848am_run(state,0);1849}18501851/**1852 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1853 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1854 * failure.1855 */1856static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1857{1858struct lock_file lock_file = LOCK_INIT;1859struct unpack_trees_options opts;1860struct tree_desc t[2];18611862if(parse_tree(head) ||parse_tree(remote))1863return-1;18641865hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18661867refresh_cache(REFRESH_QUIET);18681869memset(&opts,0,sizeof(opts));1870 opts.head_idx =1;1871 opts.src_index = &the_index;1872 opts.dst_index = &the_index;1873 opts.update =1;1874 opts.merge =1;1875 opts.reset = reset;1876 opts.fn = twoway_merge;1877init_tree_desc(&t[0], head->buffer, head->size);1878init_tree_desc(&t[1], remote->buffer, remote->size);18791880if(unpack_trees(2, t, &opts)) {1881rollback_lock_file(&lock_file);1882return-1;1883}18841885if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1886die(_("unable to write new index file"));18871888return0;1889}18901891/**1892 * Merges a tree into the index. The index's stat info will take precedence1893 * over the merged tree's. Returns 0 on success, -1 on failure.1894 */1895static intmerge_tree(struct tree *tree)1896{1897struct lock_file lock_file = LOCK_INIT;1898struct unpack_trees_options opts;1899struct tree_desc t[1];19001901if(parse_tree(tree))1902return-1;19031904hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19051906memset(&opts,0,sizeof(opts));1907 opts.head_idx =1;1908 opts.src_index = &the_index;1909 opts.dst_index = &the_index;1910 opts.merge =1;1911 opts.fn = oneway_merge;1912init_tree_desc(&t[0], tree->buffer, tree->size);19131914if(unpack_trees(1, t, &opts)) {1915rollback_lock_file(&lock_file);1916return-1;1917}19181919if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1920die(_("unable to write new index file"));19211922return0;1923}19241925/**1926 * Clean the index without touching entries that are not modified between1927 * `head` and `remote`.1928 */1929static intclean_index(const struct object_id *head,const struct object_id *remote)1930{1931struct tree *head_tree, *remote_tree, *index_tree;1932struct object_id index;19331934 head_tree =parse_tree_indirect(head);1935if(!head_tree)1936returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19371938 remote_tree =parse_tree_indirect(remote);1939if(!remote_tree)1940returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19411942read_cache_unmerged();19431944if(fast_forward_to(head_tree, head_tree,1))1945return-1;19461947if(write_cache_as_tree(&index,0, NULL))1948return-1;19491950 index_tree =parse_tree_indirect(&index);1951if(!index_tree)1952returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19531954if(fast_forward_to(index_tree, remote_tree,0))1955return-1;19561957if(merge_tree(remote_tree))1958return-1;19591960remove_branch_state(the_repository);19611962return0;1963}19641965/**1966 * Resets rerere's merge resolution metadata.1967 */1968static voidam_rerere_clear(void)1969{1970struct string_list merge_rr = STRING_LIST_INIT_DUP;1971rerere_clear(the_repository, &merge_rr);1972string_list_clear(&merge_rr,1);1973}19741975/**1976 * Resume the current am session by skipping the current patch.1977 */1978static voidam_skip(struct am_state *state)1979{1980struct object_id head;19811982am_rerere_clear();19831984if(get_oid("HEAD", &head))1985oidcpy(&head, the_hash_algo->empty_tree);19861987if(clean_index(&head, &head))1988die(_("failed to clean index"));19891990if(state->rebasing) {1991FILE*fp =xfopen(am_path(state,"rewritten"),"a");19921993assert(!is_null_oid(&state->orig_commit));1994fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1995fprintf(fp,"%s\n",oid_to_hex(&head));1996fclose(fp);1997}19981999am_next(state);2000am_load(state);2001am_run(state,0);2002}20032004/**2005 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2006 *2007 * It is not safe to reset HEAD when:2008 * 1. git-am previously failed because the index was dirty.2009 * 2. HEAD has moved since git-am previously failed.2010 */2011static intsafe_to_abort(const struct am_state *state)2012{2013struct strbuf sb = STRBUF_INIT;2014struct object_id abort_safety, head;20152016if(file_exists(am_path(state,"dirtyindex")))2017return0;20182019if(read_state_file(&sb, state,"abort-safety",1) >0) {2020if(get_oid_hex(sb.buf, &abort_safety))2021die(_("could not parse%s"),am_path(state,"abort-safety"));2022}else2023oidclr(&abort_safety);2024strbuf_release(&sb);20252026if(get_oid("HEAD", &head))2027oidclr(&head);20282029if(oideq(&head, &abort_safety))2030return1;20312032warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2033"Not rewinding to ORIG_HEAD"));20342035return0;2036}20372038/**2039 * Aborts the current am session if it is safe to do so.2040 */2041static voidam_abort(struct am_state *state)2042{2043struct object_id curr_head, orig_head;2044int has_curr_head, has_orig_head;2045char*curr_branch;20462047if(!safe_to_abort(state)) {2048am_destroy(state);2049return;2050}20512052am_rerere_clear();20532054 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2055 has_curr_head = curr_branch && !is_null_oid(&curr_head);2056if(!has_curr_head)2057oidcpy(&curr_head, the_hash_algo->empty_tree);20582059 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2060if(!has_orig_head)2061oidcpy(&orig_head, the_hash_algo->empty_tree);20622063clean_index(&curr_head, &orig_head);20642065if(has_orig_head)2066update_ref("am --abort","HEAD", &orig_head,2067 has_curr_head ? &curr_head : NULL,0,2068 UPDATE_REFS_DIE_ON_ERR);2069else if(curr_branch)2070delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20712072free(curr_branch);2073am_destroy(state);2074}20752076static intshow_patch(struct am_state *state)2077{2078struct strbuf sb = STRBUF_INIT;2079const char*patch_path;2080int len;20812082if(!is_null_oid(&state->orig_commit)) {2083const char*av[4] = {"show", NULL,"--", NULL };2084char*new_oid_str;2085int ret;20862087 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2088 ret =run_command_v_opt(av, RUN_GIT_CMD);2089free(new_oid_str);2090return ret;2091}20922093 patch_path =am_path(state,msgnum(state));2094 len =strbuf_read_file(&sb, patch_path,0);2095if(len <0)2096die_errno(_("failed to read '%s'"), patch_path);20972098setup_pager();2099write_in_full(1, sb.buf, sb.len);2100strbuf_release(&sb);2101return0;2102}21032104/**2105 * parse_options() callback that validates and sets opt->value to the2106 * PATCH_FORMAT_* enum value corresponding to `arg`.2107 */2108static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2109{2110int*opt_value = opt->value;21112112if(unset)2113*opt_value = PATCH_FORMAT_UNKNOWN;2114else if(!strcmp(arg,"mbox"))2115*opt_value = PATCH_FORMAT_MBOX;2116else if(!strcmp(arg,"stgit"))2117*opt_value = PATCH_FORMAT_STGIT;2118else if(!strcmp(arg,"stgit-series"))2119*opt_value = PATCH_FORMAT_STGIT_SERIES;2120else if(!strcmp(arg,"hg"))2121*opt_value = PATCH_FORMAT_HG;2122else if(!strcmp(arg,"mboxrd"))2123*opt_value = PATCH_FORMAT_MBOXRD;2124/*2125 * Please update $__git_patchformat in git-completion.bash2126 * when you add new options2127 */2128else2129returnerror(_("Invalid value for --patch-format:%s"), arg);2130return0;2131}21322133enum resume_mode {2134 RESUME_FALSE =0,2135 RESUME_APPLY,2136 RESUME_RESOLVED,2137 RESUME_SKIP,2138 RESUME_ABORT,2139 RESUME_QUIT,2140 RESUME_SHOW_PATCH2141};21422143static intgit_am_config(const char*k,const char*v,void*cb)2144{2145int status;21462147 status =git_gpg_config(k, v, NULL);2148if(status)2149return status;21502151returngit_default_config(k, v, NULL);2152}21532154intcmd_am(int argc,const char**argv,const char*prefix)2155{2156struct am_state state;2157int binary = -1;2158int keep_cr = -1;2159int patch_format = PATCH_FORMAT_UNKNOWN;2160enum resume_mode resume = RESUME_FALSE;2161int in_progress;2162int ret =0;21632164const char*const usage[] = {2165N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2166N_("git am [<options>] (--continue | --skip | --abort)"),2167 NULL2168};21692170struct option options[] = {2171OPT_BOOL('i',"interactive", &state.interactive,2172N_("run interactively")),2173OPT_HIDDEN_BOOL('b',"binary", &binary,2174N_("historical option -- no-op")),2175OPT_BOOL('3',"3way", &state.threeway,2176N_("allow fall back on 3way merging if needed")),2177OPT__QUIET(&state.quiet,N_("be quiet")),2178OPT_SET_INT('s',"signoff", &state.signoff,2179N_("add a Signed-off-by line to the commit message"),2180 SIGNOFF_EXPLICIT),2181OPT_BOOL('u',"utf8", &state.utf8,2182N_("recode into utf8 (default)")),2183OPT_SET_INT('k',"keep", &state.keep,2184N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2185OPT_SET_INT(0,"keep-non-patch", &state.keep,2186N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2187OPT_BOOL('m',"message-id", &state.message_id,2188N_("pass -m flag to git-mailinfo")),2189OPT_SET_INT_F(0,"keep-cr", &keep_cr,2190N_("pass --keep-cr flag to git-mailsplit for mbox format"),21911, PARSE_OPT_NONEG),2192OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2193N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21940, PARSE_OPT_NONEG),2195OPT_BOOL('c',"scissors", &state.scissors,2196N_("strip everything before a scissors line")),2197OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2198N_("pass it through git-apply"),21990),2200OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2201N_("pass it through git-apply"),2202 PARSE_OPT_NOARG),2203OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2204N_("pass it through git-apply"),2205 PARSE_OPT_NOARG),2206OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2207N_("pass it through git-apply"),22080),2209OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2210N_("pass it through git-apply"),22110),2212OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2213N_("pass it through git-apply"),22140),2215OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2216N_("pass it through git-apply"),22170),2218OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2219N_("pass it through git-apply"),22200),2221OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2222N_("format the patch(es) are in"),2223 parse_opt_patchformat),2224OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2225N_("pass it through git-apply"),2226 PARSE_OPT_NOARG),2227OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2228N_("override error message when patch failure occurs")),2229OPT_CMDMODE(0,"continue", &resume,2230N_("continue applying patches after resolving a conflict"),2231 RESUME_RESOLVED),2232OPT_CMDMODE('r',"resolved", &resume,2233N_("synonyms for --continue"),2234 RESUME_RESOLVED),2235OPT_CMDMODE(0,"skip", &resume,2236N_("skip the current patch"),2237 RESUME_SKIP),2238OPT_CMDMODE(0,"abort", &resume,2239N_("restore the original branch and abort the patching operation."),2240 RESUME_ABORT),2241OPT_CMDMODE(0,"quit", &resume,2242N_("abort the patching operation but keep HEAD where it is."),2243 RESUME_QUIT),2244OPT_CMDMODE(0,"show-current-patch", &resume,2245N_("show the patch being applied."),2246 RESUME_SHOW_PATCH),2247OPT_BOOL(0,"committer-date-is-author-date",2248&state.committer_date_is_author_date,2249N_("lie about committer date")),2250OPT_BOOL(0,"ignore-date", &state.ignore_date,2251N_("use current timestamp for author date")),2252OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2253{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2254N_("GPG-sign commits"),2255 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2256OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2257N_("(internal use for git-rebase)")),2258OPT_END()2259};22602261if(argc ==2&& !strcmp(argv[1],"-h"))2262usage_with_options(usage, options);22632264git_config(git_am_config, NULL);22652266am_state_init(&state);22672268 in_progress =am_in_progress(&state);2269if(in_progress)2270am_load(&state);22712272 argc =parse_options(argc, argv, prefix, options, usage,0);22732274if(binary >=0)2275fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2276"it will be removed. Please do not use it anymore."));22772278/* Ensure a valid committer ident can be constructed */2279git_committer_info(IDENT_STRICT);22802281if(repo_read_index_preload(the_repository, NULL,0) <0)2282die(_("failed to read the index"));22832284if(in_progress) {2285/*2286 * Catch user error to feed us patches when there is a session2287 * in progress:2288 *2289 * 1. mbox path(s) are provided on the command-line.2290 * 2. stdin is not a tty: the user is trying to feed us a patch2291 * from standard input. This is somewhat unreliable -- stdin2292 * could be /dev/null for example and the caller did not2293 * intend to feed us a patch but wanted to continue2294 * unattended.2295 */2296if(argc || (resume == RESUME_FALSE && !isatty(0)))2297die(_("previous rebase directory%sstill exists but mbox given."),2298 state.dir);22992300if(resume == RESUME_FALSE)2301 resume = RESUME_APPLY;23022303if(state.signoff == SIGNOFF_EXPLICIT)2304am_append_signoff(&state);2305}else{2306struct argv_array paths = ARGV_ARRAY_INIT;2307int i;23082309/*2310 * Handle stray state directory in the independent-run case. In2311 * the --rebasing case, it is up to the caller to take care of2312 * stray directories.2313 */2314if(file_exists(state.dir) && !state.rebasing) {2315if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2316am_destroy(&state);2317am_state_release(&state);2318return0;2319}23202321die(_("Stray%sdirectory found.\n"2322"Use\"git am --abort\"to remove it."),2323 state.dir);2324}23252326if(resume)2327die(_("Resolve operation not in progress, we are not resuming."));23282329for(i =0; i < argc; i++) {2330if(is_absolute_path(argv[i]) || !prefix)2331argv_array_push(&paths, argv[i]);2332else2333argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2334}23352336am_setup(&state, patch_format, paths.argv, keep_cr);23372338argv_array_clear(&paths);2339}23402341switch(resume) {2342case RESUME_FALSE:2343am_run(&state,0);2344break;2345case RESUME_APPLY:2346am_run(&state,1);2347break;2348case RESUME_RESOLVED:2349am_resolve(&state);2350break;2351case RESUME_SKIP:2352am_skip(&state);2353break;2354case RESUME_ABORT:2355am_abort(&state);2356break;2357case RESUME_QUIT:2358am_rerere_clear();2359am_destroy(&state);2360break;2361case RESUME_SHOW_PATCH:2362 ret =show_patch(&state);2363break;2364default:2365BUG("invalid resume value");2366}23672368am_state_release(&state);23692370return ret;2371}