1/* 2 * Builtin "git am" 3 * 4 * Based on git-am.sh by Junio C Hamano. 5 */ 6#include"cache.h" 7#include"config.h" 8#include"builtin.h" 9#include"exec-cmd.h" 10#include"parse-options.h" 11#include"dir.h" 12#include"run-command.h" 13#include"quote.h" 14#include"tempfile.h" 15#include"lockfile.h" 16#include"cache-tree.h" 17#include"refs.h" 18#include"commit.h" 19#include"diff.h" 20#include"diffcore.h" 21#include"unpack-trees.h" 22#include"branch.h" 23#include"sequencer.h" 24#include"revision.h" 25#include"merge-recursive.h" 26#include"revision.h" 27#include"log-tree.h" 28#include"notes-utils.h" 29#include"rerere.h" 30#include"prompt.h" 31#include"mailinfo.h" 32#include"apply.h" 33#include"string-list.h" 34#include"packfile.h" 35#include"repository.h" 36 37/** 38 * Returns the length of the first line of msg. 39 */ 40static intlinelen(const char*msg) 41{ 42returnstrchrnul(msg,'\n') - msg; 43} 44 45/** 46 * Returns true if `str` consists of only whitespace, false otherwise. 47 */ 48static intstr_isspace(const char*str) 49{ 50for(; *str; str++) 51if(!isspace(*str)) 52return0; 53 54return1; 55} 56 57enum patch_format { 58 PATCH_FORMAT_UNKNOWN =0, 59 PATCH_FORMAT_MBOX, 60 PATCH_FORMAT_STGIT, 61 PATCH_FORMAT_STGIT_SERIES, 62 PATCH_FORMAT_HG, 63 PATCH_FORMAT_MBOXRD 64}; 65 66enum keep_type { 67 KEEP_FALSE =0, 68 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 69 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 70}; 71 72enum scissors_type { 73 SCISSORS_UNSET = -1, 74 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 75 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 76}; 77 78enum signoff_type { 79 SIGNOFF_FALSE =0, 80 SIGNOFF_TRUE =1, 81 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 82}; 83 84struct am_state { 85/* state directory path */ 86char*dir; 87 88/* current and last patch numbers, 1-indexed */ 89int cur; 90int last; 91 92/* commit metadata and message */ 93char*author_name; 94char*author_email; 95char*author_date; 96char*msg; 97size_t msg_len; 98 99/* when --rebasing, records the original commit the patch came from */ 100struct object_id orig_commit; 101 102/* number of digits in patch filename */ 103int prec; 104 105/* various operating modes and command line options */ 106int interactive; 107int threeway; 108int quiet; 109int signoff;/* enum signoff_type */ 110int utf8; 111int keep;/* enum keep_type */ 112int message_id; 113int scissors;/* enum scissors_type */ 114struct argv_array git_apply_opts; 115const char*resolvemsg; 116int committer_date_is_author_date; 117int ignore_date; 118int allow_rerere_autoupdate; 119const char*sign_commit; 120int rebasing; 121}; 122 123/** 124 * Initializes am_state with the default values. 125 */ 126static voidam_state_init(struct am_state *state) 127{ 128int gpgsign; 129 130memset(state,0,sizeof(*state)); 131 132 state->dir =git_pathdup("rebase-apply"); 133 134 state->prec =4; 135 136git_config_get_bool("am.threeway", &state->threeway); 137 138 state->utf8 =1; 139 140git_config_get_bool("am.messageid", &state->message_id); 141 142 state->scissors = SCISSORS_UNSET; 143 144argv_array_init(&state->git_apply_opts); 145 146if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 147 state->sign_commit = gpgsign ?"": NULL; 148} 149 150/** 151 * Releases memory allocated by an am_state. 152 */ 153static voidam_state_release(struct am_state *state) 154{ 155free(state->dir); 156free(state->author_name); 157free(state->author_email); 158free(state->author_date); 159free(state->msg); 160argv_array_clear(&state->git_apply_opts); 161} 162 163/** 164 * Returns path relative to the am_state directory. 165 */ 166staticinlineconst char*am_path(const struct am_state *state,const char*path) 167{ 168returnmkpath("%s/%s", state->dir, path); 169} 170 171/** 172 * For convenience to call write_file() 173 */ 174static voidwrite_state_text(const struct am_state *state, 175const char*name,const char*string) 176{ 177write_file(am_path(state, name),"%s", string); 178} 179 180static voidwrite_state_count(const struct am_state *state, 181const char*name,int value) 182{ 183write_file(am_path(state, name),"%d", value); 184} 185 186static voidwrite_state_bool(const struct am_state *state, 187const char*name,int value) 188{ 189write_state_text(state, name, value ?"t":"f"); 190} 191 192/** 193 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 194 * at the end. 195 */ 196static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 197{ 198va_list ap; 199 200va_start(ap, fmt); 201if(!state->quiet) { 202vfprintf(fp, fmt, ap); 203putc('\n', fp); 204} 205va_end(ap); 206} 207 208/** 209 * Returns 1 if there is an am session in progress, 0 otherwise. 210 */ 211static intam_in_progress(const struct am_state *state) 212{ 213struct stat st; 214 215if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 216return0; 217if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 218return0; 219if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 220return0; 221return1; 222} 223 224/** 225 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 226 * number of bytes read on success, -1 if the file does not exist. If `trim` is 227 * set, trailing whitespace will be removed. 228 */ 229static intread_state_file(struct strbuf *sb,const struct am_state *state, 230const char*file,int trim) 231{ 232strbuf_reset(sb); 233 234if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 235if(trim) 236strbuf_trim(sb); 237 238return sb->len; 239} 240 241if(errno == ENOENT) 242return-1; 243 244die_errno(_("could not read '%s'"),am_path(state, file)); 245} 246 247/** 248 * Reads and parses the state directory's "author-script" file, and sets 249 * state->author_name, state->author_email and state->author_date accordingly. 250 * Returns 0 on success, -1 if the file could not be parsed. 251 * 252 * The author script is of the format: 253 * 254 * GIT_AUTHOR_NAME='$author_name' 255 * GIT_AUTHOR_EMAIL='$author_email' 256 * GIT_AUTHOR_DATE='$author_date' 257 * 258 * where $author_name, $author_email and $author_date are quoted. We are strict 259 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 260 * script, and thus if the file differs from what this function expects, it is 261 * better to bail out than to do something that the user does not expect. 262 */ 263static intread_am_author_script(struct am_state *state) 264{ 265const char*filename =am_path(state,"author-script"); 266 267assert(!state->author_name); 268assert(!state->author_email); 269assert(!state->author_date); 270 271returnread_author_script(filename, &state->author_name, 272&state->author_email, &state->author_date,1); 273} 274 275/** 276 * Saves state->author_name, state->author_email and state->author_date in the 277 * state directory's "author-script" file. 278 */ 279static voidwrite_author_script(const struct am_state *state) 280{ 281struct strbuf sb = STRBUF_INIT; 282 283strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 284sq_quote_buf(&sb, state->author_name); 285strbuf_addch(&sb,'\n'); 286 287strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 288sq_quote_buf(&sb, state->author_email); 289strbuf_addch(&sb,'\n'); 290 291strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 292sq_quote_buf(&sb, state->author_date); 293strbuf_addch(&sb,'\n'); 294 295write_state_text(state,"author-script", sb.buf); 296 297strbuf_release(&sb); 298} 299 300/** 301 * Reads the commit message from the state directory's "final-commit" file, 302 * setting state->msg to its contents and state->msg_len to the length of its 303 * contents in bytes. 304 * 305 * Returns 0 on success, -1 if the file does not exist. 306 */ 307static intread_commit_msg(struct am_state *state) 308{ 309struct strbuf sb = STRBUF_INIT; 310 311assert(!state->msg); 312 313if(read_state_file(&sb, state,"final-commit",0) <0) { 314strbuf_release(&sb); 315return-1; 316} 317 318 state->msg =strbuf_detach(&sb, &state->msg_len); 319return0; 320} 321 322/** 323 * Saves state->msg in the state directory's "final-commit" file. 324 */ 325static voidwrite_commit_msg(const struct am_state *state) 326{ 327const char*filename =am_path(state,"final-commit"); 328write_file_buf(filename, state->msg, state->msg_len); 329} 330 331/** 332 * Loads state from disk. 333 */ 334static voidam_load(struct am_state *state) 335{ 336struct strbuf sb = STRBUF_INIT; 337 338if(read_state_file(&sb, state,"next",1) <0) 339BUG("state file 'next' does not exist"); 340 state->cur =strtol(sb.buf, NULL,10); 341 342if(read_state_file(&sb, state,"last",1) <0) 343BUG("state file 'last' does not exist"); 344 state->last =strtol(sb.buf, NULL,10); 345 346if(read_am_author_script(state) <0) 347die(_("could not parse author script")); 348 349read_commit_msg(state); 350 351if(read_state_file(&sb, state,"original-commit",1) <0) 352oidclr(&state->orig_commit); 353else if(get_oid_hex(sb.buf, &state->orig_commit) <0) 354die(_("could not parse%s"),am_path(state,"original-commit")); 355 356read_state_file(&sb, state,"threeway",1); 357 state->threeway = !strcmp(sb.buf,"t"); 358 359read_state_file(&sb, state,"quiet",1); 360 state->quiet = !strcmp(sb.buf,"t"); 361 362read_state_file(&sb, state,"sign",1); 363 state->signoff = !strcmp(sb.buf,"t"); 364 365read_state_file(&sb, state,"utf8",1); 366 state->utf8 = !strcmp(sb.buf,"t"); 367 368if(file_exists(am_path(state,"rerere-autoupdate"))) { 369read_state_file(&sb, state,"rerere-autoupdate",1); 370 state->allow_rerere_autoupdate =strcmp(sb.buf,"t") ? 371 RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE; 372}else{ 373 state->allow_rerere_autoupdate =0; 374} 375 376read_state_file(&sb, state,"keep",1); 377if(!strcmp(sb.buf,"t")) 378 state->keep = KEEP_TRUE; 379else if(!strcmp(sb.buf,"b")) 380 state->keep = KEEP_NON_PATCH; 381else 382 state->keep = KEEP_FALSE; 383 384read_state_file(&sb, state,"messageid",1); 385 state->message_id = !strcmp(sb.buf,"t"); 386 387read_state_file(&sb, state,"scissors",1); 388if(!strcmp(sb.buf,"t")) 389 state->scissors = SCISSORS_TRUE; 390else if(!strcmp(sb.buf,"f")) 391 state->scissors = SCISSORS_FALSE; 392else 393 state->scissors = SCISSORS_UNSET; 394 395read_state_file(&sb, state,"apply-opt",1); 396argv_array_clear(&state->git_apply_opts); 397if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 398die(_("could not parse%s"),am_path(state,"apply-opt")); 399 400 state->rebasing = !!file_exists(am_path(state,"rebasing")); 401 402strbuf_release(&sb); 403} 404 405/** 406 * Removes the am_state directory, forcefully terminating the current am 407 * session. 408 */ 409static voidam_destroy(const struct am_state *state) 410{ 411struct strbuf sb = STRBUF_INIT; 412 413strbuf_addstr(&sb, state->dir); 414remove_dir_recursively(&sb,0); 415strbuf_release(&sb); 416} 417 418/** 419 * Runs applypatch-msg hook. Returns its exit code. 420 */ 421static intrun_applypatch_msg_hook(struct am_state *state) 422{ 423int ret; 424 425assert(state->msg); 426 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 427 428if(!ret) { 429FREE_AND_NULL(state->msg); 430if(read_commit_msg(state) <0) 431die(_("'%s' was deleted by the applypatch-msg hook"), 432am_path(state,"final-commit")); 433} 434 435return ret; 436} 437 438/** 439 * Runs post-rewrite hook. Returns it exit code. 440 */ 441static intrun_post_rewrite_hook(const struct am_state *state) 442{ 443struct child_process cp = CHILD_PROCESS_INIT; 444const char*hook =find_hook("post-rewrite"); 445int ret; 446 447if(!hook) 448return0; 449 450argv_array_push(&cp.args, hook); 451argv_array_push(&cp.args,"rebase"); 452 453 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 454 cp.stdout_to_stderr =1; 455 456 ret =run_command(&cp); 457 458close(cp.in); 459return ret; 460} 461 462/** 463 * Reads the state directory's "rewritten" file, and copies notes from the old 464 * commits listed in the file to their rewritten commits. 465 * 466 * Returns 0 on success, -1 on failure. 467 */ 468static intcopy_notes_for_rebase(const struct am_state *state) 469{ 470struct notes_rewrite_cfg *c; 471struct strbuf sb = STRBUF_INIT; 472const char*invalid_line =_("Malformed input line: '%s'."); 473const char*msg ="Notes added by 'git rebase'"; 474FILE*fp; 475int ret =0; 476 477assert(state->rebasing); 478 479 c =init_copy_notes_for_rewrite("rebase"); 480if(!c) 481return0; 482 483 fp =xfopen(am_path(state,"rewritten"),"r"); 484 485while(!strbuf_getline_lf(&sb, fp)) { 486struct object_id from_obj, to_obj; 487 488if(sb.len != GIT_SHA1_HEXSZ *2+1) { 489 ret =error(invalid_line, sb.buf); 490goto finish; 491} 492 493if(get_oid_hex(sb.buf, &from_obj)) { 494 ret =error(invalid_line, sb.buf); 495goto finish; 496} 497 498if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 499 ret =error(invalid_line, sb.buf); 500goto finish; 501} 502 503if(get_oid_hex(sb.buf + GIT_SHA1_HEXSZ +1, &to_obj)) { 504 ret =error(invalid_line, sb.buf); 505goto finish; 506} 507 508if(copy_note_for_rewrite(c, &from_obj, &to_obj)) 509 ret =error(_("Failed to copy notes from '%s' to '%s'"), 510oid_to_hex(&from_obj),oid_to_hex(&to_obj)); 511} 512 513finish: 514finish_copy_notes_for_rewrite(c, msg); 515fclose(fp); 516strbuf_release(&sb); 517return ret; 518} 519 520/** 521 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 522 * non-indented lines and checking if they look like they begin with valid 523 * header field names. 524 * 525 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 526 */ 527static intis_mail(FILE*fp) 528{ 529const char*header_regex ="^[!-9;-~]+:"; 530struct strbuf sb = STRBUF_INIT; 531 regex_t regex; 532int ret =1; 533 534if(fseek(fp,0L, SEEK_SET)) 535die_errno(_("fseek failed")); 536 537if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 538die("invalid pattern:%s", header_regex); 539 540while(!strbuf_getline(&sb, fp)) { 541if(!sb.len) 542break;/* End of header */ 543 544/* Ignore indented folded lines */ 545if(*sb.buf =='\t'|| *sb.buf ==' ') 546continue; 547 548/* It's a header if it matches header_regex */ 549if(regexec(®ex, sb.buf,0, NULL,0)) { 550 ret =0; 551goto done; 552} 553} 554 555done: 556regfree(®ex); 557strbuf_release(&sb); 558return ret; 559} 560 561/** 562 * Attempts to detect the patch_format of the patches contained in `paths`, 563 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 564 * detection fails. 565 */ 566static intdetect_patch_format(const char**paths) 567{ 568enum patch_format ret = PATCH_FORMAT_UNKNOWN; 569struct strbuf l1 = STRBUF_INIT; 570struct strbuf l2 = STRBUF_INIT; 571struct strbuf l3 = STRBUF_INIT; 572FILE*fp; 573 574/* 575 * We default to mbox format if input is from stdin and for directories 576 */ 577if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 578return PATCH_FORMAT_MBOX; 579 580/* 581 * Otherwise, check the first few lines of the first patch, starting 582 * from the first non-blank line, to try to detect its format. 583 */ 584 585 fp =xfopen(*paths,"r"); 586 587while(!strbuf_getline(&l1, fp)) { 588if(l1.len) 589break; 590} 591 592if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 593 ret = PATCH_FORMAT_MBOX; 594goto done; 595} 596 597if(starts_with(l1.buf,"# This series applies on GIT commit")) { 598 ret = PATCH_FORMAT_STGIT_SERIES; 599goto done; 600} 601 602if(!strcmp(l1.buf,"# HG changeset patch")) { 603 ret = PATCH_FORMAT_HG; 604goto done; 605} 606 607strbuf_getline(&l2, fp); 608strbuf_getline(&l3, fp); 609 610/* 611 * If the second line is empty and the third is a From, Author or Date 612 * entry, this is likely an StGit patch. 613 */ 614if(l1.len && !l2.len && 615(starts_with(l3.buf,"From:") || 616starts_with(l3.buf,"Author:") || 617starts_with(l3.buf,"Date:"))) { 618 ret = PATCH_FORMAT_STGIT; 619goto done; 620} 621 622if(l1.len &&is_mail(fp)) { 623 ret = PATCH_FORMAT_MBOX; 624goto done; 625} 626 627done: 628fclose(fp); 629strbuf_release(&l1); 630strbuf_release(&l2); 631strbuf_release(&l3); 632return ret; 633} 634 635/** 636 * Splits out individual email patches from `paths`, where each path is either 637 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 638 */ 639static intsplit_mail_mbox(struct am_state *state,const char**paths, 640int keep_cr,int mboxrd) 641{ 642struct child_process cp = CHILD_PROCESS_INIT; 643struct strbuf last = STRBUF_INIT; 644int ret; 645 646 cp.git_cmd =1; 647argv_array_push(&cp.args,"mailsplit"); 648argv_array_pushf(&cp.args,"-d%d", state->prec); 649argv_array_pushf(&cp.args,"-o%s", state->dir); 650argv_array_push(&cp.args,"-b"); 651if(keep_cr) 652argv_array_push(&cp.args,"--keep-cr"); 653if(mboxrd) 654argv_array_push(&cp.args,"--mboxrd"); 655argv_array_push(&cp.args,"--"); 656argv_array_pushv(&cp.args, paths); 657 658 ret =capture_command(&cp, &last,8); 659if(ret) 660goto exit; 661 662 state->cur =1; 663 state->last =strtol(last.buf, NULL,10); 664 665exit: 666strbuf_release(&last); 667return ret ? -1:0; 668} 669 670/** 671 * Callback signature for split_mail_conv(). The foreign patch should be 672 * read from `in`, and the converted patch (in RFC2822 mail format) should be 673 * written to `out`. Return 0 on success, or -1 on failure. 674 */ 675typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 676 677/** 678 * Calls `fn` for each file in `paths` to convert the foreign patch to the 679 * RFC2822 mail format suitable for parsing with git-mailinfo. 680 * 681 * Returns 0 on success, -1 on failure. 682 */ 683static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 684const char**paths,int keep_cr) 685{ 686static const char*stdin_only[] = {"-", NULL}; 687int i; 688 689if(!*paths) 690 paths = stdin_only; 691 692for(i =0; *paths; paths++, i++) { 693FILE*in, *out; 694const char*mail; 695int ret; 696 697if(!strcmp(*paths,"-")) 698 in = stdin; 699else 700 in =fopen(*paths,"r"); 701 702if(!in) 703returnerror_errno(_("could not open '%s' for reading"), 704*paths); 705 706 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 707 708 out =fopen(mail,"w"); 709if(!out) { 710if(in != stdin) 711fclose(in); 712returnerror_errno(_("could not open '%s' for writing"), 713 mail); 714} 715 716 ret =fn(out, in, keep_cr); 717 718fclose(out); 719if(in != stdin) 720fclose(in); 721 722if(ret) 723returnerror(_("could not parse patch '%s'"), *paths); 724} 725 726 state->cur =1; 727 state->last = i; 728return0; 729} 730 731/** 732 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 733 * message suitable for parsing with git-mailinfo. 734 */ 735static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 736{ 737struct strbuf sb = STRBUF_INIT; 738int subject_printed =0; 739 740while(!strbuf_getline_lf(&sb, in)) { 741const char*str; 742 743if(str_isspace(sb.buf)) 744continue; 745else if(skip_prefix(sb.buf,"Author:", &str)) 746fprintf(out,"From:%s\n", str); 747else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 748fprintf(out,"%s\n", sb.buf); 749else if(!subject_printed) { 750fprintf(out,"Subject:%s\n", sb.buf); 751 subject_printed =1; 752}else{ 753fprintf(out,"\n%s\n", sb.buf); 754break; 755} 756} 757 758strbuf_reset(&sb); 759while(strbuf_fread(&sb,8192, in) >0) { 760fwrite(sb.buf,1, sb.len, out); 761strbuf_reset(&sb); 762} 763 764strbuf_release(&sb); 765return0; 766} 767 768/** 769 * This function only supports a single StGit series file in `paths`. 770 * 771 * Given an StGit series file, converts the StGit patches in the series into 772 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 773 * the state directory. 774 * 775 * Returns 0 on success, -1 on failure. 776 */ 777static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 778int keep_cr) 779{ 780const char*series_dir; 781char*series_dir_buf; 782FILE*fp; 783struct argv_array patches = ARGV_ARRAY_INIT; 784struct strbuf sb = STRBUF_INIT; 785int ret; 786 787if(!paths[0] || paths[1]) 788returnerror(_("Only one StGIT patch series can be applied at once")); 789 790 series_dir_buf =xstrdup(*paths); 791 series_dir =dirname(series_dir_buf); 792 793 fp =fopen(*paths,"r"); 794if(!fp) 795returnerror_errno(_("could not open '%s' for reading"), *paths); 796 797while(!strbuf_getline_lf(&sb, fp)) { 798if(*sb.buf =='#') 799continue;/* skip comment lines */ 800 801argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 802} 803 804fclose(fp); 805strbuf_release(&sb); 806free(series_dir_buf); 807 808 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 809 810argv_array_clear(&patches); 811return ret; 812} 813 814/** 815 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 816 * message suitable for parsing with git-mailinfo. 817 */ 818static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 819{ 820struct strbuf sb = STRBUF_INIT; 821int rc =0; 822 823while(!strbuf_getline_lf(&sb, in)) { 824const char*str; 825 826if(skip_prefix(sb.buf,"# User ", &str)) 827fprintf(out,"From:%s\n", str); 828else if(skip_prefix(sb.buf,"# Date ", &str)) { 829 timestamp_t timestamp; 830long tz, tz2; 831char*end; 832 833 errno =0; 834 timestamp =parse_timestamp(str, &end,10); 835if(errno) { 836 rc =error(_("invalid timestamp")); 837goto exit; 838} 839 840if(!skip_prefix(end," ", &str)) { 841 rc =error(_("invalid Date line")); 842goto exit; 843} 844 845 errno =0; 846 tz =strtol(str, &end,10); 847if(errno) { 848 rc =error(_("invalid timezone offset")); 849goto exit; 850} 851 852if(*end) { 853 rc =error(_("invalid Date line")); 854goto exit; 855} 856 857/* 858 * mercurial's timezone is in seconds west of UTC, 859 * however git's timezone is in hours + minutes east of 860 * UTC. Convert it. 861 */ 862 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 863if(tz >0) 864 tz2 = -tz2; 865 866fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 867}else if(starts_with(sb.buf,"# ")) { 868continue; 869}else{ 870fprintf(out,"\n%s\n", sb.buf); 871break; 872} 873} 874 875strbuf_reset(&sb); 876while(strbuf_fread(&sb,8192, in) >0) { 877fwrite(sb.buf,1, sb.len, out); 878strbuf_reset(&sb); 879} 880exit: 881strbuf_release(&sb); 882return rc; 883} 884 885/** 886 * Splits a list of files/directories into individual email patches. Each path 887 * in `paths` must be a file/directory that is formatted according to 888 * `patch_format`. 889 * 890 * Once split out, the individual email patches will be stored in the state 891 * directory, with each patch's filename being its index, padded to state->prec 892 * digits. 893 * 894 * state->cur will be set to the index of the first mail, and state->last will 895 * be set to the index of the last mail. 896 * 897 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 898 * to disable this behavior, -1 to use the default configured setting. 899 * 900 * Returns 0 on success, -1 on failure. 901 */ 902static intsplit_mail(struct am_state *state,enum patch_format patch_format, 903const char**paths,int keep_cr) 904{ 905if(keep_cr <0) { 906 keep_cr =0; 907git_config_get_bool("am.keepcr", &keep_cr); 908} 909 910switch(patch_format) { 911case PATCH_FORMAT_MBOX: 912returnsplit_mail_mbox(state, paths, keep_cr,0); 913case PATCH_FORMAT_STGIT: 914returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 915case PATCH_FORMAT_STGIT_SERIES: 916returnsplit_mail_stgit_series(state, paths, keep_cr); 917case PATCH_FORMAT_HG: 918returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 919case PATCH_FORMAT_MBOXRD: 920returnsplit_mail_mbox(state, paths, keep_cr,1); 921default: 922BUG("invalid patch_format"); 923} 924return-1; 925} 926 927/** 928 * Setup a new am session for applying patches 929 */ 930static voidam_setup(struct am_state *state,enum patch_format patch_format, 931const char**paths,int keep_cr) 932{ 933struct object_id curr_head; 934const char*str; 935struct strbuf sb = STRBUF_INIT; 936 937if(!patch_format) 938 patch_format =detect_patch_format(paths); 939 940if(!patch_format) { 941fprintf_ln(stderr,_("Patch format detection failed.")); 942exit(128); 943} 944 945if(mkdir(state->dir,0777) <0&& errno != EEXIST) 946die_errno(_("failed to create directory '%s'"), state->dir); 947delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF); 948 949if(split_mail(state, patch_format, paths, keep_cr) <0) { 950am_destroy(state); 951die(_("Failed to split patches.")); 952} 953 954if(state->rebasing) 955 state->threeway =1; 956 957write_state_bool(state,"threeway", state->threeway); 958write_state_bool(state,"quiet", state->quiet); 959write_state_bool(state,"sign", state->signoff); 960write_state_bool(state,"utf8", state->utf8); 961 962if(state->allow_rerere_autoupdate) 963write_state_bool(state,"rerere-autoupdate", 964 state->allow_rerere_autoupdate == RERERE_AUTOUPDATE); 965 966switch(state->keep) { 967case KEEP_FALSE: 968 str ="f"; 969break; 970case KEEP_TRUE: 971 str ="t"; 972break; 973case KEEP_NON_PATCH: 974 str ="b"; 975break; 976default: 977BUG("invalid value for state->keep"); 978} 979 980write_state_text(state,"keep", str); 981write_state_bool(state,"messageid", state->message_id); 982 983switch(state->scissors) { 984case SCISSORS_UNSET: 985 str =""; 986break; 987case SCISSORS_FALSE: 988 str ="f"; 989break; 990case SCISSORS_TRUE: 991 str ="t"; 992break; 993default: 994BUG("invalid value for state->scissors"); 995} 996write_state_text(state,"scissors", str); 997 998sq_quote_argv(&sb, state->git_apply_opts.argv); 999write_state_text(state,"apply-opt", sb.buf);10001001if(state->rebasing)1002write_state_text(state,"rebasing","");1003else1004write_state_text(state,"applying","");10051006if(!get_oid("HEAD", &curr_head)) {1007write_state_text(state,"abort-safety",oid_to_hex(&curr_head));1008if(!state->rebasing)1009update_ref("am","ORIG_HEAD", &curr_head, NULL,0,1010 UPDATE_REFS_DIE_ON_ERR);1011}else{1012write_state_text(state,"abort-safety","");1013if(!state->rebasing)1014delete_ref(NULL,"ORIG_HEAD", NULL,0);1015}10161017/*1018 * NOTE: Since the "next" and "last" files determine if an am_state1019 * session is in progress, they should be written last.1020 */10211022write_state_count(state,"next", state->cur);1023write_state_count(state,"last", state->last);10241025strbuf_release(&sb);1026}10271028/**1029 * Increments the patch pointer, and cleans am_state for the application of the1030 * next patch.1031 */1032static voidam_next(struct am_state *state)1033{1034struct object_id head;10351036FREE_AND_NULL(state->author_name);1037FREE_AND_NULL(state->author_email);1038FREE_AND_NULL(state->author_date);1039FREE_AND_NULL(state->msg);1040 state->msg_len =0;10411042unlink(am_path(state,"author-script"));1043unlink(am_path(state,"final-commit"));10441045oidclr(&state->orig_commit);1046unlink(am_path(state,"original-commit"));1047delete_ref(NULL,"REBASE_HEAD", NULL, REF_NO_DEREF);10481049if(!get_oid("HEAD", &head))1050write_state_text(state,"abort-safety",oid_to_hex(&head));1051else1052write_state_text(state,"abort-safety","");10531054 state->cur++;1055write_state_count(state,"next", state->cur);1056}10571058/**1059 * Returns the filename of the current patch email.1060 */1061static const char*msgnum(const struct am_state *state)1062{1063static struct strbuf sb = STRBUF_INIT;10641065strbuf_reset(&sb);1066strbuf_addf(&sb,"%0*d", state->prec, state->cur);10671068return sb.buf;1069}10701071/**1072 * Refresh and write index.1073 */1074static voidrefresh_and_write_cache(void)1075{1076struct lock_file lock_file = LOCK_INIT;10771078hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);1079refresh_cache(REFRESH_QUIET);1080if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1081die(_("unable to write index file"));1082}10831084/**1085 * Dies with a user-friendly message on how to proceed after resolving the1086 * problem. This message can be overridden with state->resolvemsg.1087 */1088static void NORETURN die_user_resolve(const struct am_state *state)1089{1090if(state->resolvemsg) {1091printf_ln("%s", state->resolvemsg);1092}else{1093const char*cmdline = state->interactive ?"git am -i":"git am";10941095printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1096printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1097printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1098}10991100exit(128);1101}11021103/**1104 * Appends signoff to the "msg" field of the am_state.1105 */1106static voidam_append_signoff(struct am_state *state)1107{1108struct strbuf sb = STRBUF_INIT;11091110strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1111append_signoff(&sb,0,0);1112 state->msg =strbuf_detach(&sb, &state->msg_len);1113}11141115/**1116 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1117 * state->msg will be set to the patch message. state->author_name,1118 * state->author_email and state->author_date will be set to the patch author's1119 * name, email and date respectively. The patch body will be written to the1120 * state directory's "patch" file.1121 *1122 * Returns 1 if the patch should be skipped, 0 otherwise.1123 */1124static intparse_mail(struct am_state *state,const char*mail)1125{1126FILE*fp;1127struct strbuf sb = STRBUF_INIT;1128struct strbuf msg = STRBUF_INIT;1129struct strbuf author_name = STRBUF_INIT;1130struct strbuf author_date = STRBUF_INIT;1131struct strbuf author_email = STRBUF_INIT;1132int ret =0;1133struct mailinfo mi;11341135setup_mailinfo(&mi);11361137if(state->utf8)1138 mi.metainfo_charset =get_commit_output_encoding();1139else1140 mi.metainfo_charset = NULL;11411142switch(state->keep) {1143case KEEP_FALSE:1144break;1145case KEEP_TRUE:1146 mi.keep_subject =1;1147break;1148case KEEP_NON_PATCH:1149 mi.keep_non_patch_brackets_in_subject =1;1150break;1151default:1152BUG("invalid value for state->keep");1153}11541155if(state->message_id)1156 mi.add_message_id =1;11571158switch(state->scissors) {1159case SCISSORS_UNSET:1160break;1161case SCISSORS_FALSE:1162 mi.use_scissors =0;1163break;1164case SCISSORS_TRUE:1165 mi.use_scissors =1;1166break;1167default:1168BUG("invalid value for state->scissors");1169}11701171 mi.input =xfopen(mail,"r");1172 mi.output =xfopen(am_path(state,"info"),"w");1173if(mailinfo(&mi,am_path(state,"msg"),am_path(state,"patch")))1174die("could not parse patch");11751176fclose(mi.input);1177fclose(mi.output);11781179if(mi.format_flowed)1180warning(_("Patch sent with format=flowed; "1181"space at the end of lines might be lost."));11821183/* Extract message and author information */1184 fp =xfopen(am_path(state,"info"),"r");1185while(!strbuf_getline_lf(&sb, fp)) {1186const char*x;11871188if(skip_prefix(sb.buf,"Subject: ", &x)) {1189if(msg.len)1190strbuf_addch(&msg,'\n');1191strbuf_addstr(&msg, x);1192}else if(skip_prefix(sb.buf,"Author: ", &x))1193strbuf_addstr(&author_name, x);1194else if(skip_prefix(sb.buf,"Email: ", &x))1195strbuf_addstr(&author_email, x);1196else if(skip_prefix(sb.buf,"Date: ", &x))1197strbuf_addstr(&author_date, x);1198}1199fclose(fp);12001201/* Skip pine's internal folder data */1202if(!strcmp(author_name.buf,"Mail System Internal Data")) {1203 ret =1;1204goto finish;1205}12061207if(is_empty_or_missing_file(am_path(state,"patch"))) {1208printf_ln(_("Patch is empty."));1209die_user_resolve(state);1210}12111212strbuf_addstr(&msg,"\n\n");1213strbuf_addbuf(&msg, &mi.log_message);1214strbuf_stripspace(&msg,0);12151216assert(!state->author_name);1217 state->author_name =strbuf_detach(&author_name, NULL);12181219assert(!state->author_email);1220 state->author_email =strbuf_detach(&author_email, NULL);12211222assert(!state->author_date);1223 state->author_date =strbuf_detach(&author_date, NULL);12241225assert(!state->msg);1226 state->msg =strbuf_detach(&msg, &state->msg_len);12271228finish:1229strbuf_release(&msg);1230strbuf_release(&author_date);1231strbuf_release(&author_email);1232strbuf_release(&author_name);1233strbuf_release(&sb);1234clear_mailinfo(&mi);1235return ret;1236}12371238/**1239 * Sets commit_id to the commit hash where the mail was generated from.1240 * Returns 0 on success, -1 on failure.1241 */1242static intget_mail_commit_oid(struct object_id *commit_id,const char*mail)1243{1244struct strbuf sb = STRBUF_INIT;1245FILE*fp =xfopen(mail,"r");1246const char*x;1247int ret =0;12481249if(strbuf_getline_lf(&sb, fp) ||1250!skip_prefix(sb.buf,"From ", &x) ||1251get_oid_hex(x, commit_id) <0)1252 ret = -1;12531254strbuf_release(&sb);1255fclose(fp);1256return ret;1257}12581259/**1260 * Sets state->msg, state->author_name, state->author_email, state->author_date1261 * to the commit's respective info.1262 */1263static voidget_commit_info(struct am_state *state,struct commit *commit)1264{1265const char*buffer, *ident_line, *msg;1266size_t ident_len;1267struct ident_split id;12681269 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());12701271 ident_line =find_commit_header(buffer,"author", &ident_len);12721273if(split_ident_line(&id, ident_line, ident_len) <0)1274die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);12751276assert(!state->author_name);1277if(id.name_begin)1278 state->author_name =1279xmemdupz(id.name_begin, id.name_end - id.name_begin);1280else1281 state->author_name =xstrdup("");12821283assert(!state->author_email);1284if(id.mail_begin)1285 state->author_email =1286xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1287else1288 state->author_email =xstrdup("");12891290assert(!state->author_date);1291 state->author_date =xstrdup(show_ident_date(&id,DATE_MODE(NORMAL)));12921293assert(!state->msg);1294 msg =strstr(buffer,"\n\n");1295if(!msg)1296die(_("unable to parse commit%s"),oid_to_hex(&commit->object.oid));1297 state->msg =xstrdup(msg +2);1298 state->msg_len =strlen(state->msg);1299unuse_commit_buffer(commit, buffer);1300}13011302/**1303 * Writes `commit` as a patch to the state directory's "patch" file.1304 */1305static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1306{1307struct rev_info rev_info;1308FILE*fp;13091310 fp =xfopen(am_path(state,"patch"),"w");1311repo_init_revisions(the_repository, &rev_info, NULL);1312 rev_info.diff =1;1313 rev_info.abbrev =0;1314 rev_info.disable_stdin =1;1315 rev_info.show_root_diff =1;1316 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1317 rev_info.no_commit_id =1;1318 rev_info.diffopt.flags.binary =1;1319 rev_info.diffopt.flags.full_index =1;1320 rev_info.diffopt.use_color =0;1321 rev_info.diffopt.file = fp;1322 rev_info.diffopt.close_file =1;1323add_pending_object(&rev_info, &commit->object,"");1324diff_setup_done(&rev_info.diffopt);1325log_tree_commit(&rev_info, commit);1326}13271328/**1329 * Writes the diff of the index against HEAD as a patch to the state1330 * directory's "patch" file.1331 */1332static voidwrite_index_patch(const struct am_state *state)1333{1334struct tree *tree;1335struct object_id head;1336struct rev_info rev_info;1337FILE*fp;13381339if(!get_oid_tree("HEAD", &head))1340 tree =lookup_tree(the_repository, &head);1341else1342 tree =lookup_tree(the_repository,1343 the_repository->hash_algo->empty_tree);13441345 fp =xfopen(am_path(state,"patch"),"w");1346repo_init_revisions(the_repository, &rev_info, NULL);1347 rev_info.diff =1;1348 rev_info.disable_stdin =1;1349 rev_info.no_commit_id =1;1350 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1351 rev_info.diffopt.use_color =0;1352 rev_info.diffopt.file = fp;1353 rev_info.diffopt.close_file =1;1354add_pending_object(&rev_info, &tree->object,"");1355diff_setup_done(&rev_info.diffopt);1356run_diff_index(&rev_info,1);1357}13581359/**1360 * Like parse_mail(), but parses the mail by looking up its commit ID1361 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1362 * of patches.1363 *1364 * state->orig_commit will be set to the original commit ID.1365 *1366 * Will always return 0 as the patch should never be skipped.1367 */1368static intparse_mail_rebase(struct am_state *state,const char*mail)1369{1370struct commit *commit;1371struct object_id commit_oid;13721373if(get_mail_commit_oid(&commit_oid, mail) <0)1374die(_("could not parse%s"), mail);13751376 commit =lookup_commit_or_die(&commit_oid, mail);13771378get_commit_info(state, commit);13791380write_commit_patch(state, commit);13811382oidcpy(&state->orig_commit, &commit_oid);1383write_state_text(state,"original-commit",oid_to_hex(&commit_oid));1384update_ref("am","REBASE_HEAD", &commit_oid,1385 NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);13861387return0;1388}13891390/**1391 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1392 * `index_file` is not NULL, the patch will be applied to that index.1393 */1394static intrun_apply(const struct am_state *state,const char*index_file)1395{1396struct argv_array apply_paths = ARGV_ARRAY_INIT;1397struct argv_array apply_opts = ARGV_ARRAY_INIT;1398struct apply_state apply_state;1399int res, opts_left;1400int force_apply =0;1401int options =0;14021403if(init_apply_state(&apply_state, the_repository, NULL))1404BUG("init_apply_state() failed");14051406argv_array_push(&apply_opts,"apply");1407argv_array_pushv(&apply_opts, state->git_apply_opts.argv);14081409 opts_left =apply_parse_options(apply_opts.argc, apply_opts.argv,1410&apply_state, &force_apply, &options,1411 NULL);14121413if(opts_left !=0)1414die("unknown option passed through to git apply");14151416if(index_file) {1417 apply_state.index_file = index_file;1418 apply_state.cached =1;1419}else1420 apply_state.check_index =1;14211422/*1423 * If we are allowed to fall back on 3-way merge, don't give false1424 * errors during the initial attempt.1425 */1426if(state->threeway && !index_file)1427 apply_state.apply_verbosity = verbosity_silent;14281429if(check_apply_state(&apply_state, force_apply))1430BUG("check_apply_state() failed");14311432argv_array_push(&apply_paths,am_path(state,"patch"));14331434 res =apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options);14351436argv_array_clear(&apply_paths);1437argv_array_clear(&apply_opts);1438clear_apply_state(&apply_state);14391440if(res)1441return res;14421443if(index_file) {1444/* Reload index as apply_all_patches() will have modified it. */1445discard_cache();1446read_cache_from(index_file);1447}14481449return0;1450}14511452/**1453 * Builds an index that contains just the blobs needed for a 3way merge.1454 */1455static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1456{1457struct child_process cp = CHILD_PROCESS_INIT;14581459 cp.git_cmd =1;1460argv_array_push(&cp.args,"apply");1461argv_array_pushv(&cp.args, state->git_apply_opts.argv);1462argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1463argv_array_push(&cp.args,am_path(state,"patch"));14641465if(run_command(&cp))1466return-1;14671468return0;1469}14701471/**1472 * Attempt a threeway merge, using index_path as the temporary index.1473 */1474static intfall_back_threeway(const struct am_state *state,const char*index_path)1475{1476struct object_id orig_tree, their_tree, our_tree;1477const struct object_id *bases[1] = { &orig_tree };1478struct merge_options o;1479struct commit *result;1480char*their_tree_name;14811482if(get_oid("HEAD", &our_tree) <0)1483oidcpy(&our_tree, the_hash_algo->empty_tree);14841485if(build_fake_ancestor(state, index_path))1486returnerror("could not build fake ancestor");14871488discard_cache();1489read_cache_from(index_path);14901491if(write_index_as_tree(&orig_tree, &the_index, index_path,0, NULL))1492returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));14931494say(state, stdout,_("Using index info to reconstruct a base tree..."));14951496if(!state->quiet) {1497/*1498 * List paths that needed 3-way fallback, so that the user can1499 * review them with extra care to spot mismerges.1500 */1501struct rev_info rev_info;1502const char*diff_filter_str ="--diff-filter=AM";15031504repo_init_revisions(the_repository, &rev_info, NULL);1505 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1506diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1, rev_info.prefix);1507add_pending_oid(&rev_info,"HEAD", &our_tree,0);1508diff_setup_done(&rev_info.diffopt);1509run_diff_index(&rev_info,1);1510}15111512if(run_apply(state, index_path))1513returnerror(_("Did you hand edit your patch?\n"1514"It does not apply to blobs recorded in its index."));15151516if(write_index_as_tree(&their_tree, &the_index, index_path,0, NULL))1517returnerror("could not write tree");15181519say(state, stdout,_("Falling back to patching base and 3-way merge..."));15201521discard_cache();1522read_cache();15231524/*1525 * This is not so wrong. Depending on which base we picked, orig_tree1526 * may be wildly different from ours, but their_tree has the same set of1527 * wildly different changes in parts the patch did not touch, so1528 * recursive ends up canceling them, saying that we reverted all those1529 * changes.1530 */15311532init_merge_options(&o);15331534 o.branch1 ="HEAD";1535 their_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1536 o.branch2 = their_tree_name;1537 o.detect_directory_renames =0;15381539if(state->quiet)1540 o.verbosity =0;15411542if(merge_recursive_generic(&o, &our_tree, &their_tree,1, bases, &result)) {1543repo_rerere(the_repository, state->allow_rerere_autoupdate);1544free(their_tree_name);1545returnerror(_("Failed to merge in the changes."));1546}15471548free(their_tree_name);1549return0;1550}15511552/**1553 * Commits the current index with state->msg as the commit message and1554 * state->author_name, state->author_email and state->author_date as the author1555 * information.1556 */1557static voiddo_commit(const struct am_state *state)1558{1559struct object_id tree, parent, commit;1560const struct object_id *old_oid;1561struct commit_list *parents = NULL;1562const char*reflog_msg, *author;1563struct strbuf sb = STRBUF_INIT;15641565if(run_hook_le(NULL,"pre-applypatch", NULL))1566exit(1);15671568if(write_cache_as_tree(&tree,0, NULL))1569die(_("git write-tree failed to write a tree"));15701571if(!get_oid_commit("HEAD", &parent)) {1572 old_oid = &parent;1573commit_list_insert(lookup_commit(the_repository, &parent),1574&parents);1575}else{1576 old_oid = NULL;1577say(state, stderr,_("applying to an empty history"));1578}15791580 author =fmt_ident(state->author_name, state->author_email,1581 state->ignore_date ? NULL : state->author_date,1582 IDENT_STRICT);15831584if(state->committer_date_is_author_date)1585setenv("GIT_COMMITTER_DATE",1586 state->ignore_date ?"": state->author_date,1);15871588if(commit_tree(state->msg, state->msg_len, &tree, parents, &commit,1589 author, state->sign_commit))1590die(_("failed to write commit object"));15911592 reflog_msg =getenv("GIT_REFLOG_ACTION");1593if(!reflog_msg)1594 reflog_msg ="am";15951596strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1597 state->msg);15981599update_ref(sb.buf,"HEAD", &commit, old_oid,0,1600 UPDATE_REFS_DIE_ON_ERR);16011602if(state->rebasing) {1603FILE*fp =xfopen(am_path(state,"rewritten"),"a");16041605assert(!is_null_oid(&state->orig_commit));1606fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1607fprintf(fp,"%s\n",oid_to_hex(&commit));1608fclose(fp);1609}16101611run_hook_le(NULL,"post-applypatch", NULL);16121613strbuf_release(&sb);1614}16151616/**1617 * Validates the am_state for resuming -- the "msg" and authorship fields must1618 * be filled up.1619 */1620static voidvalidate_resume_state(const struct am_state *state)1621{1622if(!state->msg)1623die(_("cannot resume:%sdoes not exist."),1624am_path(state,"final-commit"));16251626if(!state->author_name || !state->author_email || !state->author_date)1627die(_("cannot resume:%sdoes not exist."),1628am_path(state,"author-script"));1629}16301631/**1632 * Interactively prompt the user on whether the current patch should be1633 * applied.1634 *1635 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1636 * skip it.1637 */1638static intdo_interactive(struct am_state *state)1639{1640assert(state->msg);16411642if(!isatty(0))1643die(_("cannot be interactive without stdin connected to a terminal."));16441645for(;;) {1646const char*reply;16471648puts(_("Commit Body is:"));1649puts("--------------------------");1650printf("%s", state->msg);1651puts("--------------------------");16521653/*1654 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1655 * in your translation. The program will only accept English1656 * input at this point.1657 */1658 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);16591660if(!reply) {1661continue;1662}else if(*reply =='y'|| *reply =='Y') {1663return0;1664}else if(*reply =='a'|| *reply =='A') {1665 state->interactive =0;1666return0;1667}else if(*reply =='n'|| *reply =='N') {1668return1;1669}else if(*reply =='e'|| *reply =='E') {1670struct strbuf msg = STRBUF_INIT;16711672if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1673free(state->msg);1674 state->msg =strbuf_detach(&msg, &state->msg_len);1675}1676strbuf_release(&msg);1677}else if(*reply =='v'|| *reply =='V') {1678const char*pager =git_pager(1);1679struct child_process cp = CHILD_PROCESS_INIT;16801681if(!pager)1682 pager ="cat";1683prepare_pager_args(&cp, pager);1684argv_array_push(&cp.args,am_path(state,"patch"));1685run_command(&cp);1686}1687}1688}16891690/**1691 * Applies all queued mail.1692 *1693 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1694 * well as the state directory's "patch" file is used as-is for applying the1695 * patch and committing it.1696 */1697static voidam_run(struct am_state *state,int resume)1698{1699const char*argv_gc_auto[] = {"gc","--auto", NULL};1700struct strbuf sb = STRBUF_INIT;17011702unlink(am_path(state,"dirtyindex"));17031704refresh_and_write_cache();17051706if(index_has_changes(&the_index, NULL, &sb)) {1707write_state_bool(state,"dirtyindex",1);1708die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1709}17101711strbuf_release(&sb);17121713while(state->cur <= state->last) {1714const char*mail =am_path(state,msgnum(state));1715int apply_status;17161717reset_ident_date();17181719if(!file_exists(mail))1720goto next;17211722if(resume) {1723validate_resume_state(state);1724}else{1725int skip;17261727if(state->rebasing)1728 skip =parse_mail_rebase(state, mail);1729else1730 skip =parse_mail(state, mail);17311732if(skip)1733goto next;/* mail should be skipped */17341735if(state->signoff)1736am_append_signoff(state);17371738write_author_script(state);1739write_commit_msg(state);1740}17411742if(state->interactive &&do_interactive(state))1743goto next;17441745if(run_applypatch_msg_hook(state))1746exit(1);17471748say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);17491750 apply_status =run_apply(state, NULL);17511752if(apply_status && state->threeway) {1753struct strbuf sb = STRBUF_INIT;17541755strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1756 apply_status =fall_back_threeway(state, sb.buf);1757strbuf_release(&sb);17581759/*1760 * Applying the patch to an earlier tree and merging1761 * the result may have produced the same tree as ours.1762 */1763if(!apply_status &&1764!index_has_changes(&the_index, NULL, NULL)) {1765say(state, stdout,_("No changes -- Patch already applied."));1766goto next;1767}1768}17691770if(apply_status) {1771printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1772linelen(state->msg), state->msg);17731774if(advice_amworkdir)1775advise(_("Use 'git am --show-current-patch' to see the failed patch"));17761777die_user_resolve(state);1778}17791780do_commit(state);17811782next:1783am_next(state);17841785if(resume)1786am_load(state);1787 resume =0;1788}17891790if(!is_empty_or_missing_file(am_path(state,"rewritten"))) {1791assert(state->rebasing);1792copy_notes_for_rebase(state);1793run_post_rewrite_hook(state);1794}17951796/*1797 * In rebasing mode, it's up to the caller to take care of1798 * housekeeping.1799 */1800if(!state->rebasing) {1801am_destroy(state);1802close_all_packs(the_repository->objects);1803run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1804}1805}18061807/**1808 * Resume the current am session after patch application failure. The user did1809 * all the hard work, and we do not have to do any patch application. Just1810 * trust and commit what the user has in the index and working tree.1811 */1812static voidam_resolve(struct am_state *state)1813{1814validate_resume_state(state);18151816say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18171818if(!index_has_changes(&the_index, NULL, NULL)) {1819printf_ln(_("No changes - did you forget to use 'git add'?\n"1820"If there is nothing left to stage, chances are that something else\n"1821"already introduced the same changes; you might want to skip this patch."));1822die_user_resolve(state);1823}18241825if(unmerged_cache()) {1826printf_ln(_("You still have unmerged paths in your index.\n"1827"You should 'git add' each file with resolved conflicts to mark them as such.\n"1828"You might run `git rm` on a file to accept\"deleted by them\"for it."));1829die_user_resolve(state);1830}18311832if(state->interactive) {1833write_index_patch(state);1834if(do_interactive(state))1835goto next;1836}18371838repo_rerere(the_repository,0);18391840do_commit(state);18411842next:1843am_next(state);1844am_load(state);1845am_run(state,0);1846}18471848/**1849 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1850 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1851 * failure.1852 */1853static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1854{1855struct lock_file lock_file = LOCK_INIT;1856struct unpack_trees_options opts;1857struct tree_desc t[2];18581859if(parse_tree(head) ||parse_tree(remote))1860return-1;18611862hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);18631864refresh_cache(REFRESH_QUIET);18651866memset(&opts,0,sizeof(opts));1867 opts.head_idx =1;1868 opts.src_index = &the_index;1869 opts.dst_index = &the_index;1870 opts.update =1;1871 opts.merge =1;1872 opts.reset = reset;1873 opts.fn = twoway_merge;1874init_tree_desc(&t[0], head->buffer, head->size);1875init_tree_desc(&t[1], remote->buffer, remote->size);18761877if(unpack_trees(2, t, &opts)) {1878rollback_lock_file(&lock_file);1879return-1;1880}18811882if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1883die(_("unable to write new index file"));18841885return0;1886}18871888/**1889 * Merges a tree into the index. The index's stat info will take precedence1890 * over the merged tree's. Returns 0 on success, -1 on failure.1891 */1892static intmerge_tree(struct tree *tree)1893{1894struct lock_file lock_file = LOCK_INIT;1895struct unpack_trees_options opts;1896struct tree_desc t[1];18971898if(parse_tree(tree))1899return-1;19001901hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);19021903memset(&opts,0,sizeof(opts));1904 opts.head_idx =1;1905 opts.src_index = &the_index;1906 opts.dst_index = &the_index;1907 opts.merge =1;1908 opts.fn = oneway_merge;1909init_tree_desc(&t[0], tree->buffer, tree->size);19101911if(unpack_trees(1, t, &opts)) {1912rollback_lock_file(&lock_file);1913return-1;1914}19151916if(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))1917die(_("unable to write new index file"));19181919return0;1920}19211922/**1923 * Clean the index without touching entries that are not modified between1924 * `head` and `remote`.1925 */1926static intclean_index(const struct object_id *head,const struct object_id *remote)1927{1928struct tree *head_tree, *remote_tree, *index_tree;1929struct object_id index;19301931 head_tree =parse_tree_indirect(head);1932if(!head_tree)1933returnerror(_("Could not parse object '%s'."),oid_to_hex(head));19341935 remote_tree =parse_tree_indirect(remote);1936if(!remote_tree)1937returnerror(_("Could not parse object '%s'."),oid_to_hex(remote));19381939read_cache_unmerged();19401941if(fast_forward_to(head_tree, head_tree,1))1942return-1;19431944if(write_cache_as_tree(&index,0, NULL))1945return-1;19461947 index_tree =parse_tree_indirect(&index);1948if(!index_tree)1949returnerror(_("Could not parse object '%s'."),oid_to_hex(&index));19501951if(fast_forward_to(index_tree, remote_tree,0))1952return-1;19531954if(merge_tree(remote_tree))1955return-1;19561957remove_branch_state(the_repository);19581959return0;1960}19611962/**1963 * Resets rerere's merge resolution metadata.1964 */1965static voidam_rerere_clear(void)1966{1967struct string_list merge_rr = STRING_LIST_INIT_DUP;1968rerere_clear(the_repository, &merge_rr);1969string_list_clear(&merge_rr,1);1970}19711972/**1973 * Resume the current am session by skipping the current patch.1974 */1975static voidam_skip(struct am_state *state)1976{1977struct object_id head;19781979am_rerere_clear();19801981if(get_oid("HEAD", &head))1982oidcpy(&head, the_hash_algo->empty_tree);19831984if(clean_index(&head, &head))1985die(_("failed to clean index"));19861987if(state->rebasing) {1988FILE*fp =xfopen(am_path(state,"rewritten"),"a");19891990assert(!is_null_oid(&state->orig_commit));1991fprintf(fp,"%s",oid_to_hex(&state->orig_commit));1992fprintf(fp,"%s\n",oid_to_hex(&head));1993fclose(fp);1994}19951996am_next(state);1997am_load(state);1998am_run(state,0);1999}20002001/**2002 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2003 *2004 * It is not safe to reset HEAD when:2005 * 1. git-am previously failed because the index was dirty.2006 * 2. HEAD has moved since git-am previously failed.2007 */2008static intsafe_to_abort(const struct am_state *state)2009{2010struct strbuf sb = STRBUF_INIT;2011struct object_id abort_safety, head;20122013if(file_exists(am_path(state,"dirtyindex")))2014return0;20152016if(read_state_file(&sb, state,"abort-safety",1) >0) {2017if(get_oid_hex(sb.buf, &abort_safety))2018die(_("could not parse%s"),am_path(state,"abort-safety"));2019}else2020oidclr(&abort_safety);2021strbuf_release(&sb);20222023if(get_oid("HEAD", &head))2024oidclr(&head);20252026if(oideq(&head, &abort_safety))2027return1;20282029warning(_("You seem to have moved HEAD since the last 'am' failure.\n"2030"Not rewinding to ORIG_HEAD"));20312032return0;2033}20342035/**2036 * Aborts the current am session if it is safe to do so.2037 */2038static voidam_abort(struct am_state *state)2039{2040struct object_id curr_head, orig_head;2041int has_curr_head, has_orig_head;2042char*curr_branch;20432044if(!safe_to_abort(state)) {2045am_destroy(state);2046return;2047}20482049am_rerere_clear();20502051 curr_branch =resolve_refdup("HEAD",0, &curr_head, NULL);2052 has_curr_head = curr_branch && !is_null_oid(&curr_head);2053if(!has_curr_head)2054oidcpy(&curr_head, the_hash_algo->empty_tree);20552056 has_orig_head = !get_oid("ORIG_HEAD", &orig_head);2057if(!has_orig_head)2058oidcpy(&orig_head, the_hash_algo->empty_tree);20592060clean_index(&curr_head, &orig_head);20612062if(has_orig_head)2063update_ref("am --abort","HEAD", &orig_head,2064 has_curr_head ? &curr_head : NULL,0,2065 UPDATE_REFS_DIE_ON_ERR);2066else if(curr_branch)2067delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);20682069free(curr_branch);2070am_destroy(state);2071}20722073static intshow_patch(struct am_state *state)2074{2075struct strbuf sb = STRBUF_INIT;2076const char*patch_path;2077int len;20782079if(!is_null_oid(&state->orig_commit)) {2080const char*av[4] = {"show", NULL,"--", NULL };2081char*new_oid_str;2082int ret;20832084 av[1] = new_oid_str =xstrdup(oid_to_hex(&state->orig_commit));2085 ret =run_command_v_opt(av, RUN_GIT_CMD);2086free(new_oid_str);2087return ret;2088}20892090 patch_path =am_path(state,msgnum(state));2091 len =strbuf_read_file(&sb, patch_path,0);2092if(len <0)2093die_errno(_("failed to read '%s'"), patch_path);20942095setup_pager();2096write_in_full(1, sb.buf, sb.len);2097strbuf_release(&sb);2098return0;2099}21002101/**2102 * parse_options() callback that validates and sets opt->value to the2103 * PATCH_FORMAT_* enum value corresponding to `arg`.2104 */2105static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2106{2107int*opt_value = opt->value;21082109if(unset)2110*opt_value = PATCH_FORMAT_UNKNOWN;2111else if(!strcmp(arg,"mbox"))2112*opt_value = PATCH_FORMAT_MBOX;2113else if(!strcmp(arg,"stgit"))2114*opt_value = PATCH_FORMAT_STGIT;2115else if(!strcmp(arg,"stgit-series"))2116*opt_value = PATCH_FORMAT_STGIT_SERIES;2117else if(!strcmp(arg,"hg"))2118*opt_value = PATCH_FORMAT_HG;2119else if(!strcmp(arg,"mboxrd"))2120*opt_value = PATCH_FORMAT_MBOXRD;2121else2122returnerror(_("Invalid value for --patch-format:%s"), arg);2123return0;2124}21252126enum resume_mode {2127 RESUME_FALSE =0,2128 RESUME_APPLY,2129 RESUME_RESOLVED,2130 RESUME_SKIP,2131 RESUME_ABORT,2132 RESUME_QUIT,2133 RESUME_SHOW_PATCH2134};21352136static intgit_am_config(const char*k,const char*v,void*cb)2137{2138int status;21392140 status =git_gpg_config(k, v, NULL);2141if(status)2142return status;21432144returngit_default_config(k, v, NULL);2145}21462147intcmd_am(int argc,const char**argv,const char*prefix)2148{2149struct am_state state;2150int binary = -1;2151int keep_cr = -1;2152int patch_format = PATCH_FORMAT_UNKNOWN;2153enum resume_mode resume = RESUME_FALSE;2154int in_progress;2155int ret =0;21562157const char*const usage[] = {2158N_("git am [<options>] [(<mbox> | <Maildir>)...]"),2159N_("git am [<options>] (--continue | --skip | --abort)"),2160 NULL2161};21622163struct option options[] = {2164OPT_BOOL('i',"interactive", &state.interactive,2165N_("run interactively")),2166OPT_HIDDEN_BOOL('b',"binary", &binary,2167N_("historical option -- no-op")),2168OPT_BOOL('3',"3way", &state.threeway,2169N_("allow fall back on 3way merging if needed")),2170OPT__QUIET(&state.quiet,N_("be quiet")),2171OPT_SET_INT('s',"signoff", &state.signoff,2172N_("add a Signed-off-by line to the commit message"),2173 SIGNOFF_EXPLICIT),2174OPT_BOOL('u',"utf8", &state.utf8,2175N_("recode into utf8 (default)")),2176OPT_SET_INT('k',"keep", &state.keep,2177N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2178OPT_SET_INT(0,"keep-non-patch", &state.keep,2179N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2180OPT_BOOL('m',"message-id", &state.message_id,2181N_("pass -m flag to git-mailinfo")),2182OPT_SET_INT_F(0,"keep-cr", &keep_cr,2183N_("pass --keep-cr flag to git-mailsplit for mbox format"),21841, PARSE_OPT_NONEG),2185OPT_SET_INT_F(0,"no-keep-cr", &keep_cr,2186N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),21870, PARSE_OPT_NONEG),2188OPT_BOOL('c',"scissors", &state.scissors,2189N_("strip everything before a scissors line")),2190OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2191N_("pass it through git-apply"),21920),2193OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2194N_("pass it through git-apply"),2195 PARSE_OPT_NOARG),2196OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2197N_("pass it through git-apply"),2198 PARSE_OPT_NOARG),2199OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2200N_("pass it through git-apply"),22010),2202OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2203N_("pass it through git-apply"),22040),2205OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2206N_("pass it through git-apply"),22070),2208OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2209N_("pass it through git-apply"),22100),2211OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2212N_("pass it through git-apply"),22130),2214OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2215N_("format the patch(es) are in"),2216 parse_opt_patchformat),2217OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2218N_("pass it through git-apply"),2219 PARSE_OPT_NOARG),2220OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2221N_("override error message when patch failure occurs")),2222OPT_CMDMODE(0,"continue", &resume,2223N_("continue applying patches after resolving a conflict"),2224 RESUME_RESOLVED),2225OPT_CMDMODE('r',"resolved", &resume,2226N_("synonyms for --continue"),2227 RESUME_RESOLVED),2228OPT_CMDMODE(0,"skip", &resume,2229N_("skip the current patch"),2230 RESUME_SKIP),2231OPT_CMDMODE(0,"abort", &resume,2232N_("restore the original branch and abort the patching operation."),2233 RESUME_ABORT),2234OPT_CMDMODE(0,"quit", &resume,2235N_("abort the patching operation but keep HEAD where it is."),2236 RESUME_QUIT),2237OPT_CMDMODE(0,"show-current-patch", &resume,2238N_("show the patch being applied."),2239 RESUME_SHOW_PATCH),2240OPT_BOOL(0,"committer-date-is-author-date",2241&state.committer_date_is_author_date,2242N_("lie about committer date")),2243OPT_BOOL(0,"ignore-date", &state.ignore_date,2244N_("use current timestamp for author date")),2245OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2246{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2247N_("GPG-sign commits"),2248 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2249OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2250N_("(internal use for git-rebase)")),2251OPT_END()2252};22532254if(argc ==2&& !strcmp(argv[1],"-h"))2255usage_with_options(usage, options);22562257git_config(git_am_config, NULL);22582259am_state_init(&state);22602261 in_progress =am_in_progress(&state);2262if(in_progress)2263am_load(&state);22642265 argc =parse_options(argc, argv, prefix, options, usage,0);22662267if(binary >=0)2268fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2269"it will be removed. Please do not use it anymore."));22702271/* Ensure a valid committer ident can be constructed */2272git_committer_info(IDENT_STRICT);22732274if(read_index_preload(&the_index, NULL,0) <0)2275die(_("failed to read the index"));22762277if(in_progress) {2278/*2279 * Catch user error to feed us patches when there is a session2280 * in progress:2281 *2282 * 1. mbox path(s) are provided on the command-line.2283 * 2. stdin is not a tty: the user is trying to feed us a patch2284 * from standard input. This is somewhat unreliable -- stdin2285 * could be /dev/null for example and the caller did not2286 * intend to feed us a patch but wanted to continue2287 * unattended.2288 */2289if(argc || (resume == RESUME_FALSE && !isatty(0)))2290die(_("previous rebase directory%sstill exists but mbox given."),2291 state.dir);22922293if(resume == RESUME_FALSE)2294 resume = RESUME_APPLY;22952296if(state.signoff == SIGNOFF_EXPLICIT)2297am_append_signoff(&state);2298}else{2299struct argv_array paths = ARGV_ARRAY_INIT;2300int i;23012302/*2303 * Handle stray state directory in the independent-run case. In2304 * the --rebasing case, it is up to the caller to take care of2305 * stray directories.2306 */2307if(file_exists(state.dir) && !state.rebasing) {2308if(resume == RESUME_ABORT || resume == RESUME_QUIT) {2309am_destroy(&state);2310am_state_release(&state);2311return0;2312}23132314die(_("Stray%sdirectory found.\n"2315"Use\"git am --abort\"to remove it."),2316 state.dir);2317}23182319if(resume)2320die(_("Resolve operation not in progress, we are not resuming."));23212322for(i =0; i < argc; i++) {2323if(is_absolute_path(argv[i]) || !prefix)2324argv_array_push(&paths, argv[i]);2325else2326argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2327}23282329am_setup(&state, patch_format, paths.argv, keep_cr);23302331argv_array_clear(&paths);2332}23332334switch(resume) {2335case RESUME_FALSE:2336am_run(&state,0);2337break;2338case RESUME_APPLY:2339am_run(&state,1);2340break;2341case RESUME_RESOLVED:2342am_resolve(&state);2343break;2344case RESUME_SKIP:2345am_skip(&state);2346break;2347case RESUME_ABORT:2348am_abort(&state);2349break;2350case RESUME_QUIT:2351am_rerere_clear();2352am_destroy(&state);2353break;2354case RESUME_SHOW_PATCH:2355 ret =show_patch(&state);2356break;2357default:2358BUG("invalid resume value");2359}23602361am_state_release(&state);23622363return ret;2364}