1/* 2 * Builtin "git am" 3 * 4 * Based on git-am.sh by Junio C Hamano. 5 */ 6#include"cache.h" 7#include"builtin.h" 8#include"exec_cmd.h" 9#include"parse-options.h" 10#include"dir.h" 11#include"run-command.h" 12#include"quote.h" 13#include"lockfile.h" 14#include"cache-tree.h" 15#include"refs.h" 16#include"commit.h" 17#include"diff.h" 18#include"diffcore.h" 19#include"unpack-trees.h" 20#include"branch.h" 21#include"sequencer.h" 22#include"revision.h" 23#include"merge-recursive.h" 24#include"revision.h" 25#include"log-tree.h" 26#include"notes-utils.h" 27#include"rerere.h" 28#include"prompt.h" 29 30/** 31 * Returns 1 if the file is empty or does not exist, 0 otherwise. 32 */ 33static intis_empty_file(const char*filename) 34{ 35struct stat st; 36 37if(stat(filename, &st) <0) { 38if(errno == ENOENT) 39return1; 40die_errno(_("could not stat%s"), filename); 41} 42 43return!st.st_size; 44} 45 46/** 47 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. 48 */ 49static intstrbuf_getline_crlf(struct strbuf *sb,FILE*fp) 50{ 51if(strbuf_getwholeline(sb, fp,'\n')) 52return EOF; 53if(sb->buf[sb->len -1] =='\n') { 54strbuf_setlen(sb, sb->len -1); 55if(sb->len >0&& sb->buf[sb->len -1] =='\r') 56strbuf_setlen(sb, sb->len -1); 57} 58return0; 59} 60 61/** 62 * Returns the length of the first line of msg. 63 */ 64static intlinelen(const char*msg) 65{ 66returnstrchrnul(msg,'\n') - msg; 67} 68 69/** 70 * Returns true if `str` consists of only whitespace, false otherwise. 71 */ 72static intstr_isspace(const char*str) 73{ 74for(; *str; str++) 75if(!isspace(*str)) 76return0; 77 78return1; 79} 80 81enum patch_format { 82 PATCH_FORMAT_UNKNOWN =0, 83 PATCH_FORMAT_MBOX, 84 PATCH_FORMAT_STGIT, 85 PATCH_FORMAT_STGIT_SERIES, 86 PATCH_FORMAT_HG 87}; 88 89enum keep_type { 90 KEEP_FALSE =0, 91 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 92 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 93}; 94 95enum scissors_type { 96 SCISSORS_UNSET = -1, 97 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 98 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 99}; 100 101enum signoff_type { 102 SIGNOFF_FALSE =0, 103 SIGNOFF_TRUE =1, 104 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 105}; 106 107struct am_state { 108/* state directory path */ 109char*dir; 110 111/* current and last patch numbers, 1-indexed */ 112int cur; 113int last; 114 115/* commit metadata and message */ 116char*author_name; 117char*author_email; 118char*author_date; 119char*msg; 120size_t msg_len; 121 122/* when --rebasing, records the original commit the patch came from */ 123unsigned char orig_commit[GIT_SHA1_RAWSZ]; 124 125/* number of digits in patch filename */ 126int prec; 127 128/* various operating modes and command line options */ 129int interactive; 130int threeway; 131int quiet; 132int signoff;/* enum signoff_type */ 133int utf8; 134int keep;/* enum keep_type */ 135int message_id; 136int scissors;/* enum scissors_type */ 137struct argv_array git_apply_opts; 138const char*resolvemsg; 139int committer_date_is_author_date; 140int ignore_date; 141int allow_rerere_autoupdate; 142const char*sign_commit; 143int rebasing; 144}; 145 146/** 147 * Initializes am_state with the default values. The state directory is set to 148 * dir. 149 */ 150static voidam_state_init(struct am_state *state,const char*dir) 151{ 152int gpgsign; 153 154memset(state,0,sizeof(*state)); 155 156assert(dir); 157 state->dir =xstrdup(dir); 158 159 state->prec =4; 160 161git_config_get_bool("am.threeway", &state->threeway); 162 163 state->utf8 =1; 164 165git_config_get_bool("am.messageid", &state->message_id); 166 167 state->scissors = SCISSORS_UNSET; 168 169argv_array_init(&state->git_apply_opts); 170 171if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 172 state->sign_commit = gpgsign ?"": NULL; 173} 174 175/** 176 * Releases memory allocated by an am_state. 177 */ 178static voidam_state_release(struct am_state *state) 179{ 180free(state->dir); 181free(state->author_name); 182free(state->author_email); 183free(state->author_date); 184free(state->msg); 185argv_array_clear(&state->git_apply_opts); 186} 187 188/** 189 * Returns path relative to the am_state directory. 190 */ 191staticinlineconst char*am_path(const struct am_state *state,const char*path) 192{ 193returnmkpath("%s/%s", state->dir, path); 194} 195 196/** 197 * For convenience to call write_file() 198 */ 199static intwrite_state_text(const struct am_state *state, 200const char*name,const char*string) 201{ 202returnwrite_file(am_path(state, name),"%s", string); 203} 204 205static intwrite_state_count(const struct am_state *state, 206const char*name,int value) 207{ 208returnwrite_file(am_path(state, name),"%d", value); 209} 210 211static intwrite_state_bool(const struct am_state *state, 212const char*name,int value) 213{ 214returnwrite_state_text(state, name, value ?"t":"f"); 215} 216 217/** 218 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 219 * at the end. 220 */ 221static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 222{ 223va_list ap; 224 225va_start(ap, fmt); 226if(!state->quiet) { 227vfprintf(fp, fmt, ap); 228putc('\n', fp); 229} 230va_end(ap); 231} 232 233/** 234 * Returns 1 if there is an am session in progress, 0 otherwise. 235 */ 236static intam_in_progress(const struct am_state *state) 237{ 238struct stat st; 239 240if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 241return0; 242if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 243return0; 244if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 245return0; 246return1; 247} 248 249/** 250 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 251 * number of bytes read on success, -1 if the file does not exist. If `trim` is 252 * set, trailing whitespace will be removed. 253 */ 254static intread_state_file(struct strbuf *sb,const struct am_state *state, 255const char*file,int trim) 256{ 257strbuf_reset(sb); 258 259if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 260if(trim) 261strbuf_trim(sb); 262 263return sb->len; 264} 265 266if(errno == ENOENT) 267return-1; 268 269die_errno(_("could not read '%s'"),am_path(state, file)); 270} 271 272/** 273 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 274 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 275 * match `key`. Returns NULL on failure. 276 * 277 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 278 * the author-script. 279 */ 280static char*read_shell_var(FILE*fp,const char*key) 281{ 282struct strbuf sb = STRBUF_INIT; 283const char*str; 284 285if(strbuf_getline(&sb, fp,'\n')) 286goto fail; 287 288if(!skip_prefix(sb.buf, key, &str)) 289goto fail; 290 291if(!skip_prefix(str,"=", &str)) 292goto fail; 293 294strbuf_remove(&sb,0, str - sb.buf); 295 296 str =sq_dequote(sb.buf); 297if(!str) 298goto fail; 299 300returnstrbuf_detach(&sb, NULL); 301 302fail: 303strbuf_release(&sb); 304return NULL; 305} 306 307/** 308 * Reads and parses the state directory's "author-script" file, and sets 309 * state->author_name, state->author_email and state->author_date accordingly. 310 * Returns 0 on success, -1 if the file could not be parsed. 311 * 312 * The author script is of the format: 313 * 314 * GIT_AUTHOR_NAME='$author_name' 315 * GIT_AUTHOR_EMAIL='$author_email' 316 * GIT_AUTHOR_DATE='$author_date' 317 * 318 * where $author_name, $author_email and $author_date are quoted. We are strict 319 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 320 * script, and thus if the file differs from what this function expects, it is 321 * better to bail out than to do something that the user does not expect. 322 */ 323static intread_author_script(struct am_state *state) 324{ 325const char*filename =am_path(state,"author-script"); 326FILE*fp; 327 328assert(!state->author_name); 329assert(!state->author_email); 330assert(!state->author_date); 331 332 fp =fopen(filename,"r"); 333if(!fp) { 334if(errno == ENOENT) 335return0; 336die_errno(_("could not open '%s' for reading"), filename); 337} 338 339 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 340if(!state->author_name) { 341fclose(fp); 342return-1; 343} 344 345 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 346if(!state->author_email) { 347fclose(fp); 348return-1; 349} 350 351 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 352if(!state->author_date) { 353fclose(fp); 354return-1; 355} 356 357if(fgetc(fp) != EOF) { 358fclose(fp); 359return-1; 360} 361 362fclose(fp); 363return0; 364} 365 366/** 367 * Saves state->author_name, state->author_email and state->author_date in the 368 * state directory's "author-script" file. 369 */ 370static voidwrite_author_script(const struct am_state *state) 371{ 372struct strbuf sb = STRBUF_INIT; 373 374strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 375sq_quote_buf(&sb, state->author_name); 376strbuf_addch(&sb,'\n'); 377 378strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 379sq_quote_buf(&sb, state->author_email); 380strbuf_addch(&sb,'\n'); 381 382strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 383sq_quote_buf(&sb, state->author_date); 384strbuf_addch(&sb,'\n'); 385 386write_state_text(state,"author-script", sb.buf); 387 388strbuf_release(&sb); 389} 390 391/** 392 * Reads the commit message from the state directory's "final-commit" file, 393 * setting state->msg to its contents and state->msg_len to the length of its 394 * contents in bytes. 395 * 396 * Returns 0 on success, -1 if the file does not exist. 397 */ 398static intread_commit_msg(struct am_state *state) 399{ 400struct strbuf sb = STRBUF_INIT; 401 402assert(!state->msg); 403 404if(read_state_file(&sb, state,"final-commit",0) <0) { 405strbuf_release(&sb); 406return-1; 407} 408 409 state->msg =strbuf_detach(&sb, &state->msg_len); 410return0; 411} 412 413/** 414 * Saves state->msg in the state directory's "final-commit" file. 415 */ 416static voidwrite_commit_msg(const struct am_state *state) 417{ 418int fd; 419const char*filename =am_path(state,"final-commit"); 420 421 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 422if(write_in_full(fd, state->msg, state->msg_len) <0) 423die_errno(_("could not write to%s"), filename); 424close(fd); 425} 426 427/** 428 * Loads state from disk. 429 */ 430static voidam_load(struct am_state *state) 431{ 432struct strbuf sb = STRBUF_INIT; 433 434if(read_state_file(&sb, state,"next",1) <0) 435die("BUG: state file 'next' does not exist"); 436 state->cur =strtol(sb.buf, NULL,10); 437 438if(read_state_file(&sb, state,"last",1) <0) 439die("BUG: state file 'last' does not exist"); 440 state->last =strtol(sb.buf, NULL,10); 441 442if(read_author_script(state) <0) 443die(_("could not parse author script")); 444 445read_commit_msg(state); 446 447if(read_state_file(&sb, state,"original-commit",1) <0) 448hashclr(state->orig_commit); 449else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 450die(_("could not parse%s"),am_path(state,"original-commit")); 451 452read_state_file(&sb, state,"threeway",1); 453 state->threeway = !strcmp(sb.buf,"t"); 454 455read_state_file(&sb, state,"quiet",1); 456 state->quiet = !strcmp(sb.buf,"t"); 457 458read_state_file(&sb, state,"sign",1); 459 state->signoff = !strcmp(sb.buf,"t"); 460 461read_state_file(&sb, state,"utf8",1); 462 state->utf8 = !strcmp(sb.buf,"t"); 463 464read_state_file(&sb, state,"keep",1); 465if(!strcmp(sb.buf,"t")) 466 state->keep = KEEP_TRUE; 467else if(!strcmp(sb.buf,"b")) 468 state->keep = KEEP_NON_PATCH; 469else 470 state->keep = KEEP_FALSE; 471 472read_state_file(&sb, state,"messageid",1); 473 state->message_id = !strcmp(sb.buf,"t"); 474 475read_state_file(&sb, state,"scissors",1); 476if(!strcmp(sb.buf,"t")) 477 state->scissors = SCISSORS_TRUE; 478else if(!strcmp(sb.buf,"f")) 479 state->scissors = SCISSORS_FALSE; 480else 481 state->scissors = SCISSORS_UNSET; 482 483read_state_file(&sb, state,"apply-opt",1); 484argv_array_clear(&state->git_apply_opts); 485if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 486die(_("could not parse%s"),am_path(state,"apply-opt")); 487 488 state->rebasing = !!file_exists(am_path(state,"rebasing")); 489 490strbuf_release(&sb); 491} 492 493/** 494 * Removes the am_state directory, forcefully terminating the current am 495 * session. 496 */ 497static voidam_destroy(const struct am_state *state) 498{ 499struct strbuf sb = STRBUF_INIT; 500 501strbuf_addstr(&sb, state->dir); 502remove_dir_recursively(&sb,0); 503strbuf_release(&sb); 504} 505 506/** 507 * Runs applypatch-msg hook. Returns its exit code. 508 */ 509static intrun_applypatch_msg_hook(struct am_state *state) 510{ 511int ret; 512 513assert(state->msg); 514 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 515 516if(!ret) { 517free(state->msg); 518 state->msg = NULL; 519if(read_commit_msg(state) <0) 520die(_("'%s' was deleted by the applypatch-msg hook"), 521am_path(state,"final-commit")); 522} 523 524return ret; 525} 526 527/** 528 * Runs post-rewrite hook. Returns it exit code. 529 */ 530static intrun_post_rewrite_hook(const struct am_state *state) 531{ 532struct child_process cp = CHILD_PROCESS_INIT; 533const char*hook =find_hook("post-rewrite"); 534int ret; 535 536if(!hook) 537return0; 538 539argv_array_push(&cp.args, hook); 540argv_array_push(&cp.args,"rebase"); 541 542 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 543 cp.stdout_to_stderr =1; 544 545 ret =run_command(&cp); 546 547close(cp.in); 548return ret; 549} 550 551/** 552 * Reads the state directory's "rewritten" file, and copies notes from the old 553 * commits listed in the file to their rewritten commits. 554 * 555 * Returns 0 on success, -1 on failure. 556 */ 557static intcopy_notes_for_rebase(const struct am_state *state) 558{ 559struct notes_rewrite_cfg *c; 560struct strbuf sb = STRBUF_INIT; 561const char*invalid_line =_("Malformed input line: '%s'."); 562const char*msg ="Notes added by 'git rebase'"; 563FILE*fp; 564int ret =0; 565 566assert(state->rebasing); 567 568 c =init_copy_notes_for_rewrite("rebase"); 569if(!c) 570return0; 571 572 fp =xfopen(am_path(state,"rewritten"),"r"); 573 574while(!strbuf_getline(&sb, fp,'\n')) { 575unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 576 577if(sb.len != GIT_SHA1_HEXSZ *2+1) { 578 ret =error(invalid_line, sb.buf); 579goto finish; 580} 581 582if(get_sha1_hex(sb.buf, from_obj)) { 583 ret =error(invalid_line, sb.buf); 584goto finish; 585} 586 587if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 588 ret =error(invalid_line, sb.buf); 589goto finish; 590} 591 592if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 593 ret =error(invalid_line, sb.buf); 594goto finish; 595} 596 597if(copy_note_for_rewrite(c, from_obj, to_obj)) 598 ret =error(_("Failed to copy notes from '%s' to '%s'"), 599sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 600} 601 602finish: 603finish_copy_notes_for_rewrite(c, msg); 604fclose(fp); 605strbuf_release(&sb); 606return ret; 607} 608 609/** 610 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 611 * non-indented lines and checking if they look like they begin with valid 612 * header field names. 613 * 614 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 615 */ 616static intis_mail(FILE*fp) 617{ 618const char*header_regex ="^[!-9;-~]+:"; 619struct strbuf sb = STRBUF_INIT; 620 regex_t regex; 621int ret =1; 622 623if(fseek(fp,0L, SEEK_SET)) 624die_errno(_("fseek failed")); 625 626if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 627die("invalid pattern:%s", header_regex); 628 629while(!strbuf_getline_crlf(&sb, fp)) { 630if(!sb.len) 631break;/* End of header */ 632 633/* Ignore indented folded lines */ 634if(*sb.buf =='\t'|| *sb.buf ==' ') 635continue; 636 637/* It's a header if it matches header_regex */ 638if(regexec(®ex, sb.buf,0, NULL,0)) { 639 ret =0; 640goto done; 641} 642} 643 644done: 645regfree(®ex); 646strbuf_release(&sb); 647return ret; 648} 649 650/** 651 * Attempts to detect the patch_format of the patches contained in `paths`, 652 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 653 * detection fails. 654 */ 655static intdetect_patch_format(const char**paths) 656{ 657enum patch_format ret = PATCH_FORMAT_UNKNOWN; 658struct strbuf l1 = STRBUF_INIT; 659struct strbuf l2 = STRBUF_INIT; 660struct strbuf l3 = STRBUF_INIT; 661FILE*fp; 662 663/* 664 * We default to mbox format if input is from stdin and for directories 665 */ 666if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 667return PATCH_FORMAT_MBOX; 668 669/* 670 * Otherwise, check the first few lines of the first patch, starting 671 * from the first non-blank line, to try to detect its format. 672 */ 673 674 fp =xfopen(*paths,"r"); 675 676while(!strbuf_getline_crlf(&l1, fp)) { 677if(l1.len) 678break; 679} 680 681if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 682 ret = PATCH_FORMAT_MBOX; 683goto done; 684} 685 686if(starts_with(l1.buf,"# This series applies on GIT commit")) { 687 ret = PATCH_FORMAT_STGIT_SERIES; 688goto done; 689} 690 691if(!strcmp(l1.buf,"# HG changeset patch")) { 692 ret = PATCH_FORMAT_HG; 693goto done; 694} 695 696strbuf_reset(&l2); 697strbuf_getline_crlf(&l2, fp); 698strbuf_reset(&l3); 699strbuf_getline_crlf(&l3, fp); 700 701/* 702 * If the second line is empty and the third is a From, Author or Date 703 * entry, this is likely an StGit patch. 704 */ 705if(l1.len && !l2.len && 706(starts_with(l3.buf,"From:") || 707starts_with(l3.buf,"Author:") || 708starts_with(l3.buf,"Date:"))) { 709 ret = PATCH_FORMAT_STGIT; 710goto done; 711} 712 713if(l1.len &&is_mail(fp)) { 714 ret = PATCH_FORMAT_MBOX; 715goto done; 716} 717 718done: 719fclose(fp); 720strbuf_release(&l1); 721return ret; 722} 723 724/** 725 * Splits out individual email patches from `paths`, where each path is either 726 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 727 */ 728static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 729{ 730struct child_process cp = CHILD_PROCESS_INIT; 731struct strbuf last = STRBUF_INIT; 732 733 cp.git_cmd =1; 734argv_array_push(&cp.args,"mailsplit"); 735argv_array_pushf(&cp.args,"-d%d", state->prec); 736argv_array_pushf(&cp.args,"-o%s", state->dir); 737argv_array_push(&cp.args,"-b"); 738if(keep_cr) 739argv_array_push(&cp.args,"--keep-cr"); 740argv_array_push(&cp.args,"--"); 741argv_array_pushv(&cp.args, paths); 742 743if(capture_command(&cp, &last,8)) 744return-1; 745 746 state->cur =1; 747 state->last =strtol(last.buf, NULL,10); 748 749return0; 750} 751 752/** 753 * Callback signature for split_mail_conv(). The foreign patch should be 754 * read from `in`, and the converted patch (in RFC2822 mail format) should be 755 * written to `out`. Return 0 on success, or -1 on failure. 756 */ 757typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 758 759/** 760 * Calls `fn` for each file in `paths` to convert the foreign patch to the 761 * RFC2822 mail format suitable for parsing with git-mailinfo. 762 * 763 * Returns 0 on success, -1 on failure. 764 */ 765static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 766const char**paths,int keep_cr) 767{ 768static const char*stdin_only[] = {"-", NULL}; 769int i; 770 771if(!*paths) 772 paths = stdin_only; 773 774for(i =0; *paths; paths++, i++) { 775FILE*in, *out; 776const char*mail; 777int ret; 778 779if(!strcmp(*paths,"-")) 780 in = stdin; 781else 782 in =fopen(*paths,"r"); 783 784if(!in) 785returnerror(_("could not open '%s' for reading:%s"), 786*paths,strerror(errno)); 787 788 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 789 790 out =fopen(mail,"w"); 791if(!out) 792returnerror(_("could not open '%s' for writing:%s"), 793 mail,strerror(errno)); 794 795 ret =fn(out, in, keep_cr); 796 797fclose(out); 798fclose(in); 799 800if(ret) 801returnerror(_("could not parse patch '%s'"), *paths); 802} 803 804 state->cur =1; 805 state->last = i; 806return0; 807} 808 809/** 810 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 811 * message suitable for parsing with git-mailinfo. 812 */ 813static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 814{ 815struct strbuf sb = STRBUF_INIT; 816int subject_printed =0; 817 818while(!strbuf_getline(&sb, in,'\n')) { 819const char*str; 820 821if(str_isspace(sb.buf)) 822continue; 823else if(skip_prefix(sb.buf,"Author:", &str)) 824fprintf(out,"From:%s\n", str); 825else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 826fprintf(out,"%s\n", sb.buf); 827else if(!subject_printed) { 828fprintf(out,"Subject:%s\n", sb.buf); 829 subject_printed =1; 830}else{ 831fprintf(out,"\n%s\n", sb.buf); 832break; 833} 834} 835 836strbuf_reset(&sb); 837while(strbuf_fread(&sb,8192, in) >0) { 838fwrite(sb.buf,1, sb.len, out); 839strbuf_reset(&sb); 840} 841 842strbuf_release(&sb); 843return0; 844} 845 846/** 847 * This function only supports a single StGit series file in `paths`. 848 * 849 * Given an StGit series file, converts the StGit patches in the series into 850 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 851 * the state directory. 852 * 853 * Returns 0 on success, -1 on failure. 854 */ 855static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 856int keep_cr) 857{ 858const char*series_dir; 859char*series_dir_buf; 860FILE*fp; 861struct argv_array patches = ARGV_ARRAY_INIT; 862struct strbuf sb = STRBUF_INIT; 863int ret; 864 865if(!paths[0] || paths[1]) 866returnerror(_("Only one StGIT patch series can be applied at once")); 867 868 series_dir_buf =xstrdup(*paths); 869 series_dir =dirname(series_dir_buf); 870 871 fp =fopen(*paths,"r"); 872if(!fp) 873returnerror(_("could not open '%s' for reading:%s"), *paths, 874strerror(errno)); 875 876while(!strbuf_getline(&sb, fp,'\n')) { 877if(*sb.buf =='#') 878continue;/* skip comment lines */ 879 880argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 881} 882 883fclose(fp); 884strbuf_release(&sb); 885free(series_dir_buf); 886 887 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 888 889argv_array_clear(&patches); 890return ret; 891} 892 893/** 894 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 895 * message suitable for parsing with git-mailinfo. 896 */ 897static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 898{ 899struct strbuf sb = STRBUF_INIT; 900 901while(!strbuf_getline(&sb, in,'\n')) { 902const char*str; 903 904if(skip_prefix(sb.buf,"# User ", &str)) 905fprintf(out,"From:%s\n", str); 906else if(skip_prefix(sb.buf,"# Date ", &str)) { 907unsigned long timestamp; 908long tz, tz2; 909char*end; 910 911 errno =0; 912 timestamp =strtoul(str, &end,10); 913if(errno) 914returnerror(_("invalid timestamp")); 915 916if(!skip_prefix(end," ", &str)) 917returnerror(_("invalid Date line")); 918 919 errno =0; 920 tz =strtol(str, &end,10); 921if(errno) 922returnerror(_("invalid timezone offset")); 923 924if(*end) 925returnerror(_("invalid Date line")); 926 927/* 928 * mercurial's timezone is in seconds west of UTC, 929 * however git's timezone is in hours + minutes east of 930 * UTC. Convert it. 931 */ 932 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 933if(tz >0) 934 tz2 = -tz2; 935 936fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 937}else if(starts_with(sb.buf,"# ")) { 938continue; 939}else{ 940fprintf(out,"\n%s\n", sb.buf); 941break; 942} 943} 944 945strbuf_reset(&sb); 946while(strbuf_fread(&sb,8192, in) >0) { 947fwrite(sb.buf,1, sb.len, out); 948strbuf_reset(&sb); 949} 950 951strbuf_release(&sb); 952return0; 953} 954 955/** 956 * Splits a list of files/directories into individual email patches. Each path 957 * in `paths` must be a file/directory that is formatted according to 958 * `patch_format`. 959 * 960 * Once split out, the individual email patches will be stored in the state 961 * directory, with each patch's filename being its index, padded to state->prec 962 * digits. 963 * 964 * state->cur will be set to the index of the first mail, and state->last will 965 * be set to the index of the last mail. 966 * 967 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 968 * to disable this behavior, -1 to use the default configured setting. 969 * 970 * Returns 0 on success, -1 on failure. 971 */ 972static intsplit_mail(struct am_state *state,enum patch_format patch_format, 973const char**paths,int keep_cr) 974{ 975if(keep_cr <0) { 976 keep_cr =0; 977git_config_get_bool("am.keepcr", &keep_cr); 978} 979 980switch(patch_format) { 981case PATCH_FORMAT_MBOX: 982returnsplit_mail_mbox(state, paths, keep_cr); 983case PATCH_FORMAT_STGIT: 984returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 985case PATCH_FORMAT_STGIT_SERIES: 986returnsplit_mail_stgit_series(state, paths, keep_cr); 987case PATCH_FORMAT_HG: 988returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 989default: 990die("BUG: invalid patch_format"); 991} 992return-1; 993} 994 995/** 996 * Setup a new am session for applying patches 997 */ 998static voidam_setup(struct am_state *state,enum patch_format patch_format, 999const char**paths,int keep_cr)1000{1001unsigned char curr_head[GIT_SHA1_RAWSZ];1002const char*str;1003struct strbuf sb = STRBUF_INIT;10041005if(!patch_format)1006 patch_format =detect_patch_format(paths);10071008if(!patch_format) {1009fprintf_ln(stderr,_("Patch format detection failed."));1010exit(128);1011}10121013if(mkdir(state->dir,0777) <0&& errno != EEXIST)1014die_errno(_("failed to create directory '%s'"), state->dir);10151016if(split_mail(state, patch_format, paths, keep_cr) <0) {1017am_destroy(state);1018die(_("Failed to split patches."));1019}10201021if(state->rebasing)1022 state->threeway =1;10231024write_state_bool(state,"threeway", state->threeway);1025write_state_bool(state,"quiet", state->quiet);1026write_state_bool(state,"sign", state->signoff);1027write_state_bool(state,"utf8", state->utf8);10281029switch(state->keep) {1030case KEEP_FALSE:1031 str ="f";1032break;1033case KEEP_TRUE:1034 str ="t";1035break;1036case KEEP_NON_PATCH:1037 str ="b";1038break;1039default:1040die("BUG: invalid value for state->keep");1041}10421043write_state_text(state,"keep", str);1044write_state_bool(state,"messageid", state->message_id);10451046switch(state->scissors) {1047case SCISSORS_UNSET:1048 str ="";1049break;1050case SCISSORS_FALSE:1051 str ="f";1052break;1053case SCISSORS_TRUE:1054 str ="t";1055break;1056default:1057die("BUG: invalid value for state->scissors");1058}1059write_state_text(state,"scissors", str);10601061sq_quote_argv(&sb, state->git_apply_opts.argv,0);1062write_state_text(state,"apply-opt", sb.buf);10631064if(state->rebasing)1065write_state_text(state,"rebasing","");1066else1067write_state_text(state,"applying","");10681069if(!get_sha1("HEAD", curr_head)) {1070write_state_text(state,"abort-safety",sha1_to_hex(curr_head));1071if(!state->rebasing)1072update_ref("am","ORIG_HEAD", curr_head, NULL,0,1073 UPDATE_REFS_DIE_ON_ERR);1074}else{1075write_state_text(state,"abort-safety","");1076if(!state->rebasing)1077delete_ref("ORIG_HEAD", NULL,0);1078}10791080/*1081 * NOTE: Since the "next" and "last" files determine if an am_state1082 * session is in progress, they should be written last.1083 */10841085write_state_count(state,"next", state->cur);1086write_state_count(state,"last", state->last);10871088strbuf_release(&sb);1089}10901091/**1092 * Increments the patch pointer, and cleans am_state for the application of the1093 * next patch.1094 */1095static voidam_next(struct am_state *state)1096{1097unsigned char head[GIT_SHA1_RAWSZ];10981099free(state->author_name);1100 state->author_name = NULL;11011102free(state->author_email);1103 state->author_email = NULL;11041105free(state->author_date);1106 state->author_date = NULL;11071108free(state->msg);1109 state->msg = NULL;1110 state->msg_len =0;11111112unlink(am_path(state,"author-script"));1113unlink(am_path(state,"final-commit"));11141115hashclr(state->orig_commit);1116unlink(am_path(state,"original-commit"));11171118if(!get_sha1("HEAD", head))1119write_state_text(state,"abort-safety",sha1_to_hex(head));1120else1121write_state_text(state,"abort-safety","");11221123 state->cur++;1124write_state_count(state,"next", state->cur);1125}11261127/**1128 * Returns the filename of the current patch email.1129 */1130static const char*msgnum(const struct am_state *state)1131{1132static struct strbuf sb = STRBUF_INIT;11331134strbuf_reset(&sb);1135strbuf_addf(&sb,"%0*d", state->prec, state->cur);11361137return sb.buf;1138}11391140/**1141 * Refresh and write index.1142 */1143static voidrefresh_and_write_cache(void)1144{1145struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11461147hold_locked_index(lock_file,1);1148refresh_cache(REFRESH_QUIET);1149if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1150die(_("unable to write index file"));1151}11521153/**1154 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1155 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1156 * strbuf is provided, the space-separated list of files that differ will be1157 * appended to it.1158 */1159static intindex_has_changes(struct strbuf *sb)1160{1161unsigned char head[GIT_SHA1_RAWSZ];1162int i;11631164if(!get_sha1_tree("HEAD", head)) {1165struct diff_options opt;11661167diff_setup(&opt);1168DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1169if(!sb)1170DIFF_OPT_SET(&opt, QUICK);1171do_diff_cache(head, &opt);1172diffcore_std(&opt);1173for(i =0; sb && i < diff_queued_diff.nr; i++) {1174if(i)1175strbuf_addch(sb,' ');1176strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1177}1178diff_flush(&opt);1179returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1180}else{1181for(i =0; sb && i < active_nr; i++) {1182if(i)1183strbuf_addch(sb,' ');1184strbuf_addstr(sb, active_cache[i]->name);1185}1186return!!active_nr;1187}1188}11891190/**1191 * Dies with a user-friendly message on how to proceed after resolving the1192 * problem. This message can be overridden with state->resolvemsg.1193 */1194static void NORETURN die_user_resolve(const struct am_state *state)1195{1196if(state->resolvemsg) {1197printf_ln("%s", state->resolvemsg);1198}else{1199const char*cmdline = state->interactive ?"git am -i":"git am";12001201printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1202printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1203printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1204}12051206exit(128);1207}12081209/**1210 * Appends signoff to the "msg" field of the am_state.1211 */1212static voidam_append_signoff(struct am_state *state)1213{1214struct strbuf sb = STRBUF_INIT;12151216strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1217append_signoff(&sb,0,0);1218 state->msg =strbuf_detach(&sb, &state->msg_len);1219}12201221/**1222 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1223 * state->msg will be set to the patch message. state->author_name,1224 * state->author_email and state->author_date will be set to the patch author's1225 * name, email and date respectively. The patch body will be written to the1226 * state directory's "patch" file.1227 *1228 * Returns 1 if the patch should be skipped, 0 otherwise.1229 */1230static intparse_mail(struct am_state *state,const char*mail)1231{1232FILE*fp;1233struct child_process cp = CHILD_PROCESS_INIT;1234struct strbuf sb = STRBUF_INIT;1235struct strbuf msg = STRBUF_INIT;1236struct strbuf author_name = STRBUF_INIT;1237struct strbuf author_date = STRBUF_INIT;1238struct strbuf author_email = STRBUF_INIT;1239int ret =0;12401241 cp.git_cmd =1;1242 cp.in =xopen(mail, O_RDONLY,0);1243 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777);12441245argv_array_push(&cp.args,"mailinfo");1246argv_array_push(&cp.args, state->utf8 ?"-u":"-n");12471248switch(state->keep) {1249case KEEP_FALSE:1250break;1251case KEEP_TRUE:1252argv_array_push(&cp.args,"-k");1253break;1254case KEEP_NON_PATCH:1255argv_array_push(&cp.args,"-b");1256break;1257default:1258die("BUG: invalid value for state->keep");1259}12601261if(state->message_id)1262argv_array_push(&cp.args,"-m");12631264switch(state->scissors) {1265case SCISSORS_UNSET:1266break;1267case SCISSORS_FALSE:1268argv_array_push(&cp.args,"--no-scissors");1269break;1270case SCISSORS_TRUE:1271argv_array_push(&cp.args,"--scissors");1272break;1273default:1274die("BUG: invalid value for state->scissors");1275}12761277argv_array_push(&cp.args,am_path(state,"msg"));1278argv_array_push(&cp.args,am_path(state,"patch"));12791280if(run_command(&cp) <0)1281die("could not parse patch");12821283close(cp.in);1284close(cp.out);12851286/* Extract message and author information */1287 fp =xfopen(am_path(state,"info"),"r");1288while(!strbuf_getline(&sb, fp,'\n')) {1289const char*x;12901291if(skip_prefix(sb.buf,"Subject: ", &x)) {1292if(msg.len)1293strbuf_addch(&msg,'\n');1294strbuf_addstr(&msg, x);1295}else if(skip_prefix(sb.buf,"Author: ", &x))1296strbuf_addstr(&author_name, x);1297else if(skip_prefix(sb.buf,"Email: ", &x))1298strbuf_addstr(&author_email, x);1299else if(skip_prefix(sb.buf,"Date: ", &x))1300strbuf_addstr(&author_date, x);1301}1302fclose(fp);13031304/* Skip pine's internal folder data */1305if(!strcmp(author_name.buf,"Mail System Internal Data")) {1306 ret =1;1307goto finish;1308}13091310if(is_empty_file(am_path(state,"patch"))) {1311printf_ln(_("Patch is empty. Was it split wrong?"));1312die_user_resolve(state);1313}13141315strbuf_addstr(&msg,"\n\n");1316if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0)1317die_errno(_("could not read '%s'"),am_path(state,"msg"));1318stripspace(&msg,0);13191320if(state->signoff)1321append_signoff(&msg,0,0);13221323assert(!state->author_name);1324 state->author_name =strbuf_detach(&author_name, NULL);13251326assert(!state->author_email);1327 state->author_email =strbuf_detach(&author_email, NULL);13281329assert(!state->author_date);1330 state->author_date =strbuf_detach(&author_date, NULL);13311332assert(!state->msg);1333 state->msg =strbuf_detach(&msg, &state->msg_len);13341335finish:1336strbuf_release(&msg);1337strbuf_release(&author_date);1338strbuf_release(&author_email);1339strbuf_release(&author_name);1340strbuf_release(&sb);1341return ret;1342}13431344/**1345 * Sets commit_id to the commit hash where the mail was generated from.1346 * Returns 0 on success, -1 on failure.1347 */1348static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1349{1350struct strbuf sb = STRBUF_INIT;1351FILE*fp =xfopen(mail,"r");1352const char*x;13531354if(strbuf_getline(&sb, fp,'\n'))1355return-1;13561357if(!skip_prefix(sb.buf,"From ", &x))1358return-1;13591360if(get_sha1_hex(x, commit_id) <0)1361return-1;13621363strbuf_release(&sb);1364fclose(fp);1365return0;1366}13671368/**1369 * Sets state->msg, state->author_name, state->author_email, state->author_date1370 * to the commit's respective info.1371 */1372static voidget_commit_info(struct am_state *state,struct commit *commit)1373{1374const char*buffer, *ident_line, *author_date, *msg;1375size_t ident_len;1376struct ident_split ident_split;1377struct strbuf sb = STRBUF_INIT;13781379 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13801381 ident_line =find_commit_header(buffer,"author", &ident_len);13821383if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1384strbuf_add(&sb, ident_line, ident_len);1385die(_("invalid ident line:%s"), sb.buf);1386}13871388assert(!state->author_name);1389if(ident_split.name_begin) {1390strbuf_add(&sb, ident_split.name_begin,1391 ident_split.name_end - ident_split.name_begin);1392 state->author_name =strbuf_detach(&sb, NULL);1393}else1394 state->author_name =xstrdup("");13951396assert(!state->author_email);1397if(ident_split.mail_begin) {1398strbuf_add(&sb, ident_split.mail_begin,1399 ident_split.mail_end - ident_split.mail_begin);1400 state->author_email =strbuf_detach(&sb, NULL);1401}else1402 state->author_email =xstrdup("");14031404 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1405strbuf_addstr(&sb, author_date);1406assert(!state->author_date);1407 state->author_date =strbuf_detach(&sb, NULL);14081409assert(!state->msg);1410 msg =strstr(buffer,"\n\n");1411if(!msg)1412die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1413 state->msg =xstrdup(msg +2);1414 state->msg_len =strlen(state->msg);1415}14161417/**1418 * Writes `commit` as a patch to the state directory's "patch" file.1419 */1420static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1421{1422struct rev_info rev_info;1423FILE*fp;14241425 fp =xfopen(am_path(state,"patch"),"w");1426init_revisions(&rev_info, NULL);1427 rev_info.diff =1;1428 rev_info.abbrev =0;1429 rev_info.disable_stdin =1;1430 rev_info.show_root_diff =1;1431 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1432 rev_info.no_commit_id =1;1433DIFF_OPT_SET(&rev_info.diffopt, BINARY);1434DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1435 rev_info.diffopt.use_color =0;1436 rev_info.diffopt.file = fp;1437 rev_info.diffopt.close_file =1;1438add_pending_object(&rev_info, &commit->object,"");1439diff_setup_done(&rev_info.diffopt);1440log_tree_commit(&rev_info, commit);1441}14421443/**1444 * Writes the diff of the index against HEAD as a patch to the state1445 * directory's "patch" file.1446 */1447static voidwrite_index_patch(const struct am_state *state)1448{1449struct tree *tree;1450unsigned char head[GIT_SHA1_RAWSZ];1451struct rev_info rev_info;1452FILE*fp;14531454if(!get_sha1_tree("HEAD", head))1455 tree =lookup_tree(head);1456else1457 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14581459 fp =xfopen(am_path(state,"patch"),"w");1460init_revisions(&rev_info, NULL);1461 rev_info.diff =1;1462 rev_info.disable_stdin =1;1463 rev_info.no_commit_id =1;1464 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1465 rev_info.diffopt.use_color =0;1466 rev_info.diffopt.file = fp;1467 rev_info.diffopt.close_file =1;1468add_pending_object(&rev_info, &tree->object,"");1469diff_setup_done(&rev_info.diffopt);1470run_diff_index(&rev_info,1);1471}14721473/**1474 * Like parse_mail(), but parses the mail by looking up its commit ID1475 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1476 * of patches.1477 *1478 * state->orig_commit will be set to the original commit ID.1479 *1480 * Will always return 0 as the patch should never be skipped.1481 */1482static intparse_mail_rebase(struct am_state *state,const char*mail)1483{1484struct commit *commit;1485unsigned char commit_sha1[GIT_SHA1_RAWSZ];14861487if(get_mail_commit_sha1(commit_sha1, mail) <0)1488die(_("could not parse%s"), mail);14891490 commit =lookup_commit_or_die(commit_sha1, mail);14911492get_commit_info(state, commit);14931494write_commit_patch(state, commit);14951496hashcpy(state->orig_commit, commit_sha1);1497write_state_text(state,"original-commit",sha1_to_hex(commit_sha1));14981499return0;1500}15011502/**1503 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1504 * `index_file` is not NULL, the patch will be applied to that index.1505 */1506static intrun_apply(const struct am_state *state,const char*index_file)1507{1508struct child_process cp = CHILD_PROCESS_INIT;15091510 cp.git_cmd =1;15111512if(index_file)1513argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);15141515/*1516 * If we are allowed to fall back on 3-way merge, don't give false1517 * errors during the initial attempt.1518 */1519if(state->threeway && !index_file) {1520 cp.no_stdout =1;1521 cp.no_stderr =1;1522}15231524argv_array_push(&cp.args,"apply");15251526argv_array_pushv(&cp.args, state->git_apply_opts.argv);15271528if(index_file)1529argv_array_push(&cp.args,"--cached");1530else1531argv_array_push(&cp.args,"--index");15321533argv_array_push(&cp.args,am_path(state,"patch"));15341535if(run_command(&cp))1536return-1;15371538/* Reload index as git-apply will have modified it. */1539discard_cache();1540read_cache_from(index_file ? index_file :get_index_file());15411542return0;1543}15441545/**1546 * Builds an index that contains just the blobs needed for a 3way merge.1547 */1548static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1549{1550struct child_process cp = CHILD_PROCESS_INIT;15511552 cp.git_cmd =1;1553argv_array_push(&cp.args,"apply");1554argv_array_pushv(&cp.args, state->git_apply_opts.argv);1555argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1556argv_array_push(&cp.args,am_path(state,"patch"));15571558if(run_command(&cp))1559return-1;15601561return0;1562}15631564/**1565 * Attempt a threeway merge, using index_path as the temporary index.1566 */1567static intfall_back_threeway(const struct am_state *state,const char*index_path)1568{1569unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1570 our_tree[GIT_SHA1_RAWSZ];1571const unsigned char*bases[1] = {orig_tree};1572struct merge_options o;1573struct commit *result;1574char*his_tree_name;15751576if(get_sha1("HEAD", our_tree) <0)1577hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);15781579if(build_fake_ancestor(state, index_path))1580returnerror("could not build fake ancestor");15811582discard_cache();1583read_cache_from(index_path);15841585if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1586returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15871588say(state, stdout,_("Using index info to reconstruct a base tree..."));15891590if(!state->quiet) {1591/*1592 * List paths that needed 3-way fallback, so that the user can1593 * review them with extra care to spot mismerges.1594 */1595struct rev_info rev_info;1596const char*diff_filter_str ="--diff-filter=AM";15971598init_revisions(&rev_info, NULL);1599 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1600diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1601add_pending_sha1(&rev_info,"HEAD", our_tree,0);1602diff_setup_done(&rev_info.diffopt);1603run_diff_index(&rev_info,1);1604}16051606if(run_apply(state, index_path))1607returnerror(_("Did you hand edit your patch?\n"1608"It does not apply to blobs recorded in its index."));16091610if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1611returnerror("could not write tree");16121613say(state, stdout,_("Falling back to patching base and 3-way merge..."));16141615discard_cache();1616read_cache();16171618/*1619 * This is not so wrong. Depending on which base we picked, orig_tree1620 * may be wildly different from ours, but his_tree has the same set of1621 * wildly different changes in parts the patch did not touch, so1622 * recursive ends up canceling them, saying that we reverted all those1623 * changes.1624 */16251626init_merge_options(&o);16271628 o.branch1 ="HEAD";1629 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1630 o.branch2 = his_tree_name;16311632if(state->quiet)1633 o.verbosity =0;16341635if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1636rerere(state->allow_rerere_autoupdate);1637free(his_tree_name);1638returnerror(_("Failed to merge in the changes."));1639}16401641free(his_tree_name);1642return0;1643}16441645/**1646 * Commits the current index with state->msg as the commit message and1647 * state->author_name, state->author_email and state->author_date as the author1648 * information.1649 */1650static voiddo_commit(const struct am_state *state)1651{1652unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1653 commit[GIT_SHA1_RAWSZ];1654unsigned char*ptr;1655struct commit_list *parents = NULL;1656const char*reflog_msg, *author;1657struct strbuf sb = STRBUF_INIT;16581659if(run_hook_le(NULL,"pre-applypatch", NULL))1660exit(1);16611662if(write_cache_as_tree(tree,0, NULL))1663die(_("git write-tree failed to write a tree"));16641665if(!get_sha1_commit("HEAD", parent)) {1666 ptr = parent;1667commit_list_insert(lookup_commit(parent), &parents);1668}else{1669 ptr = NULL;1670say(state, stderr,_("applying to an empty history"));1671}16721673 author =fmt_ident(state->author_name, state->author_email,1674 state->ignore_date ? NULL : state->author_date,1675 IDENT_STRICT);16761677if(state->committer_date_is_author_date)1678setenv("GIT_COMMITTER_DATE",1679 state->ignore_date ?"": state->author_date,1);16801681if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1682 author, state->sign_commit))1683die(_("failed to write commit object"));16841685 reflog_msg =getenv("GIT_REFLOG_ACTION");1686if(!reflog_msg)1687 reflog_msg ="am";16881689strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1690 state->msg);16911692update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);16931694if(state->rebasing) {1695FILE*fp =xfopen(am_path(state,"rewritten"),"a");16961697assert(!is_null_sha1(state->orig_commit));1698fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1699fprintf(fp,"%s\n",sha1_to_hex(commit));1700fclose(fp);1701}17021703run_hook_le(NULL,"post-applypatch", NULL);17041705strbuf_release(&sb);1706}17071708/**1709 * Validates the am_state for resuming -- the "msg" and authorship fields must1710 * be filled up.1711 */1712static voidvalidate_resume_state(const struct am_state *state)1713{1714if(!state->msg)1715die(_("cannot resume:%sdoes not exist."),1716am_path(state,"final-commit"));17171718if(!state->author_name || !state->author_email || !state->author_date)1719die(_("cannot resume:%sdoes not exist."),1720am_path(state,"author-script"));1721}17221723/**1724 * Interactively prompt the user on whether the current patch should be1725 * applied.1726 *1727 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1728 * skip it.1729 */1730static intdo_interactive(struct am_state *state)1731{1732assert(state->msg);17331734if(!isatty(0))1735die(_("cannot be interactive without stdin connected to a terminal."));17361737for(;;) {1738const char*reply;17391740puts(_("Commit Body is:"));1741puts("--------------------------");1742printf("%s", state->msg);1743puts("--------------------------");17441745/*1746 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1747 * in your translation. The program will only accept English1748 * input at this point.1749 */1750 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17511752if(!reply) {1753continue;1754}else if(*reply =='y'|| *reply =='Y') {1755return0;1756}else if(*reply =='a'|| *reply =='A') {1757 state->interactive =0;1758return0;1759}else if(*reply =='n'|| *reply =='N') {1760return1;1761}else if(*reply =='e'|| *reply =='E') {1762struct strbuf msg = STRBUF_INIT;17631764if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1765free(state->msg);1766 state->msg =strbuf_detach(&msg, &state->msg_len);1767}1768strbuf_release(&msg);1769}else if(*reply =='v'|| *reply =='V') {1770const char*pager =git_pager(1);1771struct child_process cp = CHILD_PROCESS_INIT;17721773if(!pager)1774 pager ="cat";1775argv_array_push(&cp.args, pager);1776argv_array_push(&cp.args,am_path(state,"patch"));1777run_command(&cp);1778}1779}1780}17811782/**1783 * Applies all queued mail.1784 *1785 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1786 * well as the state directory's "patch" file is used as-is for applying the1787 * patch and committing it.1788 */1789static voidam_run(struct am_state *state,int resume)1790{1791const char*argv_gc_auto[] = {"gc","--auto", NULL};1792struct strbuf sb = STRBUF_INIT;17931794unlink(am_path(state,"dirtyindex"));17951796refresh_and_write_cache();17971798if(index_has_changes(&sb)) {1799write_state_bool(state,"dirtyindex",1);1800die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1801}18021803strbuf_release(&sb);18041805while(state->cur <= state->last) {1806const char*mail =am_path(state,msgnum(state));1807int apply_status;18081809if(!file_exists(mail))1810goto next;18111812if(resume) {1813validate_resume_state(state);1814}else{1815int skip;18161817if(state->rebasing)1818 skip =parse_mail_rebase(state, mail);1819else1820 skip =parse_mail(state, mail);18211822if(skip)1823goto next;/* mail should be skipped */18241825write_author_script(state);1826write_commit_msg(state);1827}18281829if(state->interactive &&do_interactive(state))1830goto next;18311832if(run_applypatch_msg_hook(state))1833exit(1);18341835say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18361837 apply_status =run_apply(state, NULL);18381839if(apply_status && state->threeway) {1840struct strbuf sb = STRBUF_INIT;18411842strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1843 apply_status =fall_back_threeway(state, sb.buf);1844strbuf_release(&sb);18451846/*1847 * Applying the patch to an earlier tree and merging1848 * the result may have produced the same tree as ours.1849 */1850if(!apply_status && !index_has_changes(NULL)) {1851say(state, stdout,_("No changes -- Patch already applied."));1852goto next;1853}1854}18551856if(apply_status) {1857int advice_amworkdir =1;18581859printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1860linelen(state->msg), state->msg);18611862git_config_get_bool("advice.amworkdir", &advice_amworkdir);18631864if(advice_amworkdir)1865printf_ln(_("The copy of the patch that failed is found in:%s"),1866am_path(state,"patch"));18671868die_user_resolve(state);1869}18701871do_commit(state);18721873next:1874am_next(state);18751876if(resume)1877am_load(state);1878 resume =0;1879}18801881if(!is_empty_file(am_path(state,"rewritten"))) {1882assert(state->rebasing);1883copy_notes_for_rebase(state);1884run_post_rewrite_hook(state);1885}18861887/*1888 * In rebasing mode, it's up to the caller to take care of1889 * housekeeping.1890 */1891if(!state->rebasing) {1892am_destroy(state);1893run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1894}1895}18961897/**1898 * Resume the current am session after patch application failure. The user did1899 * all the hard work, and we do not have to do any patch application. Just1900 * trust and commit what the user has in the index and working tree.1901 */1902static voidam_resolve(struct am_state *state)1903{1904validate_resume_state(state);19051906say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);19071908if(!index_has_changes(NULL)) {1909printf_ln(_("No changes - did you forget to use 'git add'?\n"1910"If there is nothing left to stage, chances are that something else\n"1911"already introduced the same changes; you might want to skip this patch."));1912die_user_resolve(state);1913}19141915if(unmerged_cache()) {1916printf_ln(_("You still have unmerged paths in your index.\n"1917"Did you forget to use 'git add'?"));1918die_user_resolve(state);1919}19201921if(state->interactive) {1922write_index_patch(state);1923if(do_interactive(state))1924goto next;1925}19261927rerere(0);19281929do_commit(state);19301931next:1932am_next(state);1933am_load(state);1934am_run(state,0);1935}19361937/**1938 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1939 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1940 * failure.1941 */1942static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1943{1944struct lock_file *lock_file;1945struct unpack_trees_options opts;1946struct tree_desc t[2];19471948if(parse_tree(head) ||parse_tree(remote))1949return-1;19501951 lock_file =xcalloc(1,sizeof(struct lock_file));1952hold_locked_index(lock_file,1);19531954refresh_cache(REFRESH_QUIET);19551956memset(&opts,0,sizeof(opts));1957 opts.head_idx =1;1958 opts.src_index = &the_index;1959 opts.dst_index = &the_index;1960 opts.update =1;1961 opts.merge =1;1962 opts.reset = reset;1963 opts.fn = twoway_merge;1964init_tree_desc(&t[0], head->buffer, head->size);1965init_tree_desc(&t[1], remote->buffer, remote->size);19661967if(unpack_trees(2, t, &opts)) {1968rollback_lock_file(lock_file);1969return-1;1970}19711972if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1973die(_("unable to write new index file"));19741975return0;1976}19771978/**1979 * Clean the index without touching entries that are not modified between1980 * `head` and `remote`.1981 */1982static intclean_index(const unsigned char*head,const unsigned char*remote)1983{1984struct lock_file *lock_file;1985struct tree *head_tree, *remote_tree, *index_tree;1986unsigned char index[GIT_SHA1_RAWSZ];1987struct pathspec pathspec;19881989 head_tree =parse_tree_indirect(head);1990if(!head_tree)1991returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));19921993 remote_tree =parse_tree_indirect(remote);1994if(!remote_tree)1995returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));19961997read_cache_unmerged();19981999if(fast_forward_to(head_tree, head_tree,1))2000return-1;20012002if(write_cache_as_tree(index,0, NULL))2003return-1;20042005 index_tree =parse_tree_indirect(index);2006if(!index_tree)2007returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));20082009if(fast_forward_to(index_tree, remote_tree,0))2010return-1;20112012memset(&pathspec,0,sizeof(pathspec));20132014 lock_file =xcalloc(1,sizeof(struct lock_file));2015hold_locked_index(lock_file,1);20162017if(read_tree(remote_tree,0, &pathspec)) {2018rollback_lock_file(lock_file);2019return-1;2020}20212022if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2023die(_("unable to write new index file"));20242025remove_branch_state();20262027return0;2028}20292030/**2031 * Resets rerere's merge resolution metadata.2032 */2033static voidam_rerere_clear(void)2034{2035struct string_list merge_rr = STRING_LIST_INIT_DUP;2036int fd =setup_rerere(&merge_rr,0);20372038if(fd <0)2039return;20402041rerere_clear(&merge_rr);2042string_list_clear(&merge_rr,1);2043}20442045/**2046 * Resume the current am session by skipping the current patch.2047 */2048static voidam_skip(struct am_state *state)2049{2050unsigned char head[GIT_SHA1_RAWSZ];20512052am_rerere_clear();20532054if(get_sha1("HEAD", head))2055hashcpy(head, EMPTY_TREE_SHA1_BIN);20562057if(clean_index(head, head))2058die(_("failed to clean index"));20592060am_next(state);2061am_load(state);2062am_run(state,0);2063}20642065/**2066 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2067 *2068 * It is not safe to reset HEAD when:2069 * 1. git-am previously failed because the index was dirty.2070 * 2. HEAD has moved since git-am previously failed.2071 */2072static intsafe_to_abort(const struct am_state *state)2073{2074struct strbuf sb = STRBUF_INIT;2075unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];20762077if(file_exists(am_path(state,"dirtyindex")))2078return0;20792080if(read_state_file(&sb, state,"abort-safety",1) >0) {2081if(get_sha1_hex(sb.buf, abort_safety))2082die(_("could not parse%s"),am_path(state,"abort_safety"));2083}else2084hashclr(abort_safety);20852086if(get_sha1("HEAD", head))2087hashclr(head);20882089if(!hashcmp(head, abort_safety))2090return1;20912092error(_("You seem to have moved HEAD since the last 'am' failure.\n"2093"Not rewinding to ORIG_HEAD"));20942095return0;2096}20972098/**2099 * Aborts the current am session if it is safe to do so.2100 */2101static voidam_abort(struct am_state *state)2102{2103unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2104int has_curr_head, has_orig_head;2105char*curr_branch;21062107if(!safe_to_abort(state)) {2108am_destroy(state);2109return;2110}21112112am_rerere_clear();21132114 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2115 has_curr_head = !is_null_sha1(curr_head);2116if(!has_curr_head)2117hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);21182119 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2120if(!has_orig_head)2121hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);21222123clean_index(curr_head, orig_head);21242125if(has_orig_head)2126update_ref("am --abort","HEAD", orig_head,2127 has_curr_head ? curr_head : NULL,0,2128 UPDATE_REFS_DIE_ON_ERR);2129else if(curr_branch)2130delete_ref(curr_branch, NULL, REF_NODEREF);21312132free(curr_branch);2133am_destroy(state);2134}21352136/**2137 * parse_options() callback that validates and sets opt->value to the2138 * PATCH_FORMAT_* enum value corresponding to `arg`.2139 */2140static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2141{2142int*opt_value = opt->value;21432144if(!strcmp(arg,"mbox"))2145*opt_value = PATCH_FORMAT_MBOX;2146else if(!strcmp(arg,"stgit"))2147*opt_value = PATCH_FORMAT_STGIT;2148else if(!strcmp(arg,"stgit-series"))2149*opt_value = PATCH_FORMAT_STGIT_SERIES;2150else if(!strcmp(arg,"hg"))2151*opt_value = PATCH_FORMAT_HG;2152else2153returnerror(_("Invalid value for --patch-format:%s"), arg);2154return0;2155}21562157enum resume_mode {2158 RESUME_FALSE =0,2159 RESUME_APPLY,2160 RESUME_RESOLVED,2161 RESUME_SKIP,2162 RESUME_ABORT2163};21642165intcmd_am(int argc,const char**argv,const char*prefix)2166{2167struct am_state state;2168int binary = -1;2169int keep_cr = -1;2170int patch_format = PATCH_FORMAT_UNKNOWN;2171enum resume_mode resume = RESUME_FALSE;2172int in_progress;21732174const char*const usage[] = {2175N_("git am [options] [(<mbox>|<Maildir>)...]"),2176N_("git am [options] (--continue | --skip | --abort)"),2177 NULL2178};21792180struct option options[] = {2181OPT_BOOL('i',"interactive", &state.interactive,2182N_("run interactively")),2183OPT_HIDDEN_BOOL('b',"binary", &binary,2184N_("(historical option -- no-op")),2185OPT_BOOL('3',"3way", &state.threeway,2186N_("allow fall back on 3way merging if needed")),2187OPT__QUIET(&state.quiet,N_("be quiet")),2188OPT_SET_INT('s',"signoff", &state.signoff,2189N_("add a Signed-off-by line to the commit message"),2190 SIGNOFF_EXPLICIT),2191OPT_BOOL('u',"utf8", &state.utf8,2192N_("recode into utf8 (default)")),2193OPT_SET_INT('k',"keep", &state.keep,2194N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2195OPT_SET_INT(0,"keep-non-patch", &state.keep,2196N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2197OPT_BOOL('m',"message-id", &state.message_id,2198N_("pass -m flag to git-mailinfo")),2199{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2200N_("pass --keep-cr flag to git-mailsplit for mbox format"),2201 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2202{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2203N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2204 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2205OPT_BOOL('c',"scissors", &state.scissors,2206N_("strip everything before a scissors line")),2207OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2208N_("pass it through git-apply"),22090),2210OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2211N_("pass it through git-apply"),2212 PARSE_OPT_NOARG),2213OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2214N_("pass it through git-apply"),2215 PARSE_OPT_NOARG),2216OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2217N_("pass it through git-apply"),22180),2219OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2220N_("pass it through git-apply"),22210),2222OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2223N_("pass it through git-apply"),22240),2225OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2226N_("pass it through git-apply"),22270),2228OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2229N_("pass it through git-apply"),22300),2231OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2232N_("format the patch(es) are in"),2233 parse_opt_patchformat),2234OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2235N_("pass it through git-apply"),2236 PARSE_OPT_NOARG),2237OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2238N_("override error message when patch failure occurs")),2239OPT_CMDMODE(0,"continue", &resume,2240N_("continue applying patches after resolving a conflict"),2241 RESUME_RESOLVED),2242OPT_CMDMODE('r',"resolved", &resume,2243N_("synonyms for --continue"),2244 RESUME_RESOLVED),2245OPT_CMDMODE(0,"skip", &resume,2246N_("skip the current patch"),2247 RESUME_SKIP),2248OPT_CMDMODE(0,"abort", &resume,2249N_("restore the original branch and abort the patching operation."),2250 RESUME_ABORT),2251OPT_BOOL(0,"committer-date-is-author-date",2252&state.committer_date_is_author_date,2253N_("lie about committer date")),2254OPT_BOOL(0,"ignore-date", &state.ignore_date,2255N_("use current timestamp for author date")),2256OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2257{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2258N_("GPG-sign commits"),2259 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2260OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2261N_("(internal use for git-rebase)")),2262OPT_END()2263};22642265git_config(git_default_config, NULL);22662267am_state_init(&state,git_path("rebase-apply"));22682269 in_progress =am_in_progress(&state);2270if(in_progress)2271am_load(&state);22722273 argc =parse_options(argc, argv, prefix, options, usage,0);22742275if(binary >=0)2276fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2277"it will be removed. Please do not use it anymore."));22782279/* Ensure a valid committer ident can be constructed */2280git_committer_info(IDENT_STRICT);22812282if(read_index_preload(&the_index, NULL) <0)2283die(_("failed to read the index"));22842285if(in_progress) {2286/*2287 * Catch user error to feed us patches when there is a session2288 * in progress:2289 *2290 * 1. mbox path(s) are provided on the command-line.2291 * 2. stdin is not a tty: the user is trying to feed us a patch2292 * from standard input. This is somewhat unreliable -- stdin2293 * could be /dev/null for example and the caller did not2294 * intend to feed us a patch but wanted to continue2295 * unattended.2296 */2297if(argc || (resume == RESUME_FALSE && !isatty(0)))2298die(_("previous rebase directory%sstill exists but mbox given."),2299 state.dir);23002301if(resume == RESUME_FALSE)2302 resume = RESUME_APPLY;23032304if(state.signoff == SIGNOFF_EXPLICIT)2305am_append_signoff(&state);2306}else{2307struct argv_array paths = ARGV_ARRAY_INIT;2308int i;23092310/*2311 * Handle stray state directory in the independent-run case. In2312 * the --rebasing case, it is up to the caller to take care of2313 * stray directories.2314 */2315if(file_exists(state.dir) && !state.rebasing) {2316if(resume == RESUME_ABORT) {2317am_destroy(&state);2318am_state_release(&state);2319return0;2320}23212322die(_("Stray%sdirectory found.\n"2323"Use\"git am --abort\"to remove it."),2324 state.dir);2325}23262327if(resume)2328die(_("Resolve operation not in progress, we are not resuming."));23292330for(i =0; i < argc; i++) {2331if(is_absolute_path(argv[i]) || !prefix)2332argv_array_push(&paths, argv[i]);2333else2334argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2335}23362337am_setup(&state, patch_format, paths.argv, keep_cr);23382339argv_array_clear(&paths);2340}23412342switch(resume) {2343case RESUME_FALSE:2344am_run(&state,0);2345break;2346case RESUME_APPLY:2347am_run(&state,1);2348break;2349case RESUME_RESOLVED:2350am_resolve(&state);2351break;2352case RESUME_SKIP:2353am_skip(&state);2354break;2355case RESUME_ABORT:2356am_abort(&state);2357break;2358default:2359die("BUG: invalid resume value");2360}23612362am_state_release(&state);23632364return0;2365}