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 457 ret =run_command(&cp); 458 459close(cp.in); 460return ret; 461} 462 463/** 464 * Reads the state directory's "rewritten" file, and copies notes from the old 465 * commits listed in the file to their rewritten commits. 466 * 467 * Returns 0 on success, -1 on failure. 468 */ 469static intcopy_notes_for_rebase(const struct am_state *state) 470{ 471struct notes_rewrite_cfg *c; 472struct strbuf sb = STRBUF_INIT; 473const char*invalid_line =_("Malformed input line: '%s'."); 474const char*msg ="Notes added by 'git rebase'"; 475FILE*fp; 476int ret =0; 477 478assert(state->rebasing); 479 480 c =init_copy_notes_for_rewrite("rebase"); 481if(!c) 482return0; 483 484 fp =xfopen(am_path(state,"rewritten"),"r"); 485 486while(!strbuf_getline_lf(&sb, fp)) { 487struct object_id from_obj, to_obj; 488 489if(sb.len != GIT_SHA1_HEXSZ *2+1) { 490 ret =error(invalid_line, sb.buf); 491goto finish; 492} 493 494if(get_oid_hex(sb.buf, &from_obj)) { 495 ret =error(invalid_line, sb.buf); 496goto finish; 497} 498 499if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 500 ret =error(invalid_line, sb.buf); 501goto finish; 502} 503 504if(get_oid_hex(sb.buf + GIT_SHA1_HEXSZ +1, &to_obj)) { 505 ret =error(invalid_line, sb.buf); 506goto finish; 507} 508 509if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 510 ret =error(_("Failed to copy notes from '%s' to '%s'"), 511oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 512} 513 514finish: 515finish_copy_notes_for_rewrite(the_repository, c, msg); 516fclose(fp); 517strbuf_release(&sb); 518return ret; 519} 520 521/** 522 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 523 * non-indented lines and checking if they look like they begin with valid 524 * header field names. 525 * 526 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 527 */ 528static intis_mail(FILE*fp) 529{ 530const char*header_regex ="^[!-9;-~]+:"; 531struct strbuf sb = STRBUF_INIT; 532 regex_t regex; 533int ret =1; 534 535if(fseek(fp,0L, SEEK_SET)) 536die_errno(_("fseek failed")); 537 538if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 539die("invalid pattern:%s", header_regex); 540 541while(!strbuf_getline(&sb, fp)) { 542if(!sb.len) 543break;/* End of header */ 544 545/* Ignore indented folded lines */ 546if(*sb.buf =='\t'|| *sb.buf ==' ') 547continue; 548 549/* It's a header if it matches header_regex */ 550if(regexec(®ex, sb.buf,0, NULL,0)) { 551 ret =0; 552goto done; 553} 554} 555 556done: 557regfree(®ex); 558strbuf_release(&sb); 559return ret; 560} 561 562/** 563 * Attempts to detect the patch_format of the patches contained in `paths`, 564 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 565 * detection fails. 566 */ 567static intdetect_patch_format(const char**paths) 568{ 569enum patch_format ret = PATCH_FORMAT_UNKNOWN; 570struct strbuf l1 = STRBUF_INIT; 571struct strbuf l2 = STRBUF_INIT; 572struct strbuf l3 = STRBUF_INIT; 573FILE*fp; 574 575/* 576 * We default to mbox format if input is from stdin and for directories 577 */ 578if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 579return PATCH_FORMAT_MBOX; 580 581/* 582 * Otherwise, check the first few lines of the first patch, starting 583 * from the first non-blank line, to try to detect its format. 584 */ 585 586 fp =xfopen(*paths,"r"); 587 588while(!strbuf_getline(&l1, fp)) { 589if(l1.len) 590break; 591} 592 593if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 594 ret = PATCH_FORMAT_MBOX; 595goto done; 596} 597 598if(starts_with(l1.buf,"# This series applies on GIT commit")) { 599 ret = PATCH_FORMAT_STGIT_SERIES; 600goto done; 601} 602 603if(!strcmp(l1.buf,"# HG changeset patch")) { 604 ret = PATCH_FORMAT_HG; 605goto done; 606} 607 608strbuf_getline(&l2, fp); 609strbuf_getline(&l3, fp); 610 611/* 612 * If the second line is empty and the third is a From, Author or Date 613 * entry, this is likely an StGit patch. 614 */ 615if(l1.len && !l2.len && 616(starts_with(l3.buf,"From:") || 617starts_with(l3.buf,"Author:") || 618starts_with(l3.buf,"Date:"))) { 619 ret = PATCH_FORMAT_STGIT; 620goto done; 621} 622 623if(l1.len &&is_mail(fp)) { 624 ret = PATCH_FORMAT_MBOX; 625goto done; 626} 627 628done: 629fclose(fp); 630strbuf_release(&l1); 631strbuf_release(&l2); 632strbuf_release(&l3); 633return ret; 634} 635 636/** 637 * Splits out individual email patches from `paths`, where each path is either 638 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 639 */ 640static intsplit_mail_mbox(struct am_state *state,const char**paths, 641int keep_cr,int mboxrd) 642{ 643struct child_process cp = CHILD_PROCESS_INIT; 644struct strbuf last = STRBUF_INIT; 645int ret; 646 647 cp.git_cmd =1; 648argv_array_push(&cp.args,"mailsplit"); 649argv_array_pushf(&cp.args,"-d%d", state->prec); 650argv_array_pushf(&cp.args,"-o%s", state->dir); 651argv_array_push(&cp.args,"-b"); 652if(keep_cr) 653argv_array_push(&cp.args,"--keep-cr"); 654if(mboxrd) 655argv_array_push(&cp.args,"--mboxrd"); 656argv_array_push(&cp.args,"--"); 657argv_array_pushv(&cp.args, paths); 658 659 ret =capture_command(&cp, &last,8); 660if(ret) 661goto exit; 662 663 state->cur =1; 664 state->last =strtol(last.buf, NULL,10); 665 666exit: 667strbuf_release(&last); 668return ret ? -1:0; 669} 670 671/** 672 * Callback signature for split_mail_conv(). The foreign patch should be 673 * read from `in`, and the converted patch (in RFC2822 mail format) should be 674 * written to `out`. Return 0 on success, or -1 on failure. 675 */ 676typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 677 678/** 679 * Calls `fn` for each file in `paths` to convert the foreign patch to the 680 * RFC2822 mail format suitable for parsing with git-mailinfo. 681 * 682 * Returns 0 on success, -1 on failure. 683 */ 684static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 685const char**paths,int keep_cr) 686{ 687static const char*stdin_only[] = {"-", NULL}; 688int i; 689 690if(!*paths) 691 paths = stdin_only; 692 693for(i =0; *paths; paths++, i++) { 694FILE*in, *out; 695const char*mail; 696int ret; 697 698if(!strcmp(*paths,"-")) 699 in = stdin; 700else 701 in =fopen(*paths,"r"); 702 703if(!in) 704returnerror_errno(_("could not open '%s' for reading"), 705*paths); 706 707 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 708 709 out =fopen(mail,"w"); 710if(!out) { 711if(in != stdin) 712fclose(in); 713returnerror_errno(_("could not open '%s' for writing"), 714 mail); 715} 716 717 ret =fn(out, in, keep_cr); 718 719fclose(out); 720if(in != stdin) 721fclose(in); 722 723if(ret) 724returnerror(_("could not parse patch '%s'"), *paths); 725} 726 727 state->cur =1; 728 state->last = i; 729return0; 730} 731 732/** 733 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 734 * message suitable for parsing with git-mailinfo. 735 */ 736static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 737{ 738struct strbuf sb = STRBUF_INIT; 739int subject_printed =0; 740 741while(!strbuf_getline_lf(&sb, in)) { 742const char*str; 743 744if(str_isspace(sb.buf)) 745continue; 746else if(skip_prefix(sb.buf,"Author:", &str)) 747fprintf(out,"From:%s\n", str); 748else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 749fprintf(out,"%s\n", sb.buf); 750else if(!subject_printed) { 751fprintf(out,"Subject:%s\n", sb.buf); 752 subject_printed =1; 753}else{ 754fprintf(out,"\n%s\n", sb.buf); 755break; 756} 757} 758 759strbuf_reset(&sb); 760while(strbuf_fread(&sb,8192, in) >0) { 761fwrite(sb.buf,1, sb.len, out); 762strbuf_reset(&sb); 763} 764 765strbuf_release(&sb); 766return0; 767} 768 769/** 770 * This function only supports a single StGit series file in `paths`. 771 * 772 * Given an StGit series file, converts the StGit patches in the series into 773 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 774 * the state directory. 775 * 776 * Returns 0 on success, -1 on failure. 777 */ 778static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 779int keep_cr) 780{ 781const char*series_dir; 782char*series_dir_buf; 783FILE*fp; 784struct argv_array patches = ARGV_ARRAY_INIT; 785struct strbuf sb = STRBUF_INIT; 786int ret; 787 788if(!paths[0] || paths[1]) 789returnerror(_("Only one StGIT patch series can be applied at once")); 790 791 series_dir_buf =xstrdup(*paths); 792 series_dir =dirname(series_dir_buf); 793 794 fp =fopen(*paths,"r"); 795if(!fp) 796returnerror_errno(_("could not open '%s' for reading"), *paths); 797 798while(!strbuf_getline_lf(&sb, fp)) { 799if(*sb.buf =='#') 800continue;/* skip comment lines */ 801 802argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 803} 804 805fclose(fp); 806strbuf_release(&sb); 807free(series_dir_buf); 808 809 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 810 811argv_array_clear(&patches); 812return ret; 813} 814 815/** 816 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 817 * message suitable for parsing with git-mailinfo. 818 */ 819static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 820{ 821struct strbuf sb = STRBUF_INIT; 822int rc =0; 823 824while(!strbuf_getline_lf(&sb, in)) { 825const char*str; 826 827if(skip_prefix(sb.buf,"# User ", &str)) 828fprintf(out,"From:%s\n", str); 829else if(skip_prefix(sb.buf,"# Date ", &str)) { 830 timestamp_t timestamp; 831long tz, tz2; 832char*end; 833 834 errno =0; 835 timestamp =parse_timestamp(str, &end,10); 836if(errno) { 837 rc =error(_("invalid timestamp")); 838goto exit; 839} 840 841if(!skip_prefix(end," ", &str)) { 842 rc =error(_("invalid Date line")); 843goto exit; 844} 845 846 errno =0; 847 tz =strtol(str, &end,10); 848if(errno) { 849 rc =error(_("invalid timezone offset")); 850goto exit; 851} 852 853if(*end) { 854 rc =error(_("invalid Date line")); 855goto exit; 856} 857 858/* 859 * mercurial's timezone is in seconds west of UTC, 860 * however git's timezone is in hours + minutes east of 861 * UTC. Convert it. 862 */ 863 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 864if(tz >0) 865 tz2 = -tz2; 866 867fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 868}else if(starts_with(sb.buf,"# ")) { 869continue; 870}else{ 871fprintf(out,"\n%s\n", sb.buf); 872break; 873} 874} 875 876strbuf_reset(&sb); 877while(strbuf_fread(&sb,8192, in) >0) { 878fwrite(sb.buf,1, sb.len, out); 879strbuf_reset(&sb); 880} 881exit: 882strbuf_release(&sb); 883return rc; 884} 885 886/** 887 * Splits a list of files/directories into individual email patches. Each path 888 * in `paths` must be a file/directory that is formatted according to 889 * `patch_format`. 890 * 891 * Once split out, the individual email patches will be stored in the state 892 * directory, with each patch's filename being its index, padded to state->prec 893 * digits. 894 * 895 * state->cur will be set to the index of the first mail, and state->last will 896 * be set to the index of the last mail. 897 * 898 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 899 * to disable this behavior, -1 to use the default configured setting. 900 * 901 * Returns 0 on success, -1 on failure. 902 */ 903static intsplit_mail(struct am_state *state,enum patch_format patch_format, 904const char**paths,int keep_cr) 905{ 906if(keep_cr <0) { 907 keep_cr =0; 908git_config_get_bool("am.keepcr", &keep_cr); 909} 910 911switch(patch_format) { 912case PATCH_FORMAT_MBOX: 913returnsplit_mail_mbox(state, paths, keep_cr,0); 914case PATCH_FORMAT_STGIT: 915returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 916case PATCH_FORMAT_STGIT_SERIES: 917returnsplit_mail_stgit_series(state, paths, keep_cr); 918case PATCH_FORMAT_HG: 919returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 920case PATCH_FORMAT_MBOXRD: 921returnsplit_mail_mbox(state, paths, keep_cr,1); 922default: 923BUG("invalid patch_format"); 924} 925return-1; 926} 927 928/** 929 * Setup a new am session for applying patches 930 */ 931static voidam_setup(struct am_state *state,enum patch_format patch_format, 932const char**paths,int keep_cr) 933{ 934struct object_id curr_head; 935const char*str; 936struct strbuf sb = STRBUF_INIT; 937 938if(!patch_format) 939 patch_format =detect_patch_format(paths); 940 941if(!patch_format) { 942fprintf_ln(stderr,_("Patch format detection failed.")); 943exit(128); 944} 945 946if(mkdir(state->dir,0777) <0&& errno != EEXIST) 947die_errno(_("failed to create directory '%s'"), state->dir); 948delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF); 949 950if(split_mail(state, patch_format, paths, keep_cr) <0) { 951am_destroy(state); 952die(_("Failed to split patches.")); 953} 954 955if(state->rebasing) 956 state->threeway =1; 957 958write_state_bool(state,"threeway", state->threeway); 959write_state_bool(state,"quiet", state->quiet); 960write_state_bool(state,"sign", state->signoff); 961write_state_bool(state,"utf8", state->utf8); 962 963if(state->allow_rerere_autoupdate) 964write_state_bool(state,"rerere-autoupdate", 965 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE); 966 967switch(state->keep) { 968case KEEP_FALSE: 969 str ="f"; 970break; 971case KEEP_TRUE: 972 str ="t"; 973break; 974case KEEP_NON_PATCH: 975 str ="b"; 976break; 977default: 978BUG("invalid value for state->keep"); 979} 980 981write_state_text(state,"keep", str); 982write_state_bool(state,"messageid", state->message_id); 983 984switch(state->scissors) { 985case SCISSORS_UNSET: 986 str =""; 987break; 988case SCISSORS_FALSE: 989 str ="f"; 990break; 991case SCISSORS_TRUE: 992 str ="t"; 993break; 994default: 995BUG("invalid value for state->scissors"); 996} 997write_state_text(state,"scissors", str); 998 999sq_quote_argv(&sb, state->git_apply_opts.argv);1000write_state_text(state,"apply-opt", sb.buf);10011002if(state->rebasing)1003write_state_text(state,"rebasing","");1004else1005write_state_text(state,"applying","");10061007if(!get_oid("HEAD", &curr_head)) {1008write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1009if(!state->rebasing)1010update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1011 UPDATE_REFS_DIE_ON_ERR);1012}else{1013write_state_text(state,"abort-safety","");1014if(!state->rebasing)1015delete_ref(NULL,"ORIG_HEAD", NULL,0);1016}10171018/*1019 * NOTE: Since the "next" and "last" files determine if an am_state1020 * session is in progress, they should be written last.1021 */10221023write_state_count(state,"next", state->cur);1024write_state_count(state,"last", state->last);10251026strbuf_release(&sb);1027}10281029/**1030 * Increments the patch pointer, and cleans am_state for the application of the1031 * next patch.1032 */1033static voidam_next(struct am_state *state)1034{1035struct object_id head;10361037FREE_AND_NULL(state->author_name);1038FREE_AND_NULL(state->author_email);1039FREE_AND_NULL(state->author_date);1040FREE_AND_NULL(state->msg);1041 state->msg_len =0;10421043unlink(am_path(state,"author-script"));1044unlink(am_path(state,"final-commit"));10451046oidclr(&state->orig_commit);1047unlink(am_path(state,"original-commit"));1048delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10491050if(!get_oid("HEAD", &head))1051write_state_text(state,"abort-safety",oid_to_hex(&head));1052else1053write_state_text(state,"abort-safety","");10541055 state->cur++;1056write_state_count(state,"next", state->cur);1057}10581059/**1060 * Returns the filename of the current patch email.1061 */1062static const char*msgnum(const struct am_state *state)1063{1064static struct strbuf sb = STRBUF_INIT;10651066strbuf_reset(&sb);1067strbuf_addf(&sb,"%0*d", state->prec, state->cur);10681069return sb.buf;1070}10711072/**1073 * Refresh and write index.1074 */1075static voidrefresh_and_write_cache(void)1076{1077struct lock_file lock_file = LOCK_INIT;10781079hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1080refresh_cache(REFRESH_QUIET);1081if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1082die(_("unable to write index file"));1083}10841085/**1086 * Dies with a user-friendly message on how to proceed after resolving the1087 * problem. This message can be overridden with state->resolvemsg.1088 */1089static void NORETURN die_user_resolve(const struct am_state *state)1090{1091if(state->resolvemsg) {1092printf_ln("%s", state->resolvemsg);1093}else{1094const char*cmdline = state->interactive ?"git am -i":"git am";10951096printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1097printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1098printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1099}11001101exit(128);1102}11031104/**1105 * Appends signoff to the "msg" field of the am_state.1106 */1107static voidam_append_signoff(struct am_state *state)1108{1109struct strbuf sb = STRBUF_INIT;11101111strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1112append_signoff(&sb,0,0);1113 state->msg =strbuf_detach(&sb, &state->msg_len);1114}11151116/**1117 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1118 * state->msg will be set to the patch message. state->author_name,1119 * state->author_email and state->author_date will be set to the patch author's1120 * name, email and date respectively. The patch body will be written to the1121 * state directory's "patch" file.1122 *1123 * Returns 1 if the patch should be skipped, 0 otherwise.1124 */1125static intparse_mail(struct am_state *state,const char*mail)1126{1127FILE*fp;1128struct strbuf sb = STRBUF_INIT;1129struct strbuf msg = STRBUF_INIT;1130struct strbuf author_name = STRBUF_INIT;1131struct strbuf author_date = STRBUF_INIT;1132struct strbuf author_email = STRBUF_INIT;1133int ret =0;1134struct mailinfo mi;11351136setup_mailinfo(&mi);11371138if(state->utf8)1139 mi.metainfo_charset =get_commit_output_encoding();1140else1141 mi.metainfo_charset = NULL;11421143switch(state->keep) {1144case KEEP_FALSE:1145break;1146case KEEP_TRUE:1147 mi.keep_subject =1;1148break;1149case KEEP_NON_PATCH:1150 mi.keep_non_patch_brackets_in_subject =1;1151break;1152default:1153BUG("invalid value for state->keep");1154}11551156if(state->message_id)1157 mi.add_message_id =1;11581159switch(state->scissors) {1160case SCISSORS_UNSET:1161break;1162case SCISSORS_FALSE:1163 mi.use_scissors =0;1164break;1165case SCISSORS_TRUE:1166 mi.use_scissors =1;1167break;1168default:1169BUG("invalid value for state->scissors");1170}11711172 mi.input =xfopen(mail,"r");1173 mi.output =xfopen(am_path(state,"info"),"w");1174if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1175die("could not parse patch");11761177fclose(mi.input);1178fclose(mi.output);11791180if(mi.format_flowed)1181warning(_("Patch sent with format=flowed; "1182"space at the end of lines might be lost."));11831184/* Extract message and author information */1185 fp =xfopen(am_path(state,"info"),"r");1186while(!strbuf_getline_lf(&sb, fp)) {1187const char*x;11881189if(skip_prefix(sb.buf,"Subject: ", &x)) {1190if(msg.len)1191strbuf_addch(&msg,'\n');1192strbuf_addstr(&msg, x);1193}else if(skip_prefix(sb.buf,"Author: ", &x))1194strbuf_addstr(&author_name, x);1195else if(skip_prefix(sb.buf,"Email: ", &x))1196strbuf_addstr(&author_email, x);1197else if(skip_prefix(sb.buf,"Date: ", &x))1198strbuf_addstr(&author_date, x);1199}1200fclose(fp);12011202/* Skip pine's internal folder data */1203if(!strcmp(author_name.buf,"Mail System Internal Data")) {1204 ret =1;1205goto finish;1206}12071208if(is_empty_or_missing_file(am_path(state,"patch"))) {1209printf_ln(_("Patch is empty."));1210die_user_resolve(state);1211}12121213strbuf_addstr(&msg,"\n\n");1214strbuf_addbuf(&msg, &mi.log_message);1215strbuf_stripspace(&msg,0);12161217assert(!state->author_name);1218 state->author_name =strbuf_detach(&author_name, NULL);12191220assert(!state->author_email);1221 state->author_email =strbuf_detach(&author_email, NULL);12221223assert(!state->author_date);1224 state->author_date =strbuf_detach(&author_date, NULL);12251226assert(!state->msg);1227 state->msg =strbuf_detach(&msg, &state->msg_len);12281229finish:1230strbuf_release(&msg);1231strbuf_release(&author_date);1232strbuf_release(&author_email);1233strbuf_release(&author_name);1234strbuf_release(&sb);1235clear_mailinfo(&mi);1236return ret;1237}12381239/**1240 * Sets commit_id to the commit hash where the mail was generated from.1241 * Returns 0 on success, -1 on failure.1242 */1243static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1244{1245struct strbuf sb = STRBUF_INIT;1246FILE*fp =xfopen(mail,"r");1247const char*x;1248int ret =0;12491250if(strbuf_getline_lf(&sb, fp) ||1251!skip_prefix(sb.buf,"From ", &x) ||1252get_oid_hex(x, commit_id) <0)1253 ret = -1;12541255strbuf_release(&sb);1256fclose(fp);1257return ret;1258}12591260/**1261 * Sets state->msg, state->author_name, state->author_email, state->author_date1262 * to the commit's respective info.1263 */1264static voidget_commit_info(struct am_state *state,struct commit *commit)1265{1266const char*buffer, *ident_line, *msg;1267size_t ident_len;1268struct ident_split id;12691270 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());12711272 ident_line =find_commit_header(buffer,"author", &ident_len);12731274if(split_ident_line(&id, ident_line, ident_len) <0)1275die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12761277assert(!state->author_name);1278if(id.name_begin)1279 state->author_name =1280xmemdupz(id.name_begin, id.name_end - id.name_begin);1281else1282 state->author_name =xstrdup("");12831284assert(!state->author_email);1285if(id.mail_begin)1286 state->author_email =1287xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1288else1289 state->author_email =xstrdup("");12901291assert(!state->author_date);1292 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));12931294assert(!state->msg);1295 msg =strstr(buffer,"\n\n");1296if(!msg)1297die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1298 state->msg =xstrdup(msg +2);1299 state->msg_len =strlen(state->msg);1300unuse_commit_buffer(commit, buffer);1301}13021303/**1304 * Writes `commit` as a patch to the state directory's "patch" file.1305 */1306static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1307{1308struct rev_info rev_info;1309FILE*fp;13101311 fp =xfopen(am_path(state,"patch"),"w");1312repo_init_revisions(the_repository, &rev_info, NULL);1313 rev_info.diff =1;1314 rev_info.abbrev =0;1315 rev_info.disable_stdin =1;1316 rev_info.show_root_diff =1;1317 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1318 rev_info.no_commit_id =1;1319 rev_info.diffopt.flags.binary =1;1320 rev_info.diffopt.flags.full_index =1;1321 rev_info.diffopt.use_color =0;1322 rev_info.diffopt.file = fp;1323 rev_info.diffopt.close_file =1;1324add_pending_object(&rev_info, &commit->object,"");1325diff_setup_done(&rev_info.diffopt);1326log_tree_commit(&rev_info, commit);1327}13281329/**1330 * Writes the diff of the index against HEAD as a patch to the state1331 * directory's "patch" file.1332 */1333static voidwrite_index_patch(const struct am_state *state)1334{1335struct tree *tree;1336struct object_id head;1337struct rev_info rev_info;1338FILE*fp;13391340if(!get_oid_tree("HEAD", &head))1341 tree =lookup_tree(the_repository, &head);1342else1343 tree =lookup_tree(the_repository,1344 the_repository->hash_algo->empty_tree);13451346 fp =xfopen(am_path(state,"patch"),"w");1347repo_init_revisions(the_repository, &rev_info, NULL);1348 rev_info.diff =1;1349 rev_info.disable_stdin =1;1350 rev_info.no_commit_id =1;1351 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1352 rev_info.diffopt.use_color =0;1353 rev_info.diffopt.file = fp;1354 rev_info.diffopt.close_file =1;1355add_pending_object(&rev_info, &tree->object,"");1356diff_setup_done(&rev_info.diffopt);1357run_diff_index(&rev_info,1);1358}13591360/**1361 * Like parse_mail(), but parses the mail by looking up its commit ID1362 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1363 * of patches.1364 *1365 * state->orig_commit will be set to the original commit ID.1366 *1367 * Will always return 0 as the patch should never be skipped.1368 */1369static intparse_mail_rebase(struct am_state *state,const char*mail)1370{1371struct commit *commit;1372struct object_id commit_oid;13731374if(get_mail_commit_oid(&commit_oid, mail) <0)1375die(_("could not parse%s"), mail);13761377 commit =lookup_commit_or_die(&commit_oid, mail);13781379get_commit_info(state, commit);13801381write_commit_patch(state, commit);13821383oidcpy(&state->orig_commit, &commit_oid);1384write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1385update_ref("am","REBASE_HEAD", &commit_oid,1386 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);13871388return0;1389}13901391/**1392 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1393 * `index_file` is not NULL, the patch will be applied to that index.1394 */1395static intrun_apply(const struct am_state *state,const char*index_file)1396{1397struct argv_array apply_paths = ARGV_ARRAY_INIT;1398struct argv_array apply_opts = ARGV_ARRAY_INIT;1399struct apply_state apply_state;1400int res, opts_left;1401int force_apply =0;1402int options =0;14031404if(init_apply_state(&apply_state, the_repository, NULL))1405BUG("init_apply_state() failed");14061407argv_array_push(&apply_opts,"apply");1408argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14091410 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1411&apply_state, &force_apply, &options,1412 NULL);14131414if(opts_left !=0)1415die("unknown option passed through to git apply");14161417if(index_file) {1418 apply_state.index_file = index_file;1419 apply_state.cached =1;1420}else1421 apply_state.check_index =1;14221423/*1424 * If we are allowed to fall back on 3-way merge, don't give false1425 * errors during the initial attempt.1426 */1427if(state->threeway && !index_file)1428 apply_state.apply_verbosity = verbosity_silent;14291430if(check_apply_state(&apply_state, force_apply))1431BUG("check_apply_state() failed");14321433argv_array_push(&apply_paths,am_path(state,"patch"));14341435 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14361437argv_array_clear(&apply_paths);1438argv_array_clear(&apply_opts);1439clear_apply_state(&apply_state);14401441if(res)1442return res;14431444if(index_file) {1445/* Reload index as apply_all_patches() will have modified it. */1446discard_cache();1447read_cache_from(index_file);1448}14491450return0;1451}14521453/**1454 * Builds an index that contains just the blobs needed for a 3way merge.1455 */1456static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1457{1458struct child_process cp = CHILD_PROCESS_INIT;14591460 cp.git_cmd =1;1461argv_array_push(&cp.args,"apply");1462argv_array_pushv(&cp.args, state->git_apply_opts.argv);1463argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1464argv_array_push(&cp.args,am_path(state,"patch"));14651466if(run_command(&cp))1467return-1;14681469return0;1470}14711472/**1473 * Attempt a threeway merge, using index_path as the temporary index.1474 */1475static intfall_back_threeway(const struct am_state *state,const char*index_path)1476{1477struct object_id orig_tree, their_tree, our_tree;1478const struct object_id *bases[1] = { &orig_tree };1479struct merge_options o;1480struct commit *result;1481char*their_tree_name;14821483if(get_oid("HEAD", &our_tree) <0)1484oidcpy(&our_tree, the_hash_algo->empty_tree);14851486if(build_fake_ancestor(state, index_path))1487returnerror("could not build fake ancestor");14881489discard_cache();1490read_cache_from(index_path);14911492if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1493returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));14941495say(state, stdout,_("Using index info to reconstruct a base tree..."));14961497if(!state->quiet) {1498/*1499 * List paths that needed 3-way fallback, so that the user can1500 * review them with extra care to spot mismerges.1501 */1502struct rev_info rev_info;1503const char*diff_filter_str ="--diff-filter=AM";15041505repo_init_revisions(the_repository, &rev_info, NULL);1506 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1507diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1508add_pending_oid(&rev_info,"HEAD", &our_tree,0);1509diff_setup_done(&rev_info.diffopt);1510run_diff_index(&rev_info,1);1511}15121513if(run_apply(state, index_path))1514returnerror(_("Did you hand edit your patch?\n"1515"It does not apply to blobs recorded in its index."));15161517if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1518returnerror("could not write tree");15191520say(state, stdout,_("Falling back to patching base and 3-way merge..."));15211522discard_cache();1523read_cache();15241525/*1526 * This is not so wrong. Depending on which base we picked, orig_tree1527 * may be wildly different from ours, but their_tree has the same set of1528 * wildly different changes in parts the patch did not touch, so1529 * recursive ends up canceling them, saying that we reverted all those1530 * changes.1531 */15321533init_merge_options(&o, the_repository);15341535 o.branch1 ="HEAD";1536 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1537 o.branch2 = their_tree_name;1538 o.detect_directory_renames =0;15391540if(state->quiet)1541 o.verbosity =0;15421543if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1544repo_rerere(the_repository, state->allow_rerere_autoupdate);1545free(their_tree_name);1546returnerror(_("Failed to merge in the changes."));1547}15481549free(their_tree_name);1550return0;1551}15521553/**1554 * Commits the current index with state->msg as the commit message and1555 * state->author_name, state->author_email and state->author_date as the author1556 * information.1557 */1558static voiddo_commit(const struct am_state *state)1559{1560struct object_id tree, parent, commit;1561const struct object_id *old_oid;1562struct commit_list *parents = NULL;1563const char*reflog_msg, *author;1564struct strbuf sb = STRBUF_INIT;15651566if(run_hook_le(NULL,"pre-applypatch", NULL))1567exit(1);15681569if(write_cache_as_tree(&tree,0, NULL))1570die(_("git write-tree failed to write a tree"));15711572if(!get_oid_commit("HEAD", &parent)) {1573 old_oid = &parent;1574commit_list_insert(lookup_commit(the_repository, &parent),1575&parents);1576}else{1577 old_oid = NULL;1578say(state, stderr,_("applying to an empty history"));1579}15801581 author =fmt_ident(state->author_name, state->author_email,1582 state->ignore_date ? NULL : state->author_date,1583 IDENT_STRICT);15841585if(state->committer_date_is_author_date)1586setenv("GIT_COMMITTER_DATE",1587 state->ignore_date ?"": state->author_date,1);15881589if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1590 author, state->sign_commit))1591die(_("failed to write commit object"));15921593 reflog_msg =getenv("GIT_REFLOG_ACTION");1594if(!reflog_msg)1595 reflog_msg ="am";15961597strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1598 state->msg);15991600update_ref(sb.buf,"HEAD", &commit, old_oid,0,1601 UPDATE_REFS_DIE_ON_ERR);16021603if(state->rebasing) {1604FILE*fp =xfopen(am_path(state,"rewritten"),"a");16051606assert(!is_null_oid(&state->orig_commit));1607fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1608fprintf(fp,"%s\n",oid_to_hex(&commit));1609fclose(fp);1610}16111612run_hook_le(NULL,"post-applypatch", NULL);16131614strbuf_release(&sb);1615}16161617/**1618 * Validates the am_state for resuming -- the "msg" and authorship fields must1619 * be filled up.1620 */1621static voidvalidate_resume_state(const struct am_state *state)1622{1623if(!state->msg)1624die(_("cannot resume:%sdoes not exist."),1625am_path(state,"final-commit"));16261627if(!state->author_name || !state->author_email || !state->author_date)1628die(_("cannot resume:%sdoes not exist."),1629am_path(state,"author-script"));1630}16311632/**1633 * Interactively prompt the user on whether the current patch should be1634 * applied.1635 *1636 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1637 * skip it.1638 */1639static intdo_interactive(struct am_state *state)1640{1641assert(state->msg);16421643if(!isatty(0))1644die(_("cannot be interactive without stdin connected to a terminal."));16451646for(;;) {1647const char*reply;16481649puts(_("Commit Body is:"));1650puts("--------------------------");1651printf("%s", state->msg);1652puts("--------------------------");16531654/*1655 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1656 * in your translation. The program will only accept English1657 * input at this point.1658 */1659 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);16601661if(!reply) {1662continue;1663}else if(*reply =='y'|| *reply =='Y') {1664return0;1665}else if(*reply =='a'|| *reply =='A') {1666 state->interactive =0;1667return0;1668}else if(*reply =='n'|| *reply =='N') {1669return1;1670}else if(*reply =='e'|| *reply =='E') {1671struct strbuf msg = STRBUF_INIT;16721673if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1674free(state->msg);1675 state->msg =strbuf_detach(&msg, &state->msg_len);1676}1677strbuf_release(&msg);1678}else if(*reply =='v'|| *reply =='V') {1679const char*pager =git_pager(1);1680struct child_process cp = CHILD_PROCESS_INIT;16811682if(!pager)1683 pager ="cat";1684prepare_pager_args(&cp, pager);1685argv_array_push(&cp.args,am_path(state,"patch"));1686run_command(&cp);1687}1688}1689}16901691/**1692 * Applies all queued mail.1693 *1694 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1695 * well as the state directory's "patch" file is used as-is for applying the1696 * patch and committing it.1697 */1698static voidam_run(struct am_state *state,int resume)1699{1700const char*argv_gc_auto[] = {"gc","--auto", NULL};1701struct strbuf sb = STRBUF_INIT;17021703unlink(am_path(state,"dirtyindex"));17041705refresh_and_write_cache();17061707if(repo_index_has_changes(the_repository, NULL, &sb)) {1708write_state_bool(state,"dirtyindex",1);1709die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1710}17111712strbuf_release(&sb);17131714while(state->cur <= state->last) {1715const char*mail =am_path(state,msgnum(state));1716int apply_status;17171718reset_ident_date();17191720if(!file_exists(mail))1721goto next;17221723if(resume) {1724validate_resume_state(state);1725}else{1726int skip;17271728if(state->rebasing)1729 skip =parse_mail_rebase(state, mail);1730else1731 skip =parse_mail(state, mail);17321733if(skip)1734goto next;/* mail should be skipped */17351736if(state->signoff)1737am_append_signoff(state);17381739write_author_script(state);1740write_commit_msg(state);1741}17421743if(state->interactive &&do_interactive(state))1744goto next;17451746if(run_applypatch_msg_hook(state))1747exit(1);17481749say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17501751 apply_status =run_apply(state, NULL);17521753if(apply_status && state->threeway) {1754struct strbuf sb = STRBUF_INIT;17551756strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1757 apply_status =fall_back_threeway(state, sb.buf);1758strbuf_release(&sb);17591760/*1761 * Applying the patch to an earlier tree and merging1762 * the result may have produced the same tree as ours.1763 */1764if(!apply_status &&1765!repo_index_has_changes(the_repository, NULL, NULL)) {1766say(state, stdout,_("No changes -- Patch already applied."));1767goto next;1768}1769}17701771if(apply_status) {1772printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1773linelen(state->msg), state->msg);17741775if(advice_amworkdir)1776advise(_("Use 'git am --show-current-patch' to see the failed patch"));17771778die_user_resolve(state);1779}17801781do_commit(state);17821783next:1784am_next(state);17851786if(resume)1787am_load(state);1788 resume =0;1789}17901791if(!is_empty_or_missing_file(am_path(state,"rewritten"))) {1792assert(state->rebasing);1793copy_notes_for_rebase(state);1794run_post_rewrite_hook(state);1795}17961797/*1798 * In rebasing mode, it's up to the caller to take care of1799 * housekeeping.1800 */1801if(!state->rebasing) {1802am_destroy(state);1803close_all_packs(the_repository->objects);1804run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1805}1806}18071808/**1809 * Resume the current am session after patch application failure. The user did1810 * all the hard work, and we do not have to do any patch application. Just1811 * trust and commit what the user has in the index and working tree.1812 */1813static voidam_resolve(struct am_state *state)1814{1815validate_resume_state(state);18161817say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18181819if(!repo_index_has_changes(the_repository, NULL, NULL)) {1820printf_ln(_("No changes - did you forget to use 'git add'?\n"1821"If there is nothing left to stage, chances are that something else\n"1822"already introduced the same changes; you might want to skip this patch."));1823die_user_resolve(state);1824}18251826if(unmerged_cache()) {1827printf_ln(_("You still have unmerged paths in your index.\n"1828"You should 'git add' each file with resolved conflicts to mark them as such.\n"1829"You might run `git rm` on a file to accept\"deleted by them\"for it."));1830die_user_resolve(state);1831}18321833if(state->interactive) {1834write_index_patch(state);1835if(do_interactive(state))1836goto next;1837}18381839repo_rerere(the_repository,0);18401841do_commit(state);18421843next:1844am_next(state);1845am_load(state);1846am_run(state,0);1847}18481849/**1850 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1851 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1852 * failure.1853 */1854static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1855{1856struct lock_file lock_file = LOCK_INIT;1857struct unpack_trees_options opts;1858struct tree_desc t[2];18591860if(parse_tree(head) ||parse_tree(remote))1861return-1;18621863hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18641865refresh_cache(REFRESH_QUIET);18661867memset(&opts,0,sizeof(opts));1868 opts.head_idx =1;1869 opts.src_index = &the_index;1870 opts.dst_index = &the_index;1871 opts.update =1;1872 opts.merge =1;1873 opts.reset = reset;1874 opts.fn = twoway_merge;1875init_tree_desc(&t[0], head->buffer, head->size);1876init_tree_desc(&t[1], remote->buffer, remote->size);18771878if(unpack_trees(2, t, &opts)) {1879rollback_lock_file(&lock_file);1880return-1;1881}18821883if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1884die(_("unable to write new index file"));18851886return0;1887}18881889/**1890 * Merges a tree into the index. The index's stat info will take precedence1891 * over the merged tree's. Returns 0 on success, -1 on failure.1892 */1893static intmerge_tree(struct tree *tree)1894{1895struct lock_file lock_file = LOCK_INIT;1896struct unpack_trees_options opts;1897struct tree_desc t[1];18981899if(parse_tree(tree))1900return-1;19011902hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19031904memset(&opts,0,sizeof(opts));1905 opts.head_idx =1;1906 opts.src_index = &the_index;1907 opts.dst_index = &the_index;1908 opts.merge =1;1909 opts.fn = oneway_merge;1910init_tree_desc(&t[0], tree->buffer, tree->size);19111912if(unpack_trees(1, t, &opts)) {1913rollback_lock_file(&lock_file);1914return-1;1915}19161917if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1918die(_("unable to write new index file"));19191920return0;1921}19221923/**1924 * Clean the index without touching entries that are not modified between1925 * `head` and `remote`.1926 */1927static intclean_index(const struct object_id *head,const struct object_id *remote)1928{1929struct tree *head_tree, *remote_tree, *index_tree;1930struct object_id index;19311932 head_tree =parse_tree_indirect(head);1933if(!head_tree)1934returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19351936 remote_tree =parse_tree_indirect(remote);1937if(!remote_tree)1938returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19391940read_cache_unmerged();19411942if(fast_forward_to(head_tree, head_tree,1))1943return-1;19441945if(write_cache_as_tree(&index,0, NULL))1946return-1;19471948 index_tree =parse_tree_indirect(&index);1949if(!index_tree)1950returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19511952if(fast_forward_to(index_tree, remote_tree,0))1953return-1;19541955if(merge_tree(remote_tree))1956return-1;19571958remove_branch_state(the_repository);19591960return0;1961}19621963/**1964 * Resets rerere's merge resolution metadata.1965 */1966static voidam_rerere_clear(void)1967{1968struct string_list merge_rr = STRING_LIST_INIT_DUP;1969rerere_clear(the_repository, &merge_rr);1970string_list_clear(&merge_rr,1);1971}19721973/**1974 * Resume the current am session by skipping the current patch.1975 */1976static voidam_skip(struct am_state *state)1977{1978struct object_id head;19791980am_rerere_clear();19811982if(get_oid("HEAD", &head))1983oidcpy(&head, the_hash_algo->empty_tree);19841985if(clean_index(&head, &head))1986die(_("failed to clean index"));19871988if(state->rebasing) {1989FILE*fp =xfopen(am_path(state,"rewritten"),"a");19901991assert(!is_null_oid(&state->orig_commit));1992fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1993fprintf(fp,"%s\n",oid_to_hex(&head));1994fclose(fp);1995}19961997am_next(state);1998am_load(state);1999am_run(state,0);2000}20012002/**2003 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2004 *2005 * It is not safe to reset HEAD when:2006 * 1. git-am previously failed because the index was dirty.2007 * 2. HEAD has moved since git-am previously failed.2008 */2009static intsafe_to_abort(const struct am_state *state)2010{2011struct strbuf sb = STRBUF_INIT;2012struct object_id abort_safety, head;20132014if(file_exists(am_path(state,"dirtyindex")))2015return0;20162017if(read_state_file(&sb, state,"abort-safety",1) >0) {2018if(get_oid_hex(sb.buf, &abort_safety))2019die(_("could not parse%s"),am_path(state,"abort-safety"));2020}else2021oidclr(&abort_safety);2022strbuf_release(&sb);20232024if(get_oid("HEAD", &head))2025oidclr(&head);20262027if(oideq(&head, &abort_safety))2028return1;20292030warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2031"Not rewinding to ORIG_HEAD"));20322033return0;2034}20352036/**2037 * Aborts the current am session if it is safe to do so.2038 */2039static voidam_abort(struct am_state *state)2040{2041struct object_id curr_head, orig_head;2042int has_curr_head, has_orig_head;2043char*curr_branch;20442045if(!safe_to_abort(state)) {2046am_destroy(state);2047return;2048}20492050am_rerere_clear();20512052 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2053 has_curr_head = curr_branch && !is_null_oid(&curr_head);2054if(!has_curr_head)2055oidcpy(&curr_head, the_hash_algo->empty_tree);20562057 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2058if(!has_orig_head)2059oidcpy(&orig_head, the_hash_algo->empty_tree);20602061clean_index(&curr_head, &orig_head);20622063if(has_orig_head)2064update_ref("am --abort","HEAD", &orig_head,2065 has_curr_head ? &curr_head : NULL,0,2066 UPDATE_REFS_DIE_ON_ERR);2067else if(curr_branch)2068delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20692070free(curr_branch);2071am_destroy(state);2072}20732074static intshow_patch(struct am_state *state)2075{2076struct strbuf sb = STRBUF_INIT;2077const char*patch_path;2078int len;20792080if(!is_null_oid(&state->orig_commit)) {2081const char*av[4] = {"show", NULL,"--", NULL };2082char*new_oid_str;2083int ret;20842085 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2086 ret =run_command_v_opt(av, RUN_GIT_CMD);2087free(new_oid_str);2088return ret;2089}20902091 patch_path =am_path(state,msgnum(state));2092 len =strbuf_read_file(&sb, patch_path,0);2093if(len <0)2094die_errno(_("failed to read '%s'"), patch_path);20952096setup_pager();2097write_in_full(1, sb.buf, sb.len);2098strbuf_release(&sb);2099return0;2100}21012102/**2103 * parse_options() callback that validates and sets opt->value to the2104 * PATCH_FORMAT_* enum value corresponding to `arg`.2105 */2106static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2107{2108int*opt_value = opt->value;21092110if(unset)2111*opt_value = PATCH_FORMAT_UNKNOWN;2112else if(!strcmp(arg,"mbox"))2113*opt_value = PATCH_FORMAT_MBOX;2114else if(!strcmp(arg,"stgit"))2115*opt_value = PATCH_FORMAT_STGIT;2116else if(!strcmp(arg,"stgit-series"))2117*opt_value = PATCH_FORMAT_STGIT_SERIES;2118else if(!strcmp(arg,"hg"))2119*opt_value = PATCH_FORMAT_HG;2120else if(!strcmp(arg,"mboxrd"))2121*opt_value = PATCH_FORMAT_MBOXRD;2122else2123returnerror(_("Invalid value for --patch-format:%s"), arg);2124return0;2125}21262127enum resume_mode {2128 RESUME_FALSE =0,2129 RESUME_APPLY,2130 RESUME_RESOLVED,2131 RESUME_SKIP,2132 RESUME_ABORT,2133 RESUME_QUIT,2134 RESUME_SHOW_PATCH2135};21362137static intgit_am_config(const char*k,const char*v,void*cb)2138{2139int status;21402141 status =git_gpg_config(k, v, NULL);2142if(status)2143return status;21442145returngit_default_config(k, v, NULL);2146}21472148intcmd_am(int argc,const char**argv,const char*prefix)2149{2150struct am_state state;2151int binary = -1;2152int keep_cr = -1;2153int patch_format = PATCH_FORMAT_UNKNOWN;2154enum resume_mode resume = RESUME_FALSE;2155int in_progress;2156int ret =0;21572158const char*const usage[] = {2159N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2160N_("git am [<options>] (--continue | --skip | --abort)"),2161 NULL2162};21632164struct option options[] = {2165OPT_BOOL('i',"interactive", &state.interactive,2166N_("run interactively")),2167OPT_HIDDEN_BOOL('b',"binary", &binary,2168N_("historical option -- no-op")),2169OPT_BOOL('3',"3way", &state.threeway,2170N_("allow fall back on 3way merging if needed")),2171OPT__QUIET(&state.quiet,N_("be quiet")),2172OPT_SET_INT('s',"signoff", &state.signoff,2173N_("add a Signed-off-by line to the commit message"),2174 SIGNOFF_EXPLICIT),2175OPT_BOOL('u',"utf8", &state.utf8,2176N_("recode into utf8 (default)")),2177OPT_SET_INT('k',"keep", &state.keep,2178N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2179OPT_SET_INT(0,"keep-non-patch", &state.keep,2180N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2181OPT_BOOL('m',"message-id", &state.message_id,2182N_("pass -m flag to git-mailinfo")),2183OPT_SET_INT_F(0,"keep-cr", &keep_cr,2184N_("pass --keep-cr flag to git-mailsplit for mbox format"),21851, PARSE_OPT_NONEG),2186OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2187N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21880, PARSE_OPT_NONEG),2189OPT_BOOL('c',"scissors", &state.scissors,2190N_("strip everything before a scissors line")),2191OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2192N_("pass it through git-apply"),21930),2194OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2195N_("pass it through git-apply"),2196 PARSE_OPT_NOARG),2197OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2198N_("pass it through git-apply"),2199 PARSE_OPT_NOARG),2200OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2201N_("pass it through git-apply"),22020),2203OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2204N_("pass it through git-apply"),22050),2206OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2207N_("pass it through git-apply"),22080),2209OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2210N_("pass it through git-apply"),22110),2212OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2213N_("pass it through git-apply"),22140),2215OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2216N_("format the patch(es) are in"),2217 parse_opt_patchformat),2218OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2219N_("pass it through git-apply"),2220 PARSE_OPT_NOARG),2221OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2222N_("override error message when patch failure occurs")),2223OPT_CMDMODE(0,"continue", &resume,2224N_("continue applying patches after resolving a conflict"),2225 RESUME_RESOLVED),2226OPT_CMDMODE('r',"resolved", &resume,2227N_("synonyms for --continue"),2228 RESUME_RESOLVED),2229OPT_CMDMODE(0,"skip", &resume,2230N_("skip the current patch"),2231 RESUME_SKIP),2232OPT_CMDMODE(0,"abort", &resume,2233N_("restore the original branch and abort the patching operation."),2234 RESUME_ABORT),2235OPT_CMDMODE(0,"quit", &resume,2236N_("abort the patching operation but keep HEAD where it is."),2237 RESUME_QUIT),2238OPT_CMDMODE(0,"show-current-patch", &resume,2239N_("show the patch being applied."),2240 RESUME_SHOW_PATCH),2241OPT_BOOL(0,"committer-date-is-author-date",2242&state.committer_date_is_author_date,2243N_("lie about committer date")),2244OPT_BOOL(0,"ignore-date", &state.ignore_date,2245N_("use current timestamp for author date")),2246OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2247{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2248N_("GPG-sign commits"),2249 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2250OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2251N_("(internal use for git-rebase)")),2252OPT_END()2253};22542255if(argc ==2&& !strcmp(argv[1],"-h"))2256usage_with_options(usage, options);22572258git_config(git_am_config, NULL);22592260am_state_init(&state);22612262 in_progress =am_in_progress(&state);2263if(in_progress)2264am_load(&state);22652266 argc =parse_options(argc, argv, prefix, options, usage,0);22672268if(binary >=0)2269fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2270"it will be removed. Please do not use it anymore."));22712272/* Ensure a valid committer ident can be constructed */2273git_committer_info(IDENT_STRICT);22742275if(repo_read_index_preload(the_repository, NULL,0) <0)2276die(_("failed to read the index"));22772278if(in_progress) {2279/*2280 * Catch user error to feed us patches when there is a session2281 * in progress:2282 *2283 * 1. mbox path(s) are provided on the command-line.2284 * 2. stdin is not a tty: the user is trying to feed us a patch2285 * from standard input. This is somewhat unreliable -- stdin2286 * could be /dev/null for example and the caller did not2287 * intend to feed us a patch but wanted to continue2288 * unattended.2289 */2290if(argc || (resume == RESUME_FALSE && !isatty(0)))2291die(_("previous rebase directory%sstill exists but mbox given."),2292 state.dir);22932294if(resume == RESUME_FALSE)2295 resume = RESUME_APPLY;22962297if(state.signoff == SIGNOFF_EXPLICIT)2298am_append_signoff(&state);2299}else{2300struct argv_array paths = ARGV_ARRAY_INIT;2301int i;23022303/*2304 * Handle stray state directory in the independent-run case. In2305 * the --rebasing case, it is up to the caller to take care of2306 * stray directories.2307 */2308if(file_exists(state.dir) && !state.rebasing) {2309if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2310am_destroy(&state);2311am_state_release(&state);2312return0;2313}23142315die(_("Stray%sdirectory found.\n"2316"Use\"git am --abort\"to remove it."),2317 state.dir);2318}23192320if(resume)2321die(_("Resolve operation not in progress, we are not resuming."));23222323for(i =0; i < argc; i++) {2324if(is_absolute_path(argv[i]) || !prefix)2325argv_array_push(&paths, argv[i]);2326else2327argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2328}23292330am_setup(&state, patch_format, paths.argv, keep_cr);23312332argv_array_clear(&paths);2333}23342335switch(resume) {2336case RESUME_FALSE:2337am_run(&state,0);2338break;2339case RESUME_APPLY:2340am_run(&state,1);2341break;2342case RESUME_RESOLVED:2343am_resolve(&state);2344break;2345case RESUME_SKIP:2346am_skip(&state);2347break;2348case RESUME_ABORT:2349am_abort(&state);2350break;2351case RESUME_QUIT:2352am_rerere_clear();2353am_destroy(&state);2354break;2355case RESUME_SHOW_PATCH:2356 ret =show_patch(&state);2357break;2358default:2359BUG("invalid resume value");2360}23612362am_state_release(&state);23632364return ret;2365}