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"tempfile.h" 14#include"lockfile.h" 15#include"cache-tree.h" 16#include"refs.h" 17#include"commit.h" 18#include"diff.h" 19#include"diffcore.h" 20#include"unpack-trees.h" 21#include"branch.h" 22#include"sequencer.h" 23#include"revision.h" 24#include"merge-recursive.h" 25#include"revision.h" 26#include"log-tree.h" 27#include"notes-utils.h" 28#include"rerere.h" 29#include"prompt.h" 30 31/** 32 * Returns 1 if the file is empty or does not exist, 0 otherwise. 33 */ 34static intis_empty_file(const char*filename) 35{ 36struct stat st; 37 38if(stat(filename, &st) <0) { 39if(errno == ENOENT) 40return1; 41die_errno(_("could not stat%s"), filename); 42} 43 44return!st.st_size; 45} 46 47/** 48 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. 49 */ 50static intstrbuf_getline_crlf(struct strbuf *sb,FILE*fp) 51{ 52if(strbuf_getwholeline(sb, fp,'\n')) 53return EOF; 54if(sb->buf[sb->len -1] =='\n') { 55strbuf_setlen(sb, sb->len -1); 56if(sb->len >0&& sb->buf[sb->len -1] =='\r') 57strbuf_setlen(sb, sb->len -1); 58} 59return0; 60} 61 62/** 63 * Returns the length of the first line of msg. 64 */ 65static intlinelen(const char*msg) 66{ 67returnstrchrnul(msg,'\n') - msg; 68} 69 70/** 71 * Returns true if `str` consists of only whitespace, false otherwise. 72 */ 73static intstr_isspace(const char*str) 74{ 75for(; *str; str++) 76if(!isspace(*str)) 77return0; 78 79return1; 80} 81 82enum patch_format { 83 PATCH_FORMAT_UNKNOWN =0, 84 PATCH_FORMAT_MBOX, 85 PATCH_FORMAT_STGIT, 86 PATCH_FORMAT_STGIT_SERIES, 87 PATCH_FORMAT_HG 88}; 89 90enum keep_type { 91 KEEP_FALSE =0, 92 KEEP_TRUE,/* pass -k flag to git-mailinfo */ 93 KEEP_NON_PATCH /* pass -b flag to git-mailinfo */ 94}; 95 96enum scissors_type { 97 SCISSORS_UNSET = -1, 98 SCISSORS_FALSE =0,/* pass --no-scissors to git-mailinfo */ 99 SCISSORS_TRUE /* pass --scissors to git-mailinfo */ 100}; 101 102enum signoff_type { 103 SIGNOFF_FALSE =0, 104 SIGNOFF_TRUE =1, 105 SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ 106}; 107 108struct am_state { 109/* state directory path */ 110char*dir; 111 112/* current and last patch numbers, 1-indexed */ 113int cur; 114int last; 115 116/* commit metadata and message */ 117char*author_name; 118char*author_email; 119char*author_date; 120char*msg; 121size_t msg_len; 122 123/* when --rebasing, records the original commit the patch came from */ 124unsigned char orig_commit[GIT_SHA1_RAWSZ]; 125 126/* number of digits in patch filename */ 127int prec; 128 129/* various operating modes and command line options */ 130int interactive; 131int threeway; 132int quiet; 133int signoff;/* enum signoff_type */ 134int utf8; 135int keep;/* enum keep_type */ 136int message_id; 137int scissors;/* enum scissors_type */ 138struct argv_array git_apply_opts; 139const char*resolvemsg; 140int committer_date_is_author_date; 141int ignore_date; 142int allow_rerere_autoupdate; 143const char*sign_commit; 144int rebasing; 145}; 146 147/** 148 * Initializes am_state with the default values. The state directory is set to 149 * dir. 150 */ 151static voidam_state_init(struct am_state *state,const char*dir) 152{ 153int gpgsign; 154 155memset(state,0,sizeof(*state)); 156 157assert(dir); 158 state->dir =xstrdup(dir); 159 160 state->prec =4; 161 162git_config_get_bool("am.threeway", &state->threeway); 163 164 state->utf8 =1; 165 166git_config_get_bool("am.messageid", &state->message_id); 167 168 state->scissors = SCISSORS_UNSET; 169 170argv_array_init(&state->git_apply_opts); 171 172if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 173 state->sign_commit = gpgsign ?"": NULL; 174} 175 176/** 177 * Releases memory allocated by an am_state. 178 */ 179static voidam_state_release(struct am_state *state) 180{ 181free(state->dir); 182free(state->author_name); 183free(state->author_email); 184free(state->author_date); 185free(state->msg); 186argv_array_clear(&state->git_apply_opts); 187} 188 189/** 190 * Returns path relative to the am_state directory. 191 */ 192staticinlineconst char*am_path(const struct am_state *state,const char*path) 193{ 194returnmkpath("%s/%s", state->dir, path); 195} 196 197/** 198 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 199 * at the end. 200 */ 201static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 202{ 203va_list ap; 204 205va_start(ap, fmt); 206if(!state->quiet) { 207vfprintf(fp, fmt, ap); 208putc('\n', fp); 209} 210va_end(ap); 211} 212 213/** 214 * Returns 1 if there is an am session in progress, 0 otherwise. 215 */ 216static intam_in_progress(const struct am_state *state) 217{ 218struct stat st; 219 220if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 221return0; 222if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 223return0; 224if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 225return0; 226return1; 227} 228 229/** 230 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 231 * number of bytes read on success, -1 if the file does not exist. If `trim` is 232 * set, trailing whitespace will be removed. 233 */ 234static intread_state_file(struct strbuf *sb,const struct am_state *state, 235const char*file,int trim) 236{ 237strbuf_reset(sb); 238 239if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 240if(trim) 241strbuf_trim(sb); 242 243return sb->len; 244} 245 246if(errno == ENOENT) 247return-1; 248 249die_errno(_("could not read '%s'"),am_path(state, file)); 250} 251 252/** 253 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 254 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 255 * match `key`. Returns NULL on failure. 256 * 257 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 258 * the author-script. 259 */ 260static char*read_shell_var(FILE*fp,const char*key) 261{ 262struct strbuf sb = STRBUF_INIT; 263const char*str; 264 265if(strbuf_getline(&sb, fp,'\n')) 266goto fail; 267 268if(!skip_prefix(sb.buf, key, &str)) 269goto fail; 270 271if(!skip_prefix(str,"=", &str)) 272goto fail; 273 274strbuf_remove(&sb,0, str - sb.buf); 275 276 str =sq_dequote(sb.buf); 277if(!str) 278goto fail; 279 280returnstrbuf_detach(&sb, NULL); 281 282fail: 283strbuf_release(&sb); 284return NULL; 285} 286 287/** 288 * Reads and parses the state directory's "author-script" file, and sets 289 * state->author_name, state->author_email and state->author_date accordingly. 290 * Returns 0 on success, -1 if the file could not be parsed. 291 * 292 * The author script is of the format: 293 * 294 * GIT_AUTHOR_NAME='$author_name' 295 * GIT_AUTHOR_EMAIL='$author_email' 296 * GIT_AUTHOR_DATE='$author_date' 297 * 298 * where $author_name, $author_email and $author_date are quoted. We are strict 299 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 300 * script, and thus if the file differs from what this function expects, it is 301 * better to bail out than to do something that the user does not expect. 302 */ 303static intread_author_script(struct am_state *state) 304{ 305const char*filename =am_path(state,"author-script"); 306FILE*fp; 307 308assert(!state->author_name); 309assert(!state->author_email); 310assert(!state->author_date); 311 312 fp =fopen(filename,"r"); 313if(!fp) { 314if(errno == ENOENT) 315return0; 316die_errno(_("could not open '%s' for reading"), filename); 317} 318 319 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 320if(!state->author_name) { 321fclose(fp); 322return-1; 323} 324 325 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 326if(!state->author_email) { 327fclose(fp); 328return-1; 329} 330 331 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 332if(!state->author_date) { 333fclose(fp); 334return-1; 335} 336 337if(fgetc(fp) != EOF) { 338fclose(fp); 339return-1; 340} 341 342fclose(fp); 343return0; 344} 345 346/** 347 * Saves state->author_name, state->author_email and state->author_date in the 348 * state directory's "author-script" file. 349 */ 350static voidwrite_author_script(const struct am_state *state) 351{ 352struct strbuf sb = STRBUF_INIT; 353 354strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 355sq_quote_buf(&sb, state->author_name); 356strbuf_addch(&sb,'\n'); 357 358strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 359sq_quote_buf(&sb, state->author_email); 360strbuf_addch(&sb,'\n'); 361 362strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 363sq_quote_buf(&sb, state->author_date); 364strbuf_addch(&sb,'\n'); 365 366write_file(am_path(state,"author-script"),1,"%s", sb.buf); 367 368strbuf_release(&sb); 369} 370 371/** 372 * Reads the commit message from the state directory's "final-commit" file, 373 * setting state->msg to its contents and state->msg_len to the length of its 374 * contents in bytes. 375 * 376 * Returns 0 on success, -1 if the file does not exist. 377 */ 378static intread_commit_msg(struct am_state *state) 379{ 380struct strbuf sb = STRBUF_INIT; 381 382assert(!state->msg); 383 384if(read_state_file(&sb, state,"final-commit",0) <0) { 385strbuf_release(&sb); 386return-1; 387} 388 389 state->msg =strbuf_detach(&sb, &state->msg_len); 390return0; 391} 392 393/** 394 * Saves state->msg in the state directory's "final-commit" file. 395 */ 396static voidwrite_commit_msg(const struct am_state *state) 397{ 398int fd; 399const char*filename =am_path(state,"final-commit"); 400 401 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 402if(write_in_full(fd, state->msg, state->msg_len) <0) 403die_errno(_("could not write to%s"), filename); 404close(fd); 405} 406 407/** 408 * Loads state from disk. 409 */ 410static voidam_load(struct am_state *state) 411{ 412struct strbuf sb = STRBUF_INIT; 413 414if(read_state_file(&sb, state,"next",1) <0) 415die("BUG: state file 'next' does not exist"); 416 state->cur =strtol(sb.buf, NULL,10); 417 418if(read_state_file(&sb, state,"last",1) <0) 419die("BUG: state file 'last' does not exist"); 420 state->last =strtol(sb.buf, NULL,10); 421 422if(read_author_script(state) <0) 423die(_("could not parse author script")); 424 425read_commit_msg(state); 426 427if(read_state_file(&sb, state,"original-commit",1) <0) 428hashclr(state->orig_commit); 429else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 430die(_("could not parse%s"),am_path(state,"original-commit")); 431 432read_state_file(&sb, state,"threeway",1); 433 state->threeway = !strcmp(sb.buf,"t"); 434 435read_state_file(&sb, state,"quiet",1); 436 state->quiet = !strcmp(sb.buf,"t"); 437 438read_state_file(&sb, state,"sign",1); 439 state->signoff = !strcmp(sb.buf,"t"); 440 441read_state_file(&sb, state,"utf8",1); 442 state->utf8 = !strcmp(sb.buf,"t"); 443 444read_state_file(&sb, state,"keep",1); 445if(!strcmp(sb.buf,"t")) 446 state->keep = KEEP_TRUE; 447else if(!strcmp(sb.buf,"b")) 448 state->keep = KEEP_NON_PATCH; 449else 450 state->keep = KEEP_FALSE; 451 452read_state_file(&sb, state,"messageid",1); 453 state->message_id = !strcmp(sb.buf,"t"); 454 455read_state_file(&sb, state,"scissors",1); 456if(!strcmp(sb.buf,"t")) 457 state->scissors = SCISSORS_TRUE; 458else if(!strcmp(sb.buf,"f")) 459 state->scissors = SCISSORS_FALSE; 460else 461 state->scissors = SCISSORS_UNSET; 462 463read_state_file(&sb, state,"apply-opt",1); 464argv_array_clear(&state->git_apply_opts); 465if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 466die(_("could not parse%s"),am_path(state,"apply-opt")); 467 468 state->rebasing = !!file_exists(am_path(state,"rebasing")); 469 470strbuf_release(&sb); 471} 472 473/** 474 * Removes the am_state directory, forcefully terminating the current am 475 * session. 476 */ 477static voidam_destroy(const struct am_state *state) 478{ 479struct strbuf sb = STRBUF_INIT; 480 481strbuf_addstr(&sb, state->dir); 482remove_dir_recursively(&sb,0); 483strbuf_release(&sb); 484} 485 486/** 487 * Runs applypatch-msg hook. Returns its exit code. 488 */ 489static intrun_applypatch_msg_hook(struct am_state *state) 490{ 491int ret; 492 493assert(state->msg); 494 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 495 496if(!ret) { 497free(state->msg); 498 state->msg = NULL; 499if(read_commit_msg(state) <0) 500die(_("'%s' was deleted by the applypatch-msg hook"), 501am_path(state,"final-commit")); 502} 503 504return ret; 505} 506 507/** 508 * Runs post-rewrite hook. Returns it exit code. 509 */ 510static intrun_post_rewrite_hook(const struct am_state *state) 511{ 512struct child_process cp = CHILD_PROCESS_INIT; 513const char*hook =find_hook("post-rewrite"); 514int ret; 515 516if(!hook) 517return0; 518 519argv_array_push(&cp.args, hook); 520argv_array_push(&cp.args,"rebase"); 521 522 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 523 cp.stdout_to_stderr =1; 524 525 ret =run_command(&cp); 526 527close(cp.in); 528return ret; 529} 530 531/** 532 * Reads the state directory's "rewritten" file, and copies notes from the old 533 * commits listed in the file to their rewritten commits. 534 * 535 * Returns 0 on success, -1 on failure. 536 */ 537static intcopy_notes_for_rebase(const struct am_state *state) 538{ 539struct notes_rewrite_cfg *c; 540struct strbuf sb = STRBUF_INIT; 541const char*invalid_line =_("Malformed input line: '%s'."); 542const char*msg ="Notes added by 'git rebase'"; 543FILE*fp; 544int ret =0; 545 546assert(state->rebasing); 547 548 c =init_copy_notes_for_rewrite("rebase"); 549if(!c) 550return0; 551 552 fp =xfopen(am_path(state,"rewritten"),"r"); 553 554while(!strbuf_getline(&sb, fp,'\n')) { 555unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 556 557if(sb.len != GIT_SHA1_HEXSZ *2+1) { 558 ret =error(invalid_line, sb.buf); 559goto finish; 560} 561 562if(get_sha1_hex(sb.buf, from_obj)) { 563 ret =error(invalid_line, sb.buf); 564goto finish; 565} 566 567if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 568 ret =error(invalid_line, sb.buf); 569goto finish; 570} 571 572if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 573 ret =error(invalid_line, sb.buf); 574goto finish; 575} 576 577if(copy_note_for_rewrite(c, from_obj, to_obj)) 578 ret =error(_("Failed to copy notes from '%s' to '%s'"), 579sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 580} 581 582finish: 583finish_copy_notes_for_rewrite(c, msg); 584fclose(fp); 585strbuf_release(&sb); 586return ret; 587} 588 589/** 590 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 591 * non-indented lines and checking if they look like they begin with valid 592 * header field names. 593 * 594 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 595 */ 596static intis_mail(FILE*fp) 597{ 598const char*header_regex ="^[!-9;-~]+:"; 599struct strbuf sb = STRBUF_INIT; 600 regex_t regex; 601int ret =1; 602 603if(fseek(fp,0L, SEEK_SET)) 604die_errno(_("fseek failed")); 605 606if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 607die("invalid pattern:%s", header_regex); 608 609while(!strbuf_getline_crlf(&sb, fp)) { 610if(!sb.len) 611break;/* End of header */ 612 613/* Ignore indented folded lines */ 614if(*sb.buf =='\t'|| *sb.buf ==' ') 615continue; 616 617/* It's a header if it matches header_regex */ 618if(regexec(®ex, sb.buf,0, NULL,0)) { 619 ret =0; 620goto done; 621} 622} 623 624done: 625regfree(®ex); 626strbuf_release(&sb); 627return ret; 628} 629 630/** 631 * Attempts to detect the patch_format of the patches contained in `paths`, 632 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 633 * detection fails. 634 */ 635static intdetect_patch_format(const char**paths) 636{ 637enum patch_format ret = PATCH_FORMAT_UNKNOWN; 638struct strbuf l1 = STRBUF_INIT; 639struct strbuf l2 = STRBUF_INIT; 640struct strbuf l3 = STRBUF_INIT; 641FILE*fp; 642 643/* 644 * We default to mbox format if input is from stdin and for directories 645 */ 646if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 647return PATCH_FORMAT_MBOX; 648 649/* 650 * Otherwise, check the first few lines of the first patch, starting 651 * from the first non-blank line, to try to detect its format. 652 */ 653 654 fp =xfopen(*paths,"r"); 655 656while(!strbuf_getline_crlf(&l1, fp)) { 657if(l1.len) 658break; 659} 660 661if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 662 ret = PATCH_FORMAT_MBOX; 663goto done; 664} 665 666if(starts_with(l1.buf,"# This series applies on GIT commit")) { 667 ret = PATCH_FORMAT_STGIT_SERIES; 668goto done; 669} 670 671if(!strcmp(l1.buf,"# HG changeset patch")) { 672 ret = PATCH_FORMAT_HG; 673goto done; 674} 675 676strbuf_reset(&l2); 677strbuf_getline_crlf(&l2, fp); 678strbuf_reset(&l3); 679strbuf_getline_crlf(&l3, fp); 680 681/* 682 * If the second line is empty and the third is a From, Author or Date 683 * entry, this is likely an StGit patch. 684 */ 685if(l1.len && !l2.len && 686(starts_with(l3.buf,"From:") || 687starts_with(l3.buf,"Author:") || 688starts_with(l3.buf,"Date:"))) { 689 ret = PATCH_FORMAT_STGIT; 690goto done; 691} 692 693if(l1.len &&is_mail(fp)) { 694 ret = PATCH_FORMAT_MBOX; 695goto done; 696} 697 698done: 699fclose(fp); 700strbuf_release(&l1); 701return ret; 702} 703 704/** 705 * Splits out individual email patches from `paths`, where each path is either 706 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 707 */ 708static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 709{ 710struct child_process cp = CHILD_PROCESS_INIT; 711struct strbuf last = STRBUF_INIT; 712 713 cp.git_cmd =1; 714argv_array_push(&cp.args,"mailsplit"); 715argv_array_pushf(&cp.args,"-d%d", state->prec); 716argv_array_pushf(&cp.args,"-o%s", state->dir); 717argv_array_push(&cp.args,"-b"); 718if(keep_cr) 719argv_array_push(&cp.args,"--keep-cr"); 720argv_array_push(&cp.args,"--"); 721argv_array_pushv(&cp.args, paths); 722 723if(capture_command(&cp, &last,8)) 724return-1; 725 726 state->cur =1; 727 state->last =strtol(last.buf, NULL,10); 728 729return0; 730} 731 732/** 733 * Callback signature for split_mail_conv(). The foreign patch should be 734 * read from `in`, and the converted patch (in RFC2822 mail format) should be 735 * written to `out`. Return 0 on success, or -1 on failure. 736 */ 737typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 738 739/** 740 * Calls `fn` for each file in `paths` to convert the foreign patch to the 741 * RFC2822 mail format suitable for parsing with git-mailinfo. 742 * 743 * Returns 0 on success, -1 on failure. 744 */ 745static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 746const char**paths,int keep_cr) 747{ 748static const char*stdin_only[] = {"-", NULL}; 749int i; 750 751if(!*paths) 752 paths = stdin_only; 753 754for(i =0; *paths; paths++, i++) { 755FILE*in, *out; 756const char*mail; 757int ret; 758 759if(!strcmp(*paths,"-")) 760 in = stdin; 761else 762 in =fopen(*paths,"r"); 763 764if(!in) 765returnerror(_("could not open '%s' for reading:%s"), 766*paths,strerror(errno)); 767 768 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 769 770 out =fopen(mail,"w"); 771if(!out) 772returnerror(_("could not open '%s' for writing:%s"), 773 mail,strerror(errno)); 774 775 ret =fn(out, in, keep_cr); 776 777fclose(out); 778fclose(in); 779 780if(ret) 781returnerror(_("could not parse patch '%s'"), *paths); 782} 783 784 state->cur =1; 785 state->last = i; 786return0; 787} 788 789/** 790 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 791 * message suitable for parsing with git-mailinfo. 792 */ 793static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 794{ 795struct strbuf sb = STRBUF_INIT; 796int subject_printed =0; 797 798while(!strbuf_getline(&sb, in,'\n')) { 799const char*str; 800 801if(str_isspace(sb.buf)) 802continue; 803else if(skip_prefix(sb.buf,"Author:", &str)) 804fprintf(out,"From:%s\n", str); 805else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 806fprintf(out,"%s\n", sb.buf); 807else if(!subject_printed) { 808fprintf(out,"Subject:%s\n", sb.buf); 809 subject_printed =1; 810}else{ 811fprintf(out,"\n%s\n", sb.buf); 812break; 813} 814} 815 816strbuf_reset(&sb); 817while(strbuf_fread(&sb,8192, in) >0) { 818fwrite(sb.buf,1, sb.len, out); 819strbuf_reset(&sb); 820} 821 822strbuf_release(&sb); 823return0; 824} 825 826/** 827 * This function only supports a single StGit series file in `paths`. 828 * 829 * Given an StGit series file, converts the StGit patches in the series into 830 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 831 * the state directory. 832 * 833 * Returns 0 on success, -1 on failure. 834 */ 835static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 836int keep_cr) 837{ 838const char*series_dir; 839char*series_dir_buf; 840FILE*fp; 841struct argv_array patches = ARGV_ARRAY_INIT; 842struct strbuf sb = STRBUF_INIT; 843int ret; 844 845if(!paths[0] || paths[1]) 846returnerror(_("Only one StGIT patch series can be applied at once")); 847 848 series_dir_buf =xstrdup(*paths); 849 series_dir =dirname(series_dir_buf); 850 851 fp =fopen(*paths,"r"); 852if(!fp) 853returnerror(_("could not open '%s' for reading:%s"), *paths, 854strerror(errno)); 855 856while(!strbuf_getline(&sb, fp,'\n')) { 857if(*sb.buf =='#') 858continue;/* skip comment lines */ 859 860argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 861} 862 863fclose(fp); 864strbuf_release(&sb); 865free(series_dir_buf); 866 867 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 868 869argv_array_clear(&patches); 870return ret; 871} 872 873/** 874 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 875 * message suitable for parsing with git-mailinfo. 876 */ 877static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 878{ 879struct strbuf sb = STRBUF_INIT; 880 881while(!strbuf_getline(&sb, in,'\n')) { 882const char*str; 883 884if(skip_prefix(sb.buf,"# User ", &str)) 885fprintf(out,"From:%s\n", str); 886else if(skip_prefix(sb.buf,"# Date ", &str)) { 887unsigned long timestamp; 888long tz, tz2; 889char*end; 890 891 errno =0; 892 timestamp =strtoul(str, &end,10); 893if(errno) 894returnerror(_("invalid timestamp")); 895 896if(!skip_prefix(end," ", &str)) 897returnerror(_("invalid Date line")); 898 899 errno =0; 900 tz =strtol(str, &end,10); 901if(errno) 902returnerror(_("invalid timezone offset")); 903 904if(*end) 905returnerror(_("invalid Date line")); 906 907/* 908 * mercurial's timezone is in seconds west of UTC, 909 * however git's timezone is in hours + minutes east of 910 * UTC. Convert it. 911 */ 912 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 913if(tz >0) 914 tz2 = -tz2; 915 916fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 917}else if(starts_with(sb.buf,"# ")) { 918continue; 919}else{ 920fprintf(out,"\n%s\n", sb.buf); 921break; 922} 923} 924 925strbuf_reset(&sb); 926while(strbuf_fread(&sb,8192, in) >0) { 927fwrite(sb.buf,1, sb.len, out); 928strbuf_reset(&sb); 929} 930 931strbuf_release(&sb); 932return0; 933} 934 935/** 936 * Splits a list of files/directories into individual email patches. Each path 937 * in `paths` must be a file/directory that is formatted according to 938 * `patch_format`. 939 * 940 * Once split out, the individual email patches will be stored in the state 941 * directory, with each patch's filename being its index, padded to state->prec 942 * digits. 943 * 944 * state->cur will be set to the index of the first mail, and state->last will 945 * be set to the index of the last mail. 946 * 947 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 948 * to disable this behavior, -1 to use the default configured setting. 949 * 950 * Returns 0 on success, -1 on failure. 951 */ 952static intsplit_mail(struct am_state *state,enum patch_format patch_format, 953const char**paths,int keep_cr) 954{ 955if(keep_cr <0) { 956 keep_cr =0; 957git_config_get_bool("am.keepcr", &keep_cr); 958} 959 960switch(patch_format) { 961case PATCH_FORMAT_MBOX: 962returnsplit_mail_mbox(state, paths, keep_cr); 963case PATCH_FORMAT_STGIT: 964returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 965case PATCH_FORMAT_STGIT_SERIES: 966returnsplit_mail_stgit_series(state, paths, keep_cr); 967case PATCH_FORMAT_HG: 968returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 969default: 970die("BUG: invalid patch_format"); 971} 972return-1; 973} 974 975/** 976 * Setup a new am session for applying patches 977 */ 978static voidam_setup(struct am_state *state,enum patch_format patch_format, 979const char**paths,int keep_cr) 980{ 981unsigned char curr_head[GIT_SHA1_RAWSZ]; 982const char*str; 983struct strbuf sb = STRBUF_INIT; 984 985if(!patch_format) 986 patch_format =detect_patch_format(paths); 987 988if(!patch_format) { 989fprintf_ln(stderr,_("Patch format detection failed.")); 990exit(128); 991} 992 993if(mkdir(state->dir,0777) <0&& errno != EEXIST) 994die_errno(_("failed to create directory '%s'"), state->dir); 995 996if(split_mail(state, patch_format, paths, keep_cr) <0) { 997am_destroy(state); 998die(_("Failed to split patches.")); 999}10001001if(state->rebasing)1002 state->threeway =1;10031004write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f");10051006write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f");10071008write_file(am_path(state,"sign"),1, state->signoff ?"t":"f");10091010write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f");10111012switch(state->keep) {1013case KEEP_FALSE:1014 str ="f";1015break;1016case KEEP_TRUE:1017 str ="t";1018break;1019case KEEP_NON_PATCH:1020 str ="b";1021break;1022default:1023die("BUG: invalid value for state->keep");1024}10251026write_file(am_path(state,"keep"),1,"%s", str);10271028write_file(am_path(state,"messageid"),1, state->message_id ?"t":"f");10291030switch(state->scissors) {1031case SCISSORS_UNSET:1032 str ="";1033break;1034case SCISSORS_FALSE:1035 str ="f";1036break;1037case SCISSORS_TRUE:1038 str ="t";1039break;1040default:1041die("BUG: invalid value for state->scissors");1042}10431044write_file(am_path(state,"scissors"),1,"%s", str);10451046sq_quote_argv(&sb, state->git_apply_opts.argv,0);1047write_file(am_path(state,"apply-opt"),1,"%s", sb.buf);10481049if(state->rebasing)1050write_file(am_path(state,"rebasing"),1,"%s","");1051else1052write_file(am_path(state,"applying"),1,"%s","");10531054if(!get_sha1("HEAD", curr_head)) {1055write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head));1056if(!state->rebasing)1057update_ref("am","ORIG_HEAD", curr_head, NULL,0,1058 UPDATE_REFS_DIE_ON_ERR);1059}else{1060write_file(am_path(state,"abort-safety"),1,"%s","");1061if(!state->rebasing)1062delete_ref("ORIG_HEAD", NULL,0);1063}10641065/*1066 * NOTE: Since the "next" and "last" files determine if an am_state1067 * session is in progress, they should be written last.1068 */10691070write_file(am_path(state,"next"),1,"%d", state->cur);10711072write_file(am_path(state,"last"),1,"%d", state->last);10731074strbuf_release(&sb);1075}10761077/**1078 * Increments the patch pointer, and cleans am_state for the application of the1079 * next patch.1080 */1081static voidam_next(struct am_state *state)1082{1083unsigned char head[GIT_SHA1_RAWSZ];10841085free(state->author_name);1086 state->author_name = NULL;10871088free(state->author_email);1089 state->author_email = NULL;10901091free(state->author_date);1092 state->author_date = NULL;10931094free(state->msg);1095 state->msg = NULL;1096 state->msg_len =0;10971098unlink(am_path(state,"author-script"));1099unlink(am_path(state,"final-commit"));11001101hashclr(state->orig_commit);1102unlink(am_path(state,"original-commit"));11031104if(!get_sha1("HEAD", head))1105write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head));1106else1107write_file(am_path(state,"abort-safety"),1,"%s","");11081109 state->cur++;1110write_file(am_path(state,"next"),1,"%d", state->cur);1111}11121113/**1114 * Returns the filename of the current patch email.1115 */1116static const char*msgnum(const struct am_state *state)1117{1118static struct strbuf sb = STRBUF_INIT;11191120strbuf_reset(&sb);1121strbuf_addf(&sb,"%0*d", state->prec, state->cur);11221123return sb.buf;1124}11251126/**1127 * Refresh and write index.1128 */1129static voidrefresh_and_write_cache(void)1130{1131struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11321133hold_locked_index(lock_file,1);1134refresh_cache(REFRESH_QUIET);1135if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1136die(_("unable to write index file"));1137}11381139/**1140 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1141 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1142 * strbuf is provided, the space-separated list of files that differ will be1143 * appended to it.1144 */1145static intindex_has_changes(struct strbuf *sb)1146{1147unsigned char head[GIT_SHA1_RAWSZ];1148int i;11491150if(!get_sha1_tree("HEAD", head)) {1151struct diff_options opt;11521153diff_setup(&opt);1154DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1155if(!sb)1156DIFF_OPT_SET(&opt, QUICK);1157do_diff_cache(head, &opt);1158diffcore_std(&opt);1159for(i =0; sb && i < diff_queued_diff.nr; i++) {1160if(i)1161strbuf_addch(sb,' ');1162strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1163}1164diff_flush(&opt);1165returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1166}else{1167for(i =0; sb && i < active_nr; i++) {1168if(i)1169strbuf_addch(sb,' ');1170strbuf_addstr(sb, active_cache[i]->name);1171}1172return!!active_nr;1173}1174}11751176/**1177 * Dies with a user-friendly message on how to proceed after resolving the1178 * problem. This message can be overridden with state->resolvemsg.1179 */1180static void NORETURN die_user_resolve(const struct am_state *state)1181{1182if(state->resolvemsg) {1183printf_ln("%s", state->resolvemsg);1184}else{1185const char*cmdline = state->interactive ?"git am -i":"git am";11861187printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1188printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1189printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1190}11911192exit(128);1193}11941195/**1196 * Appends signoff to the "msg" field of the am_state.1197 */1198static voidam_append_signoff(struct am_state *state)1199{1200struct strbuf sb = STRBUF_INIT;12011202strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);1203append_signoff(&sb,0,0);1204 state->msg =strbuf_detach(&sb, &state->msg_len);1205}12061207/**1208 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1209 * state->msg will be set to the patch message. state->author_name,1210 * state->author_email and state->author_date will be set to the patch author's1211 * name, email and date respectively. The patch body will be written to the1212 * state directory's "patch" file.1213 *1214 * Returns 1 if the patch should be skipped, 0 otherwise.1215 */1216static intparse_mail(struct am_state *state,const char*mail)1217{1218FILE*fp;1219struct child_process cp = CHILD_PROCESS_INIT;1220struct strbuf sb = STRBUF_INIT;1221struct strbuf msg = STRBUF_INIT;1222struct strbuf author_name = STRBUF_INIT;1223struct strbuf author_date = STRBUF_INIT;1224struct strbuf author_email = STRBUF_INIT;1225int ret =0;12261227 cp.git_cmd =1;1228 cp.in =xopen(mail, O_RDONLY,0);1229 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777);12301231argv_array_push(&cp.args,"mailinfo");1232argv_array_push(&cp.args, state->utf8 ?"-u":"-n");12331234switch(state->keep) {1235case KEEP_FALSE:1236break;1237case KEEP_TRUE:1238argv_array_push(&cp.args,"-k");1239break;1240case KEEP_NON_PATCH:1241argv_array_push(&cp.args,"-b");1242break;1243default:1244die("BUG: invalid value for state->keep");1245}12461247if(state->message_id)1248argv_array_push(&cp.args,"-m");12491250switch(state->scissors) {1251case SCISSORS_UNSET:1252break;1253case SCISSORS_FALSE:1254argv_array_push(&cp.args,"--no-scissors");1255break;1256case SCISSORS_TRUE:1257argv_array_push(&cp.args,"--scissors");1258break;1259default:1260die("BUG: invalid value for state->scissors");1261}12621263argv_array_push(&cp.args,am_path(state,"msg"));1264argv_array_push(&cp.args,am_path(state,"patch"));12651266if(run_command(&cp) <0)1267die("could not parse patch");12681269close(cp.in);1270close(cp.out);12711272/* Extract message and author information */1273 fp =xfopen(am_path(state,"info"),"r");1274while(!strbuf_getline(&sb, fp,'\n')) {1275const char*x;12761277if(skip_prefix(sb.buf,"Subject: ", &x)) {1278if(msg.len)1279strbuf_addch(&msg,'\n');1280strbuf_addstr(&msg, x);1281}else if(skip_prefix(sb.buf,"Author: ", &x))1282strbuf_addstr(&author_name, x);1283else if(skip_prefix(sb.buf,"Email: ", &x))1284strbuf_addstr(&author_email, x);1285else if(skip_prefix(sb.buf,"Date: ", &x))1286strbuf_addstr(&author_date, x);1287}1288fclose(fp);12891290/* Skip pine's internal folder data */1291if(!strcmp(author_name.buf,"Mail System Internal Data")) {1292 ret =1;1293goto finish;1294}12951296if(is_empty_file(am_path(state,"patch"))) {1297printf_ln(_("Patch is empty. Was it split wrong?"));1298die_user_resolve(state);1299}13001301strbuf_addstr(&msg,"\n\n");1302if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0)1303die_errno(_("could not read '%s'"),am_path(state,"msg"));1304stripspace(&msg,0);13051306if(state->signoff)1307append_signoff(&msg,0,0);13081309assert(!state->author_name);1310 state->author_name =strbuf_detach(&author_name, NULL);13111312assert(!state->author_email);1313 state->author_email =strbuf_detach(&author_email, NULL);13141315assert(!state->author_date);1316 state->author_date =strbuf_detach(&author_date, NULL);13171318assert(!state->msg);1319 state->msg =strbuf_detach(&msg, &state->msg_len);13201321finish:1322strbuf_release(&msg);1323strbuf_release(&author_date);1324strbuf_release(&author_email);1325strbuf_release(&author_name);1326strbuf_release(&sb);1327return ret;1328}13291330/**1331 * Sets commit_id to the commit hash where the mail was generated from.1332 * Returns 0 on success, -1 on failure.1333 */1334static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1335{1336struct strbuf sb = STRBUF_INIT;1337FILE*fp =xfopen(mail,"r");1338const char*x;13391340if(strbuf_getline(&sb, fp,'\n'))1341return-1;13421343if(!skip_prefix(sb.buf,"From ", &x))1344return-1;13451346if(get_sha1_hex(x, commit_id) <0)1347return-1;13481349strbuf_release(&sb);1350fclose(fp);1351return0;1352}13531354/**1355 * Sets state->msg, state->author_name, state->author_email, state->author_date1356 * to the commit's respective info.1357 */1358static voidget_commit_info(struct am_state *state,struct commit *commit)1359{1360const char*buffer, *ident_line, *author_date, *msg;1361size_t ident_len;1362struct ident_split ident_split;1363struct strbuf sb = STRBUF_INIT;13641365 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13661367 ident_line =find_commit_header(buffer,"author", &ident_len);13681369if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1370strbuf_add(&sb, ident_line, ident_len);1371die(_("invalid ident line:%s"), sb.buf);1372}13731374assert(!state->author_name);1375if(ident_split.name_begin) {1376strbuf_add(&sb, ident_split.name_begin,1377 ident_split.name_end - ident_split.name_begin);1378 state->author_name =strbuf_detach(&sb, NULL);1379}else1380 state->author_name =xstrdup("");13811382assert(!state->author_email);1383if(ident_split.mail_begin) {1384strbuf_add(&sb, ident_split.mail_begin,1385 ident_split.mail_end - ident_split.mail_begin);1386 state->author_email =strbuf_detach(&sb, NULL);1387}else1388 state->author_email =xstrdup("");13891390 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1391strbuf_addstr(&sb, author_date);1392assert(!state->author_date);1393 state->author_date =strbuf_detach(&sb, NULL);13941395assert(!state->msg);1396 msg =strstr(buffer,"\n\n");1397if(!msg)1398die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1399 state->msg =xstrdup(msg +2);1400 state->msg_len =strlen(state->msg);1401}14021403/**1404 * Writes `commit` as a patch to the state directory's "patch" file.1405 */1406static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1407{1408struct rev_info rev_info;1409FILE*fp;14101411 fp =xfopen(am_path(state,"patch"),"w");1412init_revisions(&rev_info, NULL);1413 rev_info.diff =1;1414 rev_info.abbrev =0;1415 rev_info.disable_stdin =1;1416 rev_info.show_root_diff =1;1417 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1418 rev_info.no_commit_id =1;1419DIFF_OPT_SET(&rev_info.diffopt, BINARY);1420DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1421 rev_info.diffopt.use_color =0;1422 rev_info.diffopt.file = fp;1423 rev_info.diffopt.close_file =1;1424add_pending_object(&rev_info, &commit->object,"");1425diff_setup_done(&rev_info.diffopt);1426log_tree_commit(&rev_info, commit);1427}14281429/**1430 * Writes the diff of the index against HEAD as a patch to the state1431 * directory's "patch" file.1432 */1433static voidwrite_index_patch(const struct am_state *state)1434{1435struct tree *tree;1436unsigned char head[GIT_SHA1_RAWSZ];1437struct rev_info rev_info;1438FILE*fp;14391440if(!get_sha1_tree("HEAD", head))1441 tree =lookup_tree(head);1442else1443 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14441445 fp =xfopen(am_path(state,"patch"),"w");1446init_revisions(&rev_info, NULL);1447 rev_info.diff =1;1448 rev_info.disable_stdin =1;1449 rev_info.no_commit_id =1;1450 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1451 rev_info.diffopt.use_color =0;1452 rev_info.diffopt.file = fp;1453 rev_info.diffopt.close_file =1;1454add_pending_object(&rev_info, &tree->object,"");1455diff_setup_done(&rev_info.diffopt);1456run_diff_index(&rev_info,1);1457}14581459/**1460 * Like parse_mail(), but parses the mail by looking up its commit ID1461 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1462 * of patches.1463 *1464 * state->orig_commit will be set to the original commit ID.1465 *1466 * Will always return 0 as the patch should never be skipped.1467 */1468static intparse_mail_rebase(struct am_state *state,const char*mail)1469{1470struct commit *commit;1471unsigned char commit_sha1[GIT_SHA1_RAWSZ];14721473if(get_mail_commit_sha1(commit_sha1, mail) <0)1474die(_("could not parse%s"), mail);14751476 commit =lookup_commit_or_die(commit_sha1, mail);14771478get_commit_info(state, commit);14791480write_commit_patch(state, commit);14811482hashcpy(state->orig_commit, commit_sha1);1483write_file(am_path(state,"original-commit"),1,"%s",1484sha1_to_hex(commit_sha1));14851486return0;1487}14881489/**1490 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1491 * `index_file` is not NULL, the patch will be applied to that index.1492 */1493static intrun_apply(const struct am_state *state,const char*index_file)1494{1495struct child_process cp = CHILD_PROCESS_INIT;14961497 cp.git_cmd =1;14981499if(index_file)1500argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);15011502/*1503 * If we are allowed to fall back on 3-way merge, don't give false1504 * errors during the initial attempt.1505 */1506if(state->threeway && !index_file) {1507 cp.no_stdout =1;1508 cp.no_stderr =1;1509}15101511argv_array_push(&cp.args,"apply");15121513argv_array_pushv(&cp.args, state->git_apply_opts.argv);15141515if(index_file)1516argv_array_push(&cp.args,"--cached");1517else1518argv_array_push(&cp.args,"--index");15191520argv_array_push(&cp.args,am_path(state,"patch"));15211522if(run_command(&cp))1523return-1;15241525/* Reload index as git-apply will have modified it. */1526discard_cache();1527read_cache_from(index_file ? index_file :get_index_file());15281529return0;1530}15311532/**1533 * Builds an index that contains just the blobs needed for a 3way merge.1534 */1535static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1536{1537struct child_process cp = CHILD_PROCESS_INIT;15381539 cp.git_cmd =1;1540argv_array_push(&cp.args,"apply");1541argv_array_pushv(&cp.args, state->git_apply_opts.argv);1542argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1543argv_array_push(&cp.args,am_path(state,"patch"));15441545if(run_command(&cp))1546return-1;15471548return0;1549}15501551/**1552 * Attempt a threeway merge, using index_path as the temporary index.1553 */1554static intfall_back_threeway(const struct am_state *state,const char*index_path)1555{1556unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1557 our_tree[GIT_SHA1_RAWSZ];1558const unsigned char*bases[1] = {orig_tree};1559struct merge_options o;1560struct commit *result;1561char*his_tree_name;15621563if(get_sha1("HEAD", our_tree) <0)1564hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);15651566if(build_fake_ancestor(state, index_path))1567returnerror("could not build fake ancestor");15681569discard_cache();1570read_cache_from(index_path);15711572if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1573returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15741575say(state, stdout,_("Using index info to reconstruct a base tree..."));15761577if(!state->quiet) {1578/*1579 * List paths that needed 3-way fallback, so that the user can1580 * review them with extra care to spot mismerges.1581 */1582struct rev_info rev_info;1583const char*diff_filter_str ="--diff-filter=AM";15841585init_revisions(&rev_info, NULL);1586 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1587diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1588add_pending_sha1(&rev_info,"HEAD", our_tree,0);1589diff_setup_done(&rev_info.diffopt);1590run_diff_index(&rev_info,1);1591}15921593if(run_apply(state, index_path))1594returnerror(_("Did you hand edit your patch?\n"1595"It does not apply to blobs recorded in its index."));15961597if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1598returnerror("could not write tree");15991600say(state, stdout,_("Falling back to patching base and 3-way merge..."));16011602discard_cache();1603read_cache();16041605/*1606 * This is not so wrong. Depending on which base we picked, orig_tree1607 * may be wildly different from ours, but his_tree has the same set of1608 * wildly different changes in parts the patch did not touch, so1609 * recursive ends up canceling them, saying that we reverted all those1610 * changes.1611 */16121613init_merge_options(&o);16141615 o.branch1 ="HEAD";1616 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1617 o.branch2 = his_tree_name;16181619if(state->quiet)1620 o.verbosity =0;16211622if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1623rerere(state->allow_rerere_autoupdate);1624free(his_tree_name);1625returnerror(_("Failed to merge in the changes."));1626}16271628free(his_tree_name);1629return0;1630}16311632/**1633 * Commits the current index with state->msg as the commit message and1634 * state->author_name, state->author_email and state->author_date as the author1635 * information.1636 */1637static voiddo_commit(const struct am_state *state)1638{1639unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1640 commit[GIT_SHA1_RAWSZ];1641unsigned char*ptr;1642struct commit_list *parents = NULL;1643const char*reflog_msg, *author;1644struct strbuf sb = STRBUF_INIT;16451646if(run_hook_le(NULL,"pre-applypatch", NULL))1647exit(1);16481649if(write_cache_as_tree(tree,0, NULL))1650die(_("git write-tree failed to write a tree"));16511652if(!get_sha1_commit("HEAD", parent)) {1653 ptr = parent;1654commit_list_insert(lookup_commit(parent), &parents);1655}else{1656 ptr = NULL;1657say(state, stderr,_("applying to an empty history"));1658}16591660 author =fmt_ident(state->author_name, state->author_email,1661 state->ignore_date ? NULL : state->author_date,1662 IDENT_STRICT);16631664if(state->committer_date_is_author_date)1665setenv("GIT_COMMITTER_DATE",1666 state->ignore_date ?"": state->author_date,1);16671668if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1669 author, state->sign_commit))1670die(_("failed to write commit object"));16711672 reflog_msg =getenv("GIT_REFLOG_ACTION");1673if(!reflog_msg)1674 reflog_msg ="am";16751676strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1677 state->msg);16781679update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);16801681if(state->rebasing) {1682FILE*fp =xfopen(am_path(state,"rewritten"),"a");16831684assert(!is_null_sha1(state->orig_commit));1685fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1686fprintf(fp,"%s\n",sha1_to_hex(commit));1687fclose(fp);1688}16891690run_hook_le(NULL,"post-applypatch", NULL);16911692strbuf_release(&sb);1693}16941695/**1696 * Validates the am_state for resuming -- the "msg" and authorship fields must1697 * be filled up.1698 */1699static voidvalidate_resume_state(const struct am_state *state)1700{1701if(!state->msg)1702die(_("cannot resume:%sdoes not exist."),1703am_path(state,"final-commit"));17041705if(!state->author_name || !state->author_email || !state->author_date)1706die(_("cannot resume:%sdoes not exist."),1707am_path(state,"author-script"));1708}17091710/**1711 * Interactively prompt the user on whether the current patch should be1712 * applied.1713 *1714 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1715 * skip it.1716 */1717static intdo_interactive(struct am_state *state)1718{1719assert(state->msg);17201721if(!isatty(0))1722die(_("cannot be interactive without stdin connected to a terminal."));17231724for(;;) {1725const char*reply;17261727puts(_("Commit Body is:"));1728puts("--------------------------");1729printf("%s", state->msg);1730puts("--------------------------");17311732/*1733 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1734 * in your translation. The program will only accept English1735 * input at this point.1736 */1737 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17381739if(!reply) {1740continue;1741}else if(*reply =='y'|| *reply =='Y') {1742return0;1743}else if(*reply =='a'|| *reply =='A') {1744 state->interactive =0;1745return0;1746}else if(*reply =='n'|| *reply =='N') {1747return1;1748}else if(*reply =='e'|| *reply =='E') {1749struct strbuf msg = STRBUF_INIT;17501751if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1752free(state->msg);1753 state->msg =strbuf_detach(&msg, &state->msg_len);1754}1755strbuf_release(&msg);1756}else if(*reply =='v'|| *reply =='V') {1757const char*pager =git_pager(1);1758struct child_process cp = CHILD_PROCESS_INIT;17591760if(!pager)1761 pager ="cat";1762argv_array_push(&cp.args, pager);1763argv_array_push(&cp.args,am_path(state,"patch"));1764run_command(&cp);1765}1766}1767}17681769/**1770 * Applies all queued mail.1771 *1772 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1773 * well as the state directory's "patch" file is used as-is for applying the1774 * patch and committing it.1775 */1776static voidam_run(struct am_state *state,int resume)1777{1778const char*argv_gc_auto[] = {"gc","--auto", NULL};1779struct strbuf sb = STRBUF_INIT;17801781unlink(am_path(state,"dirtyindex"));17821783refresh_and_write_cache();17841785if(index_has_changes(&sb)) {1786write_file(am_path(state,"dirtyindex"),1,"t");1787die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1788}17891790strbuf_release(&sb);17911792while(state->cur <= state->last) {1793const char*mail =am_path(state,msgnum(state));1794int apply_status;17951796if(!file_exists(mail))1797goto next;17981799if(resume) {1800validate_resume_state(state);1801}else{1802int skip;18031804if(state->rebasing)1805 skip =parse_mail_rebase(state, mail);1806else1807 skip =parse_mail(state, mail);18081809if(skip)1810goto next;/* mail should be skipped */18111812write_author_script(state);1813write_commit_msg(state);1814}18151816if(state->interactive &&do_interactive(state))1817goto next;18181819if(run_applypatch_msg_hook(state))1820exit(1);18211822say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18231824 apply_status =run_apply(state, NULL);18251826if(apply_status && state->threeway) {1827struct strbuf sb = STRBUF_INIT;18281829strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1830 apply_status =fall_back_threeway(state, sb.buf);1831strbuf_release(&sb);18321833/*1834 * Applying the patch to an earlier tree and merging1835 * the result may have produced the same tree as ours.1836 */1837if(!apply_status && !index_has_changes(NULL)) {1838say(state, stdout,_("No changes -- Patch already applied."));1839goto next;1840}1841}18421843if(apply_status) {1844int advice_amworkdir =1;18451846printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1847linelen(state->msg), state->msg);18481849git_config_get_bool("advice.amworkdir", &advice_amworkdir);18501851if(advice_amworkdir)1852printf_ln(_("The copy of the patch that failed is found in:%s"),1853am_path(state,"patch"));18541855die_user_resolve(state);1856}18571858do_commit(state);18591860next:1861am_next(state);18621863if(resume)1864am_load(state);1865 resume =0;1866}18671868if(!is_empty_file(am_path(state,"rewritten"))) {1869assert(state->rebasing);1870copy_notes_for_rebase(state);1871run_post_rewrite_hook(state);1872}18731874/*1875 * In rebasing mode, it's up to the caller to take care of1876 * housekeeping.1877 */1878if(!state->rebasing) {1879am_destroy(state);1880run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1881}1882}18831884/**1885 * Resume the current am session after patch application failure. The user did1886 * all the hard work, and we do not have to do any patch application. Just1887 * trust and commit what the user has in the index and working tree.1888 */1889static voidam_resolve(struct am_state *state)1890{1891validate_resume_state(state);18921893say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18941895if(!index_has_changes(NULL)) {1896printf_ln(_("No changes - did you forget to use 'git add'?\n"1897"If there is nothing left to stage, chances are that something else\n"1898"already introduced the same changes; you might want to skip this patch."));1899die_user_resolve(state);1900}19011902if(unmerged_cache()) {1903printf_ln(_("You still have unmerged paths in your index.\n"1904"Did you forget to use 'git add'?"));1905die_user_resolve(state);1906}19071908if(state->interactive) {1909write_index_patch(state);1910if(do_interactive(state))1911goto next;1912}19131914rerere(0);19151916do_commit(state);19171918next:1919am_next(state);1920am_load(state);1921am_run(state,0);1922}19231924/**1925 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1926 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1927 * failure.1928 */1929static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1930{1931struct lock_file *lock_file;1932struct unpack_trees_options opts;1933struct tree_desc t[2];19341935if(parse_tree(head) ||parse_tree(remote))1936return-1;19371938 lock_file =xcalloc(1,sizeof(struct lock_file));1939hold_locked_index(lock_file,1);19401941refresh_cache(REFRESH_QUIET);19421943memset(&opts,0,sizeof(opts));1944 opts.head_idx =1;1945 opts.src_index = &the_index;1946 opts.dst_index = &the_index;1947 opts.update =1;1948 opts.merge =1;1949 opts.reset = reset;1950 opts.fn = twoway_merge;1951init_tree_desc(&t[0], head->buffer, head->size);1952init_tree_desc(&t[1], remote->buffer, remote->size);19531954if(unpack_trees(2, t, &opts)) {1955rollback_lock_file(lock_file);1956return-1;1957}19581959if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1960die(_("unable to write new index file"));19611962return0;1963}19641965/**1966 * Clean the index without touching entries that are not modified between1967 * `head` and `remote`.1968 */1969static intclean_index(const unsigned char*head,const unsigned char*remote)1970{1971struct lock_file *lock_file;1972struct tree *head_tree, *remote_tree, *index_tree;1973unsigned char index[GIT_SHA1_RAWSZ];1974struct pathspec pathspec;19751976 head_tree =parse_tree_indirect(head);1977if(!head_tree)1978returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));19791980 remote_tree =parse_tree_indirect(remote);1981if(!remote_tree)1982returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));19831984read_cache_unmerged();19851986if(fast_forward_to(head_tree, head_tree,1))1987return-1;19881989if(write_cache_as_tree(index,0, NULL))1990return-1;19911992 index_tree =parse_tree_indirect(index);1993if(!index_tree)1994returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));19951996if(fast_forward_to(index_tree, remote_tree,0))1997return-1;19981999memset(&pathspec,0,sizeof(pathspec));20002001 lock_file =xcalloc(1,sizeof(struct lock_file));2002hold_locked_index(lock_file,1);20032004if(read_tree(remote_tree,0, &pathspec)) {2005rollback_lock_file(lock_file);2006return-1;2007}20082009if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))2010die(_("unable to write new index file"));20112012remove_branch_state();20132014return0;2015}20162017/**2018 * Resets rerere's merge resolution metadata.2019 */2020static voidam_rerere_clear(void)2021{2022struct string_list merge_rr = STRING_LIST_INIT_DUP;2023int fd =setup_rerere(&merge_rr,0);20242025if(fd <0)2026return;20272028rerere_clear(&merge_rr);2029string_list_clear(&merge_rr,1);2030}20312032/**2033 * Resume the current am session by skipping the current patch.2034 */2035static voidam_skip(struct am_state *state)2036{2037unsigned char head[GIT_SHA1_RAWSZ];20382039am_rerere_clear();20402041if(get_sha1("HEAD", head))2042hashcpy(head, EMPTY_TREE_SHA1_BIN);20432044if(clean_index(head, head))2045die(_("failed to clean index"));20462047am_next(state);2048am_load(state);2049am_run(state,0);2050}20512052/**2053 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2054 *2055 * It is not safe to reset HEAD when:2056 * 1. git-am previously failed because the index was dirty.2057 * 2. HEAD has moved since git-am previously failed.2058 */2059static intsafe_to_abort(const struct am_state *state)2060{2061struct strbuf sb = STRBUF_INIT;2062unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];20632064if(file_exists(am_path(state,"dirtyindex")))2065return0;20662067if(read_state_file(&sb, state,"abort-safety",1) >0) {2068if(get_sha1_hex(sb.buf, abort_safety))2069die(_("could not parse%s"),am_path(state,"abort_safety"));2070}else2071hashclr(abort_safety);20722073if(get_sha1("HEAD", head))2074hashclr(head);20752076if(!hashcmp(head, abort_safety))2077return1;20782079error(_("You seem to have moved HEAD since the last 'am' failure.\n"2080"Not rewinding to ORIG_HEAD"));20812082return0;2083}20842085/**2086 * Aborts the current am session if it is safe to do so.2087 */2088static voidam_abort(struct am_state *state)2089{2090unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2091int has_curr_head, has_orig_head;2092char*curr_branch;20932094if(!safe_to_abort(state)) {2095am_destroy(state);2096return;2097}20982099am_rerere_clear();21002101 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2102 has_curr_head = !is_null_sha1(curr_head);2103if(!has_curr_head)2104hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);21052106 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2107if(!has_orig_head)2108hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);21092110clean_index(curr_head, orig_head);21112112if(has_orig_head)2113update_ref("am --abort","HEAD", orig_head,2114 has_curr_head ? curr_head : NULL,0,2115 UPDATE_REFS_DIE_ON_ERR);2116else if(curr_branch)2117delete_ref(curr_branch, NULL, REF_NODEREF);21182119free(curr_branch);2120am_destroy(state);2121}21222123/**2124 * parse_options() callback that validates and sets opt->value to the2125 * PATCH_FORMAT_* enum value corresponding to `arg`.2126 */2127static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2128{2129int*opt_value = opt->value;21302131if(!strcmp(arg,"mbox"))2132*opt_value = PATCH_FORMAT_MBOX;2133else if(!strcmp(arg,"stgit"))2134*opt_value = PATCH_FORMAT_STGIT;2135else if(!strcmp(arg,"stgit-series"))2136*opt_value = PATCH_FORMAT_STGIT_SERIES;2137else if(!strcmp(arg,"hg"))2138*opt_value = PATCH_FORMAT_HG;2139else2140returnerror(_("Invalid value for --patch-format:%s"), arg);2141return0;2142}21432144enum resume_mode {2145 RESUME_FALSE =0,2146 RESUME_APPLY,2147 RESUME_RESOLVED,2148 RESUME_SKIP,2149 RESUME_ABORT2150};21512152intcmd_am(int argc,const char**argv,const char*prefix)2153{2154struct am_state state;2155int binary = -1;2156int keep_cr = -1;2157int patch_format = PATCH_FORMAT_UNKNOWN;2158enum resume_mode resume = RESUME_FALSE;2159int in_progress;21602161const char*const usage[] = {2162N_("git am [options] [(<mbox>|<Maildir>)...]"),2163N_("git am [options] (--continue | --skip | --abort)"),2164 NULL2165};21662167struct option options[] = {2168OPT_BOOL('i',"interactive", &state.interactive,2169N_("run interactively")),2170OPT_HIDDEN_BOOL('b',"binary", &binary,2171N_("(historical option -- no-op")),2172OPT_BOOL('3',"3way", &state.threeway,2173N_("allow fall back on 3way merging if needed")),2174OPT__QUIET(&state.quiet,N_("be quiet")),2175OPT_SET_INT('s',"signoff", &state.signoff,2176N_("add a Signed-off-by line to the commit message"),2177 SIGNOFF_EXPLICIT),2178OPT_BOOL('u',"utf8", &state.utf8,2179N_("recode into utf8 (default)")),2180OPT_SET_INT('k',"keep", &state.keep,2181N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2182OPT_SET_INT(0,"keep-non-patch", &state.keep,2183N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2184OPT_BOOL('m',"message-id", &state.message_id,2185N_("pass -m flag to git-mailinfo")),2186{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2187N_("pass --keep-cr flag to git-mailsplit for mbox format"),2188 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2189{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2190N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2191 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2192OPT_BOOL('c',"scissors", &state.scissors,2193N_("strip everything before a scissors line")),2194OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2195N_("pass it through git-apply"),21960),2197OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2198N_("pass it through git-apply"),2199 PARSE_OPT_NOARG),2200OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2201N_("pass it through git-apply"),2202 PARSE_OPT_NOARG),2203OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2204N_("pass it through git-apply"),22050),2206OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2207N_("pass it through git-apply"),22080),2209OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2210N_("pass it through git-apply"),22110),2212OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2213N_("pass it through git-apply"),22140),2215OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2216N_("pass it through git-apply"),22170),2218OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2219N_("format the patch(es) are in"),2220 parse_opt_patchformat),2221OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2222N_("pass it through git-apply"),2223 PARSE_OPT_NOARG),2224OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2225N_("override error message when patch failure occurs")),2226OPT_CMDMODE(0,"continue", &resume,2227N_("continue applying patches after resolving a conflict"),2228 RESUME_RESOLVED),2229OPT_CMDMODE('r',"resolved", &resume,2230N_("synonyms for --continue"),2231 RESUME_RESOLVED),2232OPT_CMDMODE(0,"skip", &resume,2233N_("skip the current patch"),2234 RESUME_SKIP),2235OPT_CMDMODE(0,"abort", &resume,2236N_("restore the original branch and abort the patching operation."),2237 RESUME_ABORT),2238OPT_BOOL(0,"committer-date-is-author-date",2239&state.committer_date_is_author_date,2240N_("lie about committer date")),2241OPT_BOOL(0,"ignore-date", &state.ignore_date,2242N_("use current timestamp for author date")),2243OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2244{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2245N_("GPG-sign commits"),2246 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2247OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2248N_("(internal use for git-rebase)")),2249OPT_END()2250};22512252git_config(git_default_config, NULL);22532254am_state_init(&state,git_path("rebase-apply"));22552256 in_progress =am_in_progress(&state);2257if(in_progress)2258am_load(&state);22592260 argc =parse_options(argc, argv, prefix, options, usage,0);22612262if(binary >=0)2263fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2264"it will be removed. Please do not use it anymore."));22652266/* Ensure a valid committer ident can be constructed */2267git_committer_info(IDENT_STRICT);22682269if(read_index_preload(&the_index, NULL) <0)2270die(_("failed to read the index"));22712272if(in_progress) {2273/*2274 * Catch user error to feed us patches when there is a session2275 * in progress:2276 *2277 * 1. mbox path(s) are provided on the command-line.2278 * 2. stdin is not a tty: the user is trying to feed us a patch2279 * from standard input. This is somewhat unreliable -- stdin2280 * could be /dev/null for example and the caller did not2281 * intend to feed us a patch but wanted to continue2282 * unattended.2283 */2284if(argc || (resume == RESUME_FALSE && !isatty(0)))2285die(_("previous rebase directory%sstill exists but mbox given."),2286 state.dir);22872288if(resume == RESUME_FALSE)2289 resume = RESUME_APPLY;22902291if(state.signoff == SIGNOFF_EXPLICIT)2292am_append_signoff(&state);2293}else{2294struct argv_array paths = ARGV_ARRAY_INIT;2295int i;22962297/*2298 * Handle stray state directory in the independent-run case. In2299 * the --rebasing case, it is up to the caller to take care of2300 * stray directories.2301 */2302if(file_exists(state.dir) && !state.rebasing) {2303if(resume == RESUME_ABORT) {2304am_destroy(&state);2305am_state_release(&state);2306return0;2307}23082309die(_("Stray%sdirectory found.\n"2310"Use\"git am --abort\"to remove it."),2311 state.dir);2312}23132314if(resume)2315die(_("Resolve operation not in progress, we are not resuming."));23162317for(i =0; i < argc; i++) {2318if(is_absolute_path(argv[i]) || !prefix)2319argv_array_push(&paths, argv[i]);2320else2321argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2322}23232324am_setup(&state, patch_format, paths.argv, keep_cr);23252326argv_array_clear(&paths);2327}23282329switch(resume) {2330case RESUME_FALSE:2331am_run(&state,0);2332break;2333case RESUME_APPLY:2334am_run(&state,1);2335break;2336case RESUME_RESOLVED:2337am_resolve(&state);2338break;2339case RESUME_SKIP:2340am_skip(&state);2341break;2342case RESUME_ABORT:2343am_abort(&state);2344break;2345default:2346die("BUG: invalid resume value");2347}23482349am_state_release(&state);23502351return0;2352}