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{ 202const char*fmt; 203 204if(*string && string[strlen(string) -1] !='\n') 205 fmt ="%s\n"; 206else 207 fmt ="%s"; 208returnwrite_file(am_path(state, name), fmt, string); 209} 210 211static intwrite_state_count(const struct am_state *state, 212const char*name,int value) 213{ 214returnwrite_file(am_path(state, name),"%d\n", value); 215} 216 217static intwrite_state_bool(const struct am_state *state, 218const char*name,int value) 219{ 220returnwrite_state_text(state, name, value ?"t":"f"); 221} 222 223/** 224 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 225 * at the end. 226 */ 227static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 228{ 229va_list ap; 230 231va_start(ap, fmt); 232if(!state->quiet) { 233vfprintf(fp, fmt, ap); 234putc('\n', fp); 235} 236va_end(ap); 237} 238 239/** 240 * Returns 1 if there is an am session in progress, 0 otherwise. 241 */ 242static intam_in_progress(const struct am_state *state) 243{ 244struct stat st; 245 246if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 247return0; 248if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 249return0; 250if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 251return0; 252return1; 253} 254 255/** 256 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 257 * number of bytes read on success, -1 if the file does not exist. If `trim` is 258 * set, trailing whitespace will be removed. 259 */ 260static intread_state_file(struct strbuf *sb,const struct am_state *state, 261const char*file,int trim) 262{ 263strbuf_reset(sb); 264 265if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 266if(trim) 267strbuf_trim(sb); 268 269return sb->len; 270} 271 272if(errno == ENOENT) 273return-1; 274 275die_errno(_("could not read '%s'"),am_path(state, file)); 276} 277 278/** 279 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 280 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 281 * match `key`. Returns NULL on failure. 282 * 283 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 284 * the author-script. 285 */ 286static char*read_shell_var(FILE*fp,const char*key) 287{ 288struct strbuf sb = STRBUF_INIT; 289const char*str; 290 291if(strbuf_getline(&sb, fp,'\n')) 292goto fail; 293 294if(!skip_prefix(sb.buf, key, &str)) 295goto fail; 296 297if(!skip_prefix(str,"=", &str)) 298goto fail; 299 300strbuf_remove(&sb,0, str - sb.buf); 301 302 str =sq_dequote(sb.buf); 303if(!str) 304goto fail; 305 306returnstrbuf_detach(&sb, NULL); 307 308fail: 309strbuf_release(&sb); 310return NULL; 311} 312 313/** 314 * Reads and parses the state directory's "author-script" file, and sets 315 * state->author_name, state->author_email and state->author_date accordingly. 316 * Returns 0 on success, -1 if the file could not be parsed. 317 * 318 * The author script is of the format: 319 * 320 * GIT_AUTHOR_NAME='$author_name' 321 * GIT_AUTHOR_EMAIL='$author_email' 322 * GIT_AUTHOR_DATE='$author_date' 323 * 324 * where $author_name, $author_email and $author_date are quoted. We are strict 325 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 326 * script, and thus if the file differs from what this function expects, it is 327 * better to bail out than to do something that the user does not expect. 328 */ 329static intread_author_script(struct am_state *state) 330{ 331const char*filename =am_path(state,"author-script"); 332FILE*fp; 333 334assert(!state->author_name); 335assert(!state->author_email); 336assert(!state->author_date); 337 338 fp =fopen(filename,"r"); 339if(!fp) { 340if(errno == ENOENT) 341return0; 342die_errno(_("could not open '%s' for reading"), filename); 343} 344 345 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 346if(!state->author_name) { 347fclose(fp); 348return-1; 349} 350 351 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 352if(!state->author_email) { 353fclose(fp); 354return-1; 355} 356 357 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 358if(!state->author_date) { 359fclose(fp); 360return-1; 361} 362 363if(fgetc(fp) != EOF) { 364fclose(fp); 365return-1; 366} 367 368fclose(fp); 369return0; 370} 371 372/** 373 * Saves state->author_name, state->author_email and state->author_date in the 374 * state directory's "author-script" file. 375 */ 376static voidwrite_author_script(const struct am_state *state) 377{ 378struct strbuf sb = STRBUF_INIT; 379 380strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 381sq_quote_buf(&sb, state->author_name); 382strbuf_addch(&sb,'\n'); 383 384strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 385sq_quote_buf(&sb, state->author_email); 386strbuf_addch(&sb,'\n'); 387 388strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 389sq_quote_buf(&sb, state->author_date); 390strbuf_addch(&sb,'\n'); 391 392write_state_text(state,"author-script", sb.buf); 393 394strbuf_release(&sb); 395} 396 397/** 398 * Reads the commit message from the state directory's "final-commit" file, 399 * setting state->msg to its contents and state->msg_len to the length of its 400 * contents in bytes. 401 * 402 * Returns 0 on success, -1 if the file does not exist. 403 */ 404static intread_commit_msg(struct am_state *state) 405{ 406struct strbuf sb = STRBUF_INIT; 407 408assert(!state->msg); 409 410if(read_state_file(&sb, state,"final-commit",0) <0) { 411strbuf_release(&sb); 412return-1; 413} 414 415 state->msg =strbuf_detach(&sb, &state->msg_len); 416return0; 417} 418 419/** 420 * Saves state->msg in the state directory's "final-commit" file. 421 */ 422static voidwrite_commit_msg(const struct am_state *state) 423{ 424int fd; 425const char*filename =am_path(state,"final-commit"); 426 427 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 428if(write_in_full(fd, state->msg, state->msg_len) <0) 429die_errno(_("could not write to%s"), filename); 430close(fd); 431} 432 433/** 434 * Loads state from disk. 435 */ 436static voidam_load(struct am_state *state) 437{ 438struct strbuf sb = STRBUF_INIT; 439 440if(read_state_file(&sb, state,"next",1) <0) 441die("BUG: state file 'next' does not exist"); 442 state->cur =strtol(sb.buf, NULL,10); 443 444if(read_state_file(&sb, state,"last",1) <0) 445die("BUG: state file 'last' does not exist"); 446 state->last =strtol(sb.buf, NULL,10); 447 448if(read_author_script(state) <0) 449die(_("could not parse author script")); 450 451read_commit_msg(state); 452 453if(read_state_file(&sb, state,"original-commit",1) <0) 454hashclr(state->orig_commit); 455else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 456die(_("could not parse%s"),am_path(state,"original-commit")); 457 458read_state_file(&sb, state,"threeway",1); 459 state->threeway = !strcmp(sb.buf,"t"); 460 461read_state_file(&sb, state,"quiet",1); 462 state->quiet = !strcmp(sb.buf,"t"); 463 464read_state_file(&sb, state,"sign",1); 465 state->signoff = !strcmp(sb.buf,"t"); 466 467read_state_file(&sb, state,"utf8",1); 468 state->utf8 = !strcmp(sb.buf,"t"); 469 470read_state_file(&sb, state,"keep",1); 471if(!strcmp(sb.buf,"t")) 472 state->keep = KEEP_TRUE; 473else if(!strcmp(sb.buf,"b")) 474 state->keep = KEEP_NON_PATCH; 475else 476 state->keep = KEEP_FALSE; 477 478read_state_file(&sb, state,"messageid",1); 479 state->message_id = !strcmp(sb.buf,"t"); 480 481read_state_file(&sb, state,"scissors",1); 482if(!strcmp(sb.buf,"t")) 483 state->scissors = SCISSORS_TRUE; 484else if(!strcmp(sb.buf,"f")) 485 state->scissors = SCISSORS_FALSE; 486else 487 state->scissors = SCISSORS_UNSET; 488 489read_state_file(&sb, state,"apply-opt",1); 490argv_array_clear(&state->git_apply_opts); 491if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 492die(_("could not parse%s"),am_path(state,"apply-opt")); 493 494 state->rebasing = !!file_exists(am_path(state,"rebasing")); 495 496strbuf_release(&sb); 497} 498 499/** 500 * Removes the am_state directory, forcefully terminating the current am 501 * session. 502 */ 503static voidam_destroy(const struct am_state *state) 504{ 505struct strbuf sb = STRBUF_INIT; 506 507strbuf_addstr(&sb, state->dir); 508remove_dir_recursively(&sb,0); 509strbuf_release(&sb); 510} 511 512/** 513 * Runs applypatch-msg hook. Returns its exit code. 514 */ 515static intrun_applypatch_msg_hook(struct am_state *state) 516{ 517int ret; 518 519assert(state->msg); 520 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 521 522if(!ret) { 523free(state->msg); 524 state->msg = NULL; 525if(read_commit_msg(state) <0) 526die(_("'%s' was deleted by the applypatch-msg hook"), 527am_path(state,"final-commit")); 528} 529 530return ret; 531} 532 533/** 534 * Runs post-rewrite hook. Returns it exit code. 535 */ 536static intrun_post_rewrite_hook(const struct am_state *state) 537{ 538struct child_process cp = CHILD_PROCESS_INIT; 539const char*hook =find_hook("post-rewrite"); 540int ret; 541 542if(!hook) 543return0; 544 545argv_array_push(&cp.args, hook); 546argv_array_push(&cp.args,"rebase"); 547 548 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 549 cp.stdout_to_stderr =1; 550 551 ret =run_command(&cp); 552 553close(cp.in); 554return ret; 555} 556 557/** 558 * Reads the state directory's "rewritten" file, and copies notes from the old 559 * commits listed in the file to their rewritten commits. 560 * 561 * Returns 0 on success, -1 on failure. 562 */ 563static intcopy_notes_for_rebase(const struct am_state *state) 564{ 565struct notes_rewrite_cfg *c; 566struct strbuf sb = STRBUF_INIT; 567const char*invalid_line =_("Malformed input line: '%s'."); 568const char*msg ="Notes added by 'git rebase'"; 569FILE*fp; 570int ret =0; 571 572assert(state->rebasing); 573 574 c =init_copy_notes_for_rewrite("rebase"); 575if(!c) 576return0; 577 578 fp =xfopen(am_path(state,"rewritten"),"r"); 579 580while(!strbuf_getline(&sb, fp,'\n')) { 581unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 582 583if(sb.len != GIT_SHA1_HEXSZ *2+1) { 584 ret =error(invalid_line, sb.buf); 585goto finish; 586} 587 588if(get_sha1_hex(sb.buf, from_obj)) { 589 ret =error(invalid_line, sb.buf); 590goto finish; 591} 592 593if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 594 ret =error(invalid_line, sb.buf); 595goto finish; 596} 597 598if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 599 ret =error(invalid_line, sb.buf); 600goto finish; 601} 602 603if(copy_note_for_rewrite(c, from_obj, to_obj)) 604 ret =error(_("Failed to copy notes from '%s' to '%s'"), 605sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 606} 607 608finish: 609finish_copy_notes_for_rewrite(c, msg); 610fclose(fp); 611strbuf_release(&sb); 612return ret; 613} 614 615/** 616 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 617 * non-indented lines and checking if they look like they begin with valid 618 * header field names. 619 * 620 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 621 */ 622static intis_mail(FILE*fp) 623{ 624const char*header_regex ="^[!-9;-~]+:"; 625struct strbuf sb = STRBUF_INIT; 626 regex_t regex; 627int ret =1; 628 629if(fseek(fp,0L, SEEK_SET)) 630die_errno(_("fseek failed")); 631 632if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 633die("invalid pattern:%s", header_regex); 634 635while(!strbuf_getline_crlf(&sb, fp)) { 636if(!sb.len) 637break;/* End of header */ 638 639/* Ignore indented folded lines */ 640if(*sb.buf =='\t'|| *sb.buf ==' ') 641continue; 642 643/* It's a header if it matches header_regex */ 644if(regexec(®ex, sb.buf,0, NULL,0)) { 645 ret =0; 646goto done; 647} 648} 649 650done: 651regfree(®ex); 652strbuf_release(&sb); 653return ret; 654} 655 656/** 657 * Attempts to detect the patch_format of the patches contained in `paths`, 658 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 659 * detection fails. 660 */ 661static intdetect_patch_format(const char**paths) 662{ 663enum patch_format ret = PATCH_FORMAT_UNKNOWN; 664struct strbuf l1 = STRBUF_INIT; 665struct strbuf l2 = STRBUF_INIT; 666struct strbuf l3 = STRBUF_INIT; 667FILE*fp; 668 669/* 670 * We default to mbox format if input is from stdin and for directories 671 */ 672if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 673return PATCH_FORMAT_MBOX; 674 675/* 676 * Otherwise, check the first few lines of the first patch, starting 677 * from the first non-blank line, to try to detect its format. 678 */ 679 680 fp =xfopen(*paths,"r"); 681 682while(!strbuf_getline_crlf(&l1, fp)) { 683if(l1.len) 684break; 685} 686 687if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 688 ret = PATCH_FORMAT_MBOX; 689goto done; 690} 691 692if(starts_with(l1.buf,"# This series applies on GIT commit")) { 693 ret = PATCH_FORMAT_STGIT_SERIES; 694goto done; 695} 696 697if(!strcmp(l1.buf,"# HG changeset patch")) { 698 ret = PATCH_FORMAT_HG; 699goto done; 700} 701 702strbuf_reset(&l2); 703strbuf_getline_crlf(&l2, fp); 704strbuf_reset(&l3); 705strbuf_getline_crlf(&l3, fp); 706 707/* 708 * If the second line is empty and the third is a From, Author or Date 709 * entry, this is likely an StGit patch. 710 */ 711if(l1.len && !l2.len && 712(starts_with(l3.buf,"From:") || 713starts_with(l3.buf,"Author:") || 714starts_with(l3.buf,"Date:"))) { 715 ret = PATCH_FORMAT_STGIT; 716goto done; 717} 718 719if(l1.len &&is_mail(fp)) { 720 ret = PATCH_FORMAT_MBOX; 721goto done; 722} 723 724done: 725fclose(fp); 726strbuf_release(&l1); 727return ret; 728} 729 730/** 731 * Splits out individual email patches from `paths`, where each path is either 732 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 733 */ 734static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 735{ 736struct child_process cp = CHILD_PROCESS_INIT; 737struct strbuf last = STRBUF_INIT; 738 739 cp.git_cmd =1; 740argv_array_push(&cp.args,"mailsplit"); 741argv_array_pushf(&cp.args,"-d%d", state->prec); 742argv_array_pushf(&cp.args,"-o%s", state->dir); 743argv_array_push(&cp.args,"-b"); 744if(keep_cr) 745argv_array_push(&cp.args,"--keep-cr"); 746argv_array_push(&cp.args,"--"); 747argv_array_pushv(&cp.args, paths); 748 749if(capture_command(&cp, &last,8)) 750return-1; 751 752 state->cur =1; 753 state->last =strtol(last.buf, NULL,10); 754 755return0; 756} 757 758/** 759 * Callback signature for split_mail_conv(). The foreign patch should be 760 * read from `in`, and the converted patch (in RFC2822 mail format) should be 761 * written to `out`. Return 0 on success, or -1 on failure. 762 */ 763typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 764 765/** 766 * Calls `fn` for each file in `paths` to convert the foreign patch to the 767 * RFC2822 mail format suitable for parsing with git-mailinfo. 768 * 769 * Returns 0 on success, -1 on failure. 770 */ 771static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 772const char**paths,int keep_cr) 773{ 774static const char*stdin_only[] = {"-", NULL}; 775int i; 776 777if(!*paths) 778 paths = stdin_only; 779 780for(i =0; *paths; paths++, i++) { 781FILE*in, *out; 782const char*mail; 783int ret; 784 785if(!strcmp(*paths,"-")) 786 in = stdin; 787else 788 in =fopen(*paths,"r"); 789 790if(!in) 791returnerror(_("could not open '%s' for reading:%s"), 792*paths,strerror(errno)); 793 794 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 795 796 out =fopen(mail,"w"); 797if(!out) 798returnerror(_("could not open '%s' for writing:%s"), 799 mail,strerror(errno)); 800 801 ret =fn(out, in, keep_cr); 802 803fclose(out); 804fclose(in); 805 806if(ret) 807returnerror(_("could not parse patch '%s'"), *paths); 808} 809 810 state->cur =1; 811 state->last = i; 812return0; 813} 814 815/** 816 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 817 * message suitable for parsing with git-mailinfo. 818 */ 819static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 820{ 821struct strbuf sb = STRBUF_INIT; 822int subject_printed =0; 823 824while(!strbuf_getline(&sb, in,'\n')) { 825const char*str; 826 827if(str_isspace(sb.buf)) 828continue; 829else if(skip_prefix(sb.buf,"Author:", &str)) 830fprintf(out,"From:%s\n", str); 831else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 832fprintf(out,"%s\n", sb.buf); 833else if(!subject_printed) { 834fprintf(out,"Subject:%s\n", sb.buf); 835 subject_printed =1; 836}else{ 837fprintf(out,"\n%s\n", sb.buf); 838break; 839} 840} 841 842strbuf_reset(&sb); 843while(strbuf_fread(&sb,8192, in) >0) { 844fwrite(sb.buf,1, sb.len, out); 845strbuf_reset(&sb); 846} 847 848strbuf_release(&sb); 849return0; 850} 851 852/** 853 * This function only supports a single StGit series file in `paths`. 854 * 855 * Given an StGit series file, converts the StGit patches in the series into 856 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 857 * the state directory. 858 * 859 * Returns 0 on success, -1 on failure. 860 */ 861static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 862int keep_cr) 863{ 864const char*series_dir; 865char*series_dir_buf; 866FILE*fp; 867struct argv_array patches = ARGV_ARRAY_INIT; 868struct strbuf sb = STRBUF_INIT; 869int ret; 870 871if(!paths[0] || paths[1]) 872returnerror(_("Only one StGIT patch series can be applied at once")); 873 874 series_dir_buf =xstrdup(*paths); 875 series_dir =dirname(series_dir_buf); 876 877 fp =fopen(*paths,"r"); 878if(!fp) 879returnerror(_("could not open '%s' for reading:%s"), *paths, 880strerror(errno)); 881 882while(!strbuf_getline(&sb, fp,'\n')) { 883if(*sb.buf =='#') 884continue;/* skip comment lines */ 885 886argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 887} 888 889fclose(fp); 890strbuf_release(&sb); 891free(series_dir_buf); 892 893 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 894 895argv_array_clear(&patches); 896return ret; 897} 898 899/** 900 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 901 * message suitable for parsing with git-mailinfo. 902 */ 903static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 904{ 905struct strbuf sb = STRBUF_INIT; 906 907while(!strbuf_getline(&sb, in,'\n')) { 908const char*str; 909 910if(skip_prefix(sb.buf,"# User ", &str)) 911fprintf(out,"From:%s\n", str); 912else if(skip_prefix(sb.buf,"# Date ", &str)) { 913unsigned long timestamp; 914long tz, tz2; 915char*end; 916 917 errno =0; 918 timestamp =strtoul(str, &end,10); 919if(errno) 920returnerror(_("invalid timestamp")); 921 922if(!skip_prefix(end," ", &str)) 923returnerror(_("invalid Date line")); 924 925 errno =0; 926 tz =strtol(str, &end,10); 927if(errno) 928returnerror(_("invalid timezone offset")); 929 930if(*end) 931returnerror(_("invalid Date line")); 932 933/* 934 * mercurial's timezone is in seconds west of UTC, 935 * however git's timezone is in hours + minutes east of 936 * UTC. Convert it. 937 */ 938 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 939if(tz >0) 940 tz2 = -tz2; 941 942fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 943}else if(starts_with(sb.buf,"# ")) { 944continue; 945}else{ 946fprintf(out,"\n%s\n", sb.buf); 947break; 948} 949} 950 951strbuf_reset(&sb); 952while(strbuf_fread(&sb,8192, in) >0) { 953fwrite(sb.buf,1, sb.len, out); 954strbuf_reset(&sb); 955} 956 957strbuf_release(&sb); 958return0; 959} 960 961/** 962 * Splits a list of files/directories into individual email patches. Each path 963 * in `paths` must be a file/directory that is formatted according to 964 * `patch_format`. 965 * 966 * Once split out, the individual email patches will be stored in the state 967 * directory, with each patch's filename being its index, padded to state->prec 968 * digits. 969 * 970 * state->cur will be set to the index of the first mail, and state->last will 971 * be set to the index of the last mail. 972 * 973 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 974 * to disable this behavior, -1 to use the default configured setting. 975 * 976 * Returns 0 on success, -1 on failure. 977 */ 978static intsplit_mail(struct am_state *state,enum patch_format patch_format, 979const char**paths,int keep_cr) 980{ 981if(keep_cr <0) { 982 keep_cr =0; 983git_config_get_bool("am.keepcr", &keep_cr); 984} 985 986switch(patch_format) { 987case PATCH_FORMAT_MBOX: 988returnsplit_mail_mbox(state, paths, keep_cr); 989case PATCH_FORMAT_STGIT: 990returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 991case PATCH_FORMAT_STGIT_SERIES: 992returnsplit_mail_stgit_series(state, paths, keep_cr); 993case PATCH_FORMAT_HG: 994returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 995default: 996die("BUG: invalid patch_format"); 997} 998return-1; 999}10001001/**1002 * Setup a new am session for applying patches1003 */1004static voidam_setup(struct am_state *state,enum patch_format patch_format,1005const char**paths,int keep_cr)1006{1007unsigned char curr_head[GIT_SHA1_RAWSZ];1008const char*str;1009struct strbuf sb = STRBUF_INIT;10101011if(!patch_format)1012 patch_format =detect_patch_format(paths);10131014if(!patch_format) {1015fprintf_ln(stderr,_("Patch format detection failed."));1016exit(128);1017}10181019if(mkdir(state->dir,0777) <0&& errno != EEXIST)1020die_errno(_("failed to create directory '%s'"), state->dir);10211022if(split_mail(state, patch_format, paths, keep_cr) <0) {1023am_destroy(state);1024die(_("Failed to split patches."));1025}10261027if(state->rebasing)1028 state->threeway =1;10291030write_state_bool(state,"threeway", state->threeway);1031write_state_bool(state,"quiet", state->quiet);1032write_state_bool(state,"sign", state->signoff);1033write_state_bool(state,"utf8", state->utf8);10341035switch(state->keep) {1036case KEEP_FALSE:1037 str ="f";1038break;1039case KEEP_TRUE:1040 str ="t";1041break;1042case KEEP_NON_PATCH:1043 str ="b";1044break;1045default:1046die("BUG: invalid value for state->keep");1047}10481049write_state_text(state,"keep", str);1050write_state_bool(state,"messageid", state->message_id);10511052switch(state->scissors) {1053case SCISSORS_UNSET:1054 str ="";1055break;1056case SCISSORS_FALSE:1057 str ="f";1058break;1059case SCISSORS_TRUE:1060 str ="t";1061break;1062default:1063die("BUG: invalid value for state->scissors");1064}1065write_state_text(state,"scissors", str);10661067sq_quote_argv(&sb, state->git_apply_opts.argv,0);1068write_state_text(state,"apply-opt", sb.buf);10691070if(state->rebasing)1071write_state_text(state,"rebasing","");1072else1073write_state_text(state,"applying","");10741075if(!get_sha1("HEAD", curr_head)) {1076write_state_text(state,"abort-safety",sha1_to_hex(curr_head));1077if(!state->rebasing)1078update_ref("am","ORIG_HEAD", curr_head, NULL,0,1079 UPDATE_REFS_DIE_ON_ERR);1080}else{1081write_state_text(state,"abort-safety","");1082if(!state->rebasing)1083delete_ref("ORIG_HEAD", NULL,0);1084}10851086/*1087 * NOTE: Since the "next" and "last" files determine if an am_state1088 * session is in progress, they should be written last.1089 */10901091write_state_count(state,"next", state->cur);1092write_state_count(state,"last", state->last);10931094strbuf_release(&sb);1095}10961097/**1098 * Increments the patch pointer, and cleans am_state for the application of the1099 * next patch.1100 */1101static voidam_next(struct am_state *state)1102{1103unsigned char head[GIT_SHA1_RAWSZ];11041105free(state->author_name);1106 state->author_name = NULL;11071108free(state->author_email);1109 state->author_email = NULL;11101111free(state->author_date);1112 state->author_date = NULL;11131114free(state->msg);1115 state->msg = NULL;1116 state->msg_len =0;11171118unlink(am_path(state,"author-script"));1119unlink(am_path(state,"final-commit"));11201121hashclr(state->orig_commit);1122unlink(am_path(state,"original-commit"));11231124if(!get_sha1("HEAD", head))1125write_state_text(state,"abort-safety",sha1_to_hex(head));1126else1127write_state_text(state,"abort-safety","");11281129 state->cur++;1130write_state_count(state,"next", state->cur);1131}11321133/**1134 * Returns the filename of the current patch email.1135 */1136static const char*msgnum(const struct am_state *state)1137{1138static struct strbuf sb = STRBUF_INIT;11391140strbuf_reset(&sb);1141strbuf_addf(&sb,"%0*d", state->prec, state->cur);11421143return sb.buf;1144}11451146/**1147 * Refresh and write index.1148 */1149static voidrefresh_and_write_cache(void)1150{1151struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11521153hold_locked_index(lock_file,1);1154refresh_cache(REFRESH_QUIET);1155if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1156die(_("unable to write index file"));1157}11581159/**1160 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1161 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1162 * strbuf is provided, the space-separated list of files that differ will be1163 * appended to it.1164 */1165static intindex_has_changes(struct strbuf *sb)1166{1167unsigned char head[GIT_SHA1_RAWSZ];1168int i;11691170if(!get_sha1_tree("HEAD", head)) {1171struct diff_options opt;11721173diff_setup(&opt);1174DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1175if(!sb)1176DIFF_OPT_SET(&opt, QUICK);1177do_diff_cache(head, &opt);1178diffcore_std(&opt);1179for(i =0; sb && i < diff_queued_diff.nr; i++) {1180if(i)1181strbuf_addch(sb,' ');1182strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1183}1184diff_flush(&opt);1185returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1186}else{1187for(i =0; sb && i < active_nr; i++) {1188if(i)1189strbuf_addch(sb,' ');1190strbuf_addstr(sb, active_cache[i]->name);1191}1192return!!active_nr;1193}1194}11951196/**1197 * Dies with a user-friendly message on how to proceed after resolving the1198 * problem. This message can be overridden with state->resolvemsg.1199 */1200static void NORETURN die_user_resolve(const struct am_state *state)1201{1202if(state->resolvemsg) {1203printf_ln("%s", state->resolvemsg);1204}else{1205const char*cmdline = state->interactive ?"git am -i":"git am";12061207printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1208printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1209printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1210}12111212exit(128);1213}12141215/**1216 * Appends signoff to the "msg" field of the am_state.1217 */1218static voidam_append_signoff(struct am_state *state)1219{1220struct strbuf sb = STRBUF_INIT;12211222strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1223append_signoff(&sb,0,0);1224 state->msg =strbuf_detach(&sb, &state->msg_len);1225}12261227/**1228 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1229 * state->msg will be set to the patch message. state->author_name,1230 * state->author_email and state->author_date will be set to the patch author's1231 * name, email and date respectively. The patch body will be written to the1232 * state directory's "patch" file.1233 *1234 * Returns 1 if the patch should be skipped, 0 otherwise.1235 */1236static intparse_mail(struct am_state *state,const char*mail)1237{1238FILE*fp;1239struct child_process cp = CHILD_PROCESS_INIT;1240struct strbuf sb = STRBUF_INIT;1241struct strbuf msg = STRBUF_INIT;1242struct strbuf author_name = STRBUF_INIT;1243struct strbuf author_date = STRBUF_INIT;1244struct strbuf author_email = STRBUF_INIT;1245int ret =0;12461247 cp.git_cmd =1;1248 cp.in =xopen(mail, O_RDONLY,0);1249 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777);12501251argv_array_push(&cp.args,"mailinfo");1252argv_array_push(&cp.args, state->utf8 ?"-u":"-n");12531254switch(state->keep) {1255case KEEP_FALSE:1256break;1257case KEEP_TRUE:1258argv_array_push(&cp.args,"-k");1259break;1260case KEEP_NON_PATCH:1261argv_array_push(&cp.args,"-b");1262break;1263default:1264die("BUG: invalid value for state->keep");1265}12661267if(state->message_id)1268argv_array_push(&cp.args,"-m");12691270switch(state->scissors) {1271case SCISSORS_UNSET:1272break;1273case SCISSORS_FALSE:1274argv_array_push(&cp.args,"--no-scissors");1275break;1276case SCISSORS_TRUE:1277argv_array_push(&cp.args,"--scissors");1278break;1279default:1280die("BUG: invalid value for state->scissors");1281}12821283argv_array_push(&cp.args,am_path(state,"msg"));1284argv_array_push(&cp.args,am_path(state,"patch"));12851286if(run_command(&cp) <0)1287die("could not parse patch");12881289close(cp.in);1290close(cp.out);12911292/* Extract message and author information */1293 fp =xfopen(am_path(state,"info"),"r");1294while(!strbuf_getline(&sb, fp,'\n')) {1295const char*x;12961297if(skip_prefix(sb.buf,"Subject: ", &x)) {1298if(msg.len)1299strbuf_addch(&msg,'\n');1300strbuf_addstr(&msg, x);1301}else if(skip_prefix(sb.buf,"Author: ", &x))1302strbuf_addstr(&author_name, x);1303else if(skip_prefix(sb.buf,"Email: ", &x))1304strbuf_addstr(&author_email, x);1305else if(skip_prefix(sb.buf,"Date: ", &x))1306strbuf_addstr(&author_date, x);1307}1308fclose(fp);13091310/* Skip pine's internal folder data */1311if(!strcmp(author_name.buf,"Mail System Internal Data")) {1312 ret =1;1313goto finish;1314}13151316if(is_empty_file(am_path(state,"patch"))) {1317printf_ln(_("Patch is empty. Was it split wrong?"));1318die_user_resolve(state);1319}13201321strbuf_addstr(&msg,"\n\n");1322if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0)1323die_errno(_("could not read '%s'"),am_path(state,"msg"));1324stripspace(&msg,0);13251326if(state->signoff)1327append_signoff(&msg,0,0);13281329assert(!state->author_name);1330 state->author_name =strbuf_detach(&author_name, NULL);13311332assert(!state->author_email);1333 state->author_email =strbuf_detach(&author_email, NULL);13341335assert(!state->author_date);1336 state->author_date =strbuf_detach(&author_date, NULL);13371338assert(!state->msg);1339 state->msg =strbuf_detach(&msg, &state->msg_len);13401341finish:1342strbuf_release(&msg);1343strbuf_release(&author_date);1344strbuf_release(&author_email);1345strbuf_release(&author_name);1346strbuf_release(&sb);1347return ret;1348}13491350/**1351 * Sets commit_id to the commit hash where the mail was generated from.1352 * Returns 0 on success, -1 on failure.1353 */1354static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1355{1356struct strbuf sb = STRBUF_INIT;1357FILE*fp =xfopen(mail,"r");1358const char*x;13591360if(strbuf_getline(&sb, fp,'\n'))1361return-1;13621363if(!skip_prefix(sb.buf,"From ", &x))1364return-1;13651366if(get_sha1_hex(x, commit_id) <0)1367return-1;13681369strbuf_release(&sb);1370fclose(fp);1371return0;1372}13731374/**1375 * Sets state->msg, state->author_name, state->author_email, state->author_date1376 * to the commit's respective info.1377 */1378static voidget_commit_info(struct am_state *state,struct commit *commit)1379{1380const char*buffer, *ident_line, *author_date, *msg;1381size_t ident_len;1382struct ident_split ident_split;1383struct strbuf sb = STRBUF_INIT;13841385 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13861387 ident_line =find_commit_header(buffer,"author", &ident_len);13881389if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1390strbuf_add(&sb, ident_line, ident_len);1391die(_("invalid ident line:%s"), sb.buf);1392}13931394assert(!state->author_name);1395if(ident_split.name_begin) {1396strbuf_add(&sb, ident_split.name_begin,1397 ident_split.name_end - ident_split.name_begin);1398 state->author_name =strbuf_detach(&sb, NULL);1399}else1400 state->author_name =xstrdup("");14011402assert(!state->author_email);1403if(ident_split.mail_begin) {1404strbuf_add(&sb, ident_split.mail_begin,1405 ident_split.mail_end - ident_split.mail_begin);1406 state->author_email =strbuf_detach(&sb, NULL);1407}else1408 state->author_email =xstrdup("");14091410 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1411strbuf_addstr(&sb, author_date);1412assert(!state->author_date);1413 state->author_date =strbuf_detach(&sb, NULL);14141415assert(!state->msg);1416 msg =strstr(buffer,"\n\n");1417if(!msg)1418die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1419 state->msg =xstrdup(msg +2);1420 state->msg_len =strlen(state->msg);1421}14221423/**1424 * Writes `commit` as a patch to the state directory's "patch" file.1425 */1426static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1427{1428struct rev_info rev_info;1429FILE*fp;14301431 fp =xfopen(am_path(state,"patch"),"w");1432init_revisions(&rev_info, NULL);1433 rev_info.diff =1;1434 rev_info.abbrev =0;1435 rev_info.disable_stdin =1;1436 rev_info.show_root_diff =1;1437 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1438 rev_info.no_commit_id =1;1439DIFF_OPT_SET(&rev_info.diffopt, BINARY);1440DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1441 rev_info.diffopt.use_color =0;1442 rev_info.diffopt.file = fp;1443 rev_info.diffopt.close_file =1;1444add_pending_object(&rev_info, &commit->object,"");1445diff_setup_done(&rev_info.diffopt);1446log_tree_commit(&rev_info, commit);1447}14481449/**1450 * Writes the diff of the index against HEAD as a patch to the state1451 * directory's "patch" file.1452 */1453static voidwrite_index_patch(const struct am_state *state)1454{1455struct tree *tree;1456unsigned char head[GIT_SHA1_RAWSZ];1457struct rev_info rev_info;1458FILE*fp;14591460if(!get_sha1_tree("HEAD", head))1461 tree =lookup_tree(head);1462else1463 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14641465 fp =xfopen(am_path(state,"patch"),"w");1466init_revisions(&rev_info, NULL);1467 rev_info.diff =1;1468 rev_info.disable_stdin =1;1469 rev_info.no_commit_id =1;1470 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1471 rev_info.diffopt.use_color =0;1472 rev_info.diffopt.file = fp;1473 rev_info.diffopt.close_file =1;1474add_pending_object(&rev_info, &tree->object,"");1475diff_setup_done(&rev_info.diffopt);1476run_diff_index(&rev_info,1);1477}14781479/**1480 * Like parse_mail(), but parses the mail by looking up its commit ID1481 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1482 * of patches.1483 *1484 * state->orig_commit will be set to the original commit ID.1485 *1486 * Will always return 0 as the patch should never be skipped.1487 */1488static intparse_mail_rebase(struct am_state *state,const char*mail)1489{1490struct commit *commit;1491unsigned char commit_sha1[GIT_SHA1_RAWSZ];14921493if(get_mail_commit_sha1(commit_sha1, mail) <0)1494die(_("could not parse%s"), mail);14951496 commit =lookup_commit_or_die(commit_sha1, mail);14971498get_commit_info(state, commit);14991500write_commit_patch(state, commit);15011502hashcpy(state->orig_commit, commit_sha1);1503write_state_text(state,"original-commit",sha1_to_hex(commit_sha1));15041505return0;1506}15071508/**1509 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1510 * `index_file` is not NULL, the patch will be applied to that index.1511 */1512static intrun_apply(const struct am_state *state,const char*index_file)1513{1514struct child_process cp = CHILD_PROCESS_INIT;15151516 cp.git_cmd =1;15171518if(index_file)1519argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);15201521/*1522 * If we are allowed to fall back on 3-way merge, don't give false1523 * errors during the initial attempt.1524 */1525if(state->threeway && !index_file) {1526 cp.no_stdout =1;1527 cp.no_stderr =1;1528}15291530argv_array_push(&cp.args,"apply");15311532argv_array_pushv(&cp.args, state->git_apply_opts.argv);15331534if(index_file)1535argv_array_push(&cp.args,"--cached");1536else1537argv_array_push(&cp.args,"--index");15381539argv_array_push(&cp.args,am_path(state,"patch"));15401541if(run_command(&cp))1542return-1;15431544/* Reload index as git-apply will have modified it. */1545discard_cache();1546read_cache_from(index_file ? index_file :get_index_file());15471548return0;1549}15501551/**1552 * Builds an index that contains just the blobs needed for a 3way merge.1553 */1554static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1555{1556struct child_process cp = CHILD_PROCESS_INIT;15571558 cp.git_cmd =1;1559argv_array_push(&cp.args,"apply");1560argv_array_pushv(&cp.args, state->git_apply_opts.argv);1561argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1562argv_array_push(&cp.args,am_path(state,"patch"));15631564if(run_command(&cp))1565return-1;15661567return0;1568}15691570/**1571 * Attempt a threeway merge, using index_path as the temporary index.1572 */1573static intfall_back_threeway(const struct am_state *state,const char*index_path)1574{1575unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1576 our_tree[GIT_SHA1_RAWSZ];1577const unsigned char*bases[1] = {orig_tree};1578struct merge_options o;1579struct commit *result;1580char*his_tree_name;15811582if(get_sha1("HEAD", our_tree) <0)1583hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);15841585if(build_fake_ancestor(state, index_path))1586returnerror("could not build fake ancestor");15871588discard_cache();1589read_cache_from(index_path);15901591if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1592returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15931594say(state, stdout,_("Using index info to reconstruct a base tree..."));15951596if(!state->quiet) {1597/*1598 * List paths that needed 3-way fallback, so that the user can1599 * review them with extra care to spot mismerges.1600 */1601struct rev_info rev_info;1602const char*diff_filter_str ="--diff-filter=AM";16031604init_revisions(&rev_info, NULL);1605 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1606diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1607add_pending_sha1(&rev_info,"HEAD", our_tree,0);1608diff_setup_done(&rev_info.diffopt);1609run_diff_index(&rev_info,1);1610}16111612if(run_apply(state, index_path))1613returnerror(_("Did you hand edit your patch?\n"1614"It does not apply to blobs recorded in its index."));16151616if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1617returnerror("could not write tree");16181619say(state, stdout,_("Falling back to patching base and 3-way merge..."));16201621discard_cache();1622read_cache();16231624/*1625 * This is not so wrong. Depending on which base we picked, orig_tree1626 * may be wildly different from ours, but his_tree has the same set of1627 * wildly different changes in parts the patch did not touch, so1628 * recursive ends up canceling them, saying that we reverted all those1629 * changes.1630 */16311632init_merge_options(&o);16331634 o.branch1 ="HEAD";1635 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1636 o.branch2 = his_tree_name;16371638if(state->quiet)1639 o.verbosity =0;16401641if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1642rerere(state->allow_rerere_autoupdate);1643free(his_tree_name);1644returnerror(_("Failed to merge in the changes."));1645}16461647free(his_tree_name);1648return0;1649}16501651/**1652 * Commits the current index with state->msg as the commit message and1653 * state->author_name, state->author_email and state->author_date as the author1654 * information.1655 */1656static voiddo_commit(const struct am_state *state)1657{1658unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1659 commit[GIT_SHA1_RAWSZ];1660unsigned char*ptr;1661struct commit_list *parents = NULL;1662const char*reflog_msg, *author;1663struct strbuf sb = STRBUF_INIT;16641665if(run_hook_le(NULL,"pre-applypatch", NULL))1666exit(1);16671668if(write_cache_as_tree(tree,0, NULL))1669die(_("git write-tree failed to write a tree"));16701671if(!get_sha1_commit("HEAD", parent)) {1672 ptr = parent;1673commit_list_insert(lookup_commit(parent), &parents);1674}else{1675 ptr = NULL;1676say(state, stderr,_("applying to an empty history"));1677}16781679 author =fmt_ident(state->author_name, state->author_email,1680 state->ignore_date ? NULL : state->author_date,1681 IDENT_STRICT);16821683if(state->committer_date_is_author_date)1684setenv("GIT_COMMITTER_DATE",1685 state->ignore_date ?"": state->author_date,1);16861687if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1688 author, state->sign_commit))1689die(_("failed to write commit object"));16901691 reflog_msg =getenv("GIT_REFLOG_ACTION");1692if(!reflog_msg)1693 reflog_msg ="am";16941695strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1696 state->msg);16971698update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);16991700if(state->rebasing) {1701FILE*fp =xfopen(am_path(state,"rewritten"),"a");17021703assert(!is_null_sha1(state->orig_commit));1704fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1705fprintf(fp,"%s\n",sha1_to_hex(commit));1706fclose(fp);1707}17081709run_hook_le(NULL,"post-applypatch", NULL);17101711strbuf_release(&sb);1712}17131714/**1715 * Validates the am_state for resuming -- the "msg" and authorship fields must1716 * be filled up.1717 */1718static voidvalidate_resume_state(const struct am_state *state)1719{1720if(!state->msg)1721die(_("cannot resume:%sdoes not exist."),1722am_path(state,"final-commit"));17231724if(!state->author_name || !state->author_email || !state->author_date)1725die(_("cannot resume:%sdoes not exist."),1726am_path(state,"author-script"));1727}17281729/**1730 * Interactively prompt the user on whether the current patch should be1731 * applied.1732 *1733 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1734 * skip it.1735 */1736static intdo_interactive(struct am_state *state)1737{1738assert(state->msg);17391740if(!isatty(0))1741die(_("cannot be interactive without stdin connected to a terminal."));17421743for(;;) {1744const char*reply;17451746puts(_("Commit Body is:"));1747puts("--------------------------");1748printf("%s", state->msg);1749puts("--------------------------");17501751/*1752 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1753 * in your translation. The program will only accept English1754 * input at this point.1755 */1756 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17571758if(!reply) {1759continue;1760}else if(*reply =='y'|| *reply =='Y') {1761return0;1762}else if(*reply =='a'|| *reply =='A') {1763 state->interactive =0;1764return0;1765}else if(*reply =='n'|| *reply =='N') {1766return1;1767}else if(*reply =='e'|| *reply =='E') {1768struct strbuf msg = STRBUF_INIT;17691770if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1771free(state->msg);1772 state->msg =strbuf_detach(&msg, &state->msg_len);1773}1774strbuf_release(&msg);1775}else if(*reply =='v'|| *reply =='V') {1776const char*pager =git_pager(1);1777struct child_process cp = CHILD_PROCESS_INIT;17781779if(!pager)1780 pager ="cat";1781argv_array_push(&cp.args, pager);1782argv_array_push(&cp.args,am_path(state,"patch"));1783run_command(&cp);1784}1785}1786}17871788/**1789 * Applies all queued mail.1790 *1791 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1792 * well as the state directory's "patch" file is used as-is for applying the1793 * patch and committing it.1794 */1795static voidam_run(struct am_state *state,int resume)1796{1797const char*argv_gc_auto[] = {"gc","--auto", NULL};1798struct strbuf sb = STRBUF_INIT;17991800unlink(am_path(state,"dirtyindex"));18011802refresh_and_write_cache();18031804if(index_has_changes(&sb)) {1805write_state_bool(state,"dirtyindex",1);1806die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1807}18081809strbuf_release(&sb);18101811while(state->cur <= state->last) {1812const char*mail =am_path(state,msgnum(state));1813int apply_status;18141815if(!file_exists(mail))1816goto next;18171818if(resume) {1819validate_resume_state(state);1820}else{1821int skip;18221823if(state->rebasing)1824 skip =parse_mail_rebase(state, mail);1825else1826 skip =parse_mail(state, mail);18271828if(skip)1829goto next;/* mail should be skipped */18301831write_author_script(state);1832write_commit_msg(state);1833}18341835if(state->interactive &&do_interactive(state))1836goto next;18371838if(run_applypatch_msg_hook(state))1839exit(1);18401841say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18421843 apply_status =run_apply(state, NULL);18441845if(apply_status && state->threeway) {1846struct strbuf sb = STRBUF_INIT;18471848strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1849 apply_status =fall_back_threeway(state, sb.buf);1850strbuf_release(&sb);18511852/*1853 * Applying the patch to an earlier tree and merging1854 * the result may have produced the same tree as ours.1855 */1856if(!apply_status && !index_has_changes(NULL)) {1857say(state, stdout,_("No changes -- Patch already applied."));1858goto next;1859}1860}18611862if(apply_status) {1863int advice_amworkdir =1;18641865printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1866linelen(state->msg), state->msg);18671868git_config_get_bool("advice.amworkdir", &advice_amworkdir);18691870if(advice_amworkdir)1871printf_ln(_("The copy of the patch that failed is found in:%s"),1872am_path(state,"patch"));18731874die_user_resolve(state);1875}18761877do_commit(state);18781879next:1880am_next(state);18811882if(resume)1883am_load(state);1884 resume =0;1885}18861887if(!is_empty_file(am_path(state,"rewritten"))) {1888assert(state->rebasing);1889copy_notes_for_rebase(state);1890run_post_rewrite_hook(state);1891}18921893/*1894 * In rebasing mode, it's up to the caller to take care of1895 * housekeeping.1896 */1897if(!state->rebasing) {1898am_destroy(state);1899run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1900}1901}19021903/**1904 * Resume the current am session after patch application failure. The user did1905 * all the hard work, and we do not have to do any patch application. Just1906 * trust and commit what the user has in the index and working tree.1907 */1908static voidam_resolve(struct am_state *state)1909{1910validate_resume_state(state);19111912say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);19131914if(!index_has_changes(NULL)) {1915printf_ln(_("No changes - did you forget to use 'git add'?\n"1916"If there is nothing left to stage, chances are that something else\n"1917"already introduced the same changes; you might want to skip this patch."));1918die_user_resolve(state);1919}19201921if(unmerged_cache()) {1922printf_ln(_("You still have unmerged paths in your index.\n"1923"Did you forget to use 'git add'?"));1924die_user_resolve(state);1925}19261927if(state->interactive) {1928write_index_patch(state);1929if(do_interactive(state))1930goto next;1931}19321933rerere(0);19341935do_commit(state);19361937next:1938am_next(state);1939am_load(state);1940am_run(state,0);1941}19421943/**1944 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1945 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1946 * failure.1947 */1948static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1949{1950struct lock_file *lock_file;1951struct unpack_trees_options opts;1952struct tree_desc t[2];19531954if(parse_tree(head) ||parse_tree(remote))1955return-1;19561957 lock_file =xcalloc(1,sizeof(struct lock_file));1958hold_locked_index(lock_file,1);19591960refresh_cache(REFRESH_QUIET);19611962memset(&opts,0,sizeof(opts));1963 opts.head_idx =1;1964 opts.src_index = &the_index;1965 opts.dst_index = &the_index;1966 opts.update =1;1967 opts.merge =1;1968 opts.reset = reset;1969 opts.fn = twoway_merge;1970init_tree_desc(&t[0], head->buffer, head->size);1971init_tree_desc(&t[1], remote->buffer, remote->size);19721973if(unpack_trees(2, t, &opts)) {1974rollback_lock_file(lock_file);1975return-1;1976}19771978if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1979die(_("unable to write new index file"));19801981return0;1982}19831984/**1985 * Clean the index without touching entries that are not modified between1986 * `head` and `remote`.1987 */1988static intclean_index(const unsigned char*head,const unsigned char*remote)1989{1990struct lock_file *lock_file;1991struct tree *head_tree, *remote_tree, *index_tree;1992unsigned char index[GIT_SHA1_RAWSZ];1993struct pathspec pathspec;19941995 head_tree =parse_tree_indirect(head);1996if(!head_tree)1997returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));19981999 remote_tree =parse_tree_indirect(remote);2000if(!remote_tree)2001returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));20022003read_cache_unmerged();20042005if(fast_forward_to(head_tree, head_tree,1))2006return-1;20072008if(write_cache_as_tree(index,0, NULL))2009return-1;20102011 index_tree =parse_tree_indirect(index);2012if(!index_tree)2013returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));20142015if(fast_forward_to(index_tree, remote_tree,0))2016return-1;20172018memset(&pathspec,0,sizeof(pathspec));20192020 lock_file =xcalloc(1,sizeof(struct lock_file));2021hold_locked_index(lock_file,1);20222023if(read_tree(remote_tree,0, &pathspec)) {2024rollback_lock_file(lock_file);2025return-1;2026}20272028if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2029die(_("unable to write new index file"));20302031remove_branch_state();20322033return0;2034}20352036/**2037 * Resets rerere's merge resolution metadata.2038 */2039static voidam_rerere_clear(void)2040{2041struct string_list merge_rr = STRING_LIST_INIT_DUP;2042int fd =setup_rerere(&merge_rr,0);20432044if(fd <0)2045return;20462047rerere_clear(&merge_rr);2048string_list_clear(&merge_rr,1);2049}20502051/**2052 * Resume the current am session by skipping the current patch.2053 */2054static voidam_skip(struct am_state *state)2055{2056unsigned char head[GIT_SHA1_RAWSZ];20572058am_rerere_clear();20592060if(get_sha1("HEAD", head))2061hashcpy(head, EMPTY_TREE_SHA1_BIN);20622063if(clean_index(head, head))2064die(_("failed to clean index"));20652066am_next(state);2067am_load(state);2068am_run(state,0);2069}20702071/**2072 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2073 *2074 * It is not safe to reset HEAD when:2075 * 1. git-am previously failed because the index was dirty.2076 * 2. HEAD has moved since git-am previously failed.2077 */2078static intsafe_to_abort(const struct am_state *state)2079{2080struct strbuf sb = STRBUF_INIT;2081unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];20822083if(file_exists(am_path(state,"dirtyindex")))2084return0;20852086if(read_state_file(&sb, state,"abort-safety",1) >0) {2087if(get_sha1_hex(sb.buf, abort_safety))2088die(_("could not parse%s"),am_path(state,"abort_safety"));2089}else2090hashclr(abort_safety);20912092if(get_sha1("HEAD", head))2093hashclr(head);20942095if(!hashcmp(head, abort_safety))2096return1;20972098error(_("You seem to have moved HEAD since the last 'am' failure.\n"2099"Not rewinding to ORIG_HEAD"));21002101return0;2102}21032104/**2105 * Aborts the current am session if it is safe to do so.2106 */2107static voidam_abort(struct am_state *state)2108{2109unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2110int has_curr_head, has_orig_head;2111char*curr_branch;21122113if(!safe_to_abort(state)) {2114am_destroy(state);2115return;2116}21172118am_rerere_clear();21192120 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2121 has_curr_head = !is_null_sha1(curr_head);2122if(!has_curr_head)2123hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);21242125 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2126if(!has_orig_head)2127hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);21282129clean_index(curr_head, orig_head);21302131if(has_orig_head)2132update_ref("am --abort","HEAD", orig_head,2133 has_curr_head ? curr_head : NULL,0,2134 UPDATE_REFS_DIE_ON_ERR);2135else if(curr_branch)2136delete_ref(curr_branch, NULL, REF_NODEREF);21372138free(curr_branch);2139am_destroy(state);2140}21412142/**2143 * parse_options() callback that validates and sets opt->value to the2144 * PATCH_FORMAT_* enum value corresponding to `arg`.2145 */2146static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2147{2148int*opt_value = opt->value;21492150if(!strcmp(arg,"mbox"))2151*opt_value = PATCH_FORMAT_MBOX;2152else if(!strcmp(arg,"stgit"))2153*opt_value = PATCH_FORMAT_STGIT;2154else if(!strcmp(arg,"stgit-series"))2155*opt_value = PATCH_FORMAT_STGIT_SERIES;2156else if(!strcmp(arg,"hg"))2157*opt_value = PATCH_FORMAT_HG;2158else2159returnerror(_("Invalid value for --patch-format:%s"), arg);2160return0;2161}21622163enum resume_mode {2164 RESUME_FALSE =0,2165 RESUME_APPLY,2166 RESUME_RESOLVED,2167 RESUME_SKIP,2168 RESUME_ABORT2169};21702171intcmd_am(int argc,const char**argv,const char*prefix)2172{2173struct am_state state;2174int binary = -1;2175int keep_cr = -1;2176int patch_format = PATCH_FORMAT_UNKNOWN;2177enum resume_mode resume = RESUME_FALSE;2178int in_progress;21792180const char*const usage[] = {2181N_("git am [options] [(<mbox>|<Maildir>)...]"),2182N_("git am [options] (--continue | --skip | --abort)"),2183 NULL2184};21852186struct option options[] = {2187OPT_BOOL('i',"interactive", &state.interactive,2188N_("run interactively")),2189OPT_HIDDEN_BOOL('b',"binary", &binary,2190N_("(historical option -- no-op")),2191OPT_BOOL('3',"3way", &state.threeway,2192N_("allow fall back on 3way merging if needed")),2193OPT__QUIET(&state.quiet,N_("be quiet")),2194OPT_SET_INT('s',"signoff", &state.signoff,2195N_("add a Signed-off-by line to the commit message"),2196 SIGNOFF_EXPLICIT),2197OPT_BOOL('u',"utf8", &state.utf8,2198N_("recode into utf8 (default)")),2199OPT_SET_INT('k',"keep", &state.keep,2200N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2201OPT_SET_INT(0,"keep-non-patch", &state.keep,2202N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2203OPT_BOOL('m',"message-id", &state.message_id,2204N_("pass -m flag to git-mailinfo")),2205{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2206N_("pass --keep-cr flag to git-mailsplit for mbox format"),2207 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2208{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2209N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2210 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2211OPT_BOOL('c',"scissors", &state.scissors,2212N_("strip everything before a scissors line")),2213OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2214N_("pass it through git-apply"),22150),2216OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2217N_("pass it through git-apply"),2218 PARSE_OPT_NOARG),2219OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2220N_("pass it through git-apply"),2221 PARSE_OPT_NOARG),2222OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2223N_("pass it through git-apply"),22240),2225OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2226N_("pass it through git-apply"),22270),2228OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2229N_("pass it through git-apply"),22300),2231OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2232N_("pass it through git-apply"),22330),2234OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2235N_("pass it through git-apply"),22360),2237OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2238N_("format the patch(es) are in"),2239 parse_opt_patchformat),2240OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2241N_("pass it through git-apply"),2242 PARSE_OPT_NOARG),2243OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2244N_("override error message when patch failure occurs")),2245OPT_CMDMODE(0,"continue", &resume,2246N_("continue applying patches after resolving a conflict"),2247 RESUME_RESOLVED),2248OPT_CMDMODE('r',"resolved", &resume,2249N_("synonyms for --continue"),2250 RESUME_RESOLVED),2251OPT_CMDMODE(0,"skip", &resume,2252N_("skip the current patch"),2253 RESUME_SKIP),2254OPT_CMDMODE(0,"abort", &resume,2255N_("restore the original branch and abort the patching operation."),2256 RESUME_ABORT),2257OPT_BOOL(0,"committer-date-is-author-date",2258&state.committer_date_is_author_date,2259N_("lie about committer date")),2260OPT_BOOL(0,"ignore-date", &state.ignore_date,2261N_("use current timestamp for author date")),2262OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2263{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2264N_("GPG-sign commits"),2265 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2266OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2267N_("(internal use for git-rebase)")),2268OPT_END()2269};22702271git_config(git_default_config, NULL);22722273am_state_init(&state,git_path("rebase-apply"));22742275 in_progress =am_in_progress(&state);2276if(in_progress)2277am_load(&state);22782279 argc =parse_options(argc, argv, prefix, options, usage,0);22802281if(binary >=0)2282fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2283"it will be removed. Please do not use it anymore."));22842285/* Ensure a valid committer ident can be constructed */2286git_committer_info(IDENT_STRICT);22872288if(read_index_preload(&the_index, NULL) <0)2289die(_("failed to read the index"));22902291if(in_progress) {2292/*2293 * Catch user error to feed us patches when there is a session2294 * in progress:2295 *2296 * 1. mbox path(s) are provided on the command-line.2297 * 2. stdin is not a tty: the user is trying to feed us a patch2298 * from standard input. This is somewhat unreliable -- stdin2299 * could be /dev/null for example and the caller did not2300 * intend to feed us a patch but wanted to continue2301 * unattended.2302 */2303if(argc || (resume == RESUME_FALSE && !isatty(0)))2304die(_("previous rebase directory%sstill exists but mbox given."),2305 state.dir);23062307if(resume == RESUME_FALSE)2308 resume = RESUME_APPLY;23092310if(state.signoff == SIGNOFF_EXPLICIT)2311am_append_signoff(&state);2312}else{2313struct argv_array paths = ARGV_ARRAY_INIT;2314int i;23152316/*2317 * Handle stray state directory in the independent-run case. In2318 * the --rebasing case, it is up to the caller to take care of2319 * stray directories.2320 */2321if(file_exists(state.dir) && !state.rebasing) {2322if(resume == RESUME_ABORT) {2323am_destroy(&state);2324am_state_release(&state);2325return0;2326}23272328die(_("Stray%sdirectory found.\n"2329"Use\"git am --abort\"to remove it."),2330 state.dir);2331}23322333if(resume)2334die(_("Resolve operation not in progress, we are not resuming."));23352336for(i =0; i < argc; i++) {2337if(is_absolute_path(argv[i]) || !prefix)2338argv_array_push(&paths, argv[i]);2339else2340argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2341}23422343am_setup(&state, patch_format, paths.argv, keep_cr);23442345argv_array_clear(&paths);2346}23472348switch(resume) {2349case RESUME_FALSE:2350am_run(&state,0);2351break;2352case RESUME_APPLY:2353am_run(&state,1);2354break;2355case RESUME_RESOLVED:2356am_resolve(&state);2357break;2358case RESUME_SKIP:2359am_skip(&state);2360break;2361case RESUME_ABORT:2362am_abort(&state);2363break;2364default:2365die("BUG: invalid resume value");2366}23672368am_state_release(&state);23692370return0;2371}