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 101struct am_state { 102/* state directory path */ 103char*dir; 104 105/* current and last patch numbers, 1-indexed */ 106int cur; 107int last; 108 109/* commit metadata and message */ 110char*author_name; 111char*author_email; 112char*author_date; 113char*msg; 114size_t msg_len; 115 116/* when --rebasing, records the original commit the patch came from */ 117unsigned char orig_commit[GIT_SHA1_RAWSZ]; 118 119/* number of digits in patch filename */ 120int prec; 121 122/* various operating modes and command line options */ 123int interactive; 124int threeway; 125int quiet; 126int signoff; 127int utf8; 128int keep;/* enum keep_type */ 129int message_id; 130int scissors;/* enum scissors_type */ 131struct argv_array git_apply_opts; 132const char*resolvemsg; 133int committer_date_is_author_date; 134int ignore_date; 135int allow_rerere_autoupdate; 136const char*sign_commit; 137int rebasing; 138}; 139 140/** 141 * Initializes am_state with the default values. The state directory is set to 142 * dir. 143 */ 144static voidam_state_init(struct am_state *state,const char*dir) 145{ 146int gpgsign; 147 148memset(state,0,sizeof(*state)); 149 150assert(dir); 151 state->dir =xstrdup(dir); 152 153 state->prec =4; 154 155git_config_get_bool("am.threeway", &state->threeway); 156 157 state->utf8 =1; 158 159git_config_get_bool("am.messageid", &state->message_id); 160 161 state->scissors = SCISSORS_UNSET; 162 163argv_array_init(&state->git_apply_opts); 164 165if(!git_config_get_bool("commit.gpgsign", &gpgsign)) 166 state->sign_commit = gpgsign ?"": NULL; 167} 168 169/** 170 * Releases memory allocated by an am_state. 171 */ 172static voidam_state_release(struct am_state *state) 173{ 174free(state->dir); 175free(state->author_name); 176free(state->author_email); 177free(state->author_date); 178free(state->msg); 179argv_array_clear(&state->git_apply_opts); 180} 181 182/** 183 * Returns path relative to the am_state directory. 184 */ 185staticinlineconst char*am_path(const struct am_state *state,const char*path) 186{ 187returnmkpath("%s/%s", state->dir, path); 188} 189 190/** 191 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 192 * at the end. 193 */ 194static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 195{ 196va_list ap; 197 198va_start(ap, fmt); 199if(!state->quiet) { 200vfprintf(fp, fmt, ap); 201putc('\n', fp); 202} 203va_end(ap); 204} 205 206/** 207 * Returns 1 if there is an am session in progress, 0 otherwise. 208 */ 209static intam_in_progress(const struct am_state *state) 210{ 211struct stat st; 212 213if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 214return0; 215if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 216return0; 217if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 218return0; 219return1; 220} 221 222/** 223 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 224 * number of bytes read on success, -1 if the file does not exist. If `trim` is 225 * set, trailing whitespace will be removed. 226 */ 227static intread_state_file(struct strbuf *sb,const struct am_state *state, 228const char*file,int trim) 229{ 230strbuf_reset(sb); 231 232if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 233if(trim) 234strbuf_trim(sb); 235 236return sb->len; 237} 238 239if(errno == ENOENT) 240return-1; 241 242die_errno(_("could not read '%s'"),am_path(state, file)); 243} 244 245/** 246 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 247 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 248 * match `key`. Returns NULL on failure. 249 * 250 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 251 * the author-script. 252 */ 253static char*read_shell_var(FILE*fp,const char*key) 254{ 255struct strbuf sb = STRBUF_INIT; 256const char*str; 257 258if(strbuf_getline(&sb, fp,'\n')) 259goto fail; 260 261if(!skip_prefix(sb.buf, key, &str)) 262goto fail; 263 264if(!skip_prefix(str,"=", &str)) 265goto fail; 266 267strbuf_remove(&sb,0, str - sb.buf); 268 269 str =sq_dequote(sb.buf); 270if(!str) 271goto fail; 272 273returnstrbuf_detach(&sb, NULL); 274 275fail: 276strbuf_release(&sb); 277return NULL; 278} 279 280/** 281 * Reads and parses the state directory's "author-script" file, and sets 282 * state->author_name, state->author_email and state->author_date accordingly. 283 * Returns 0 on success, -1 if the file could not be parsed. 284 * 285 * The author script is of the format: 286 * 287 * GIT_AUTHOR_NAME='$author_name' 288 * GIT_AUTHOR_EMAIL='$author_email' 289 * GIT_AUTHOR_DATE='$author_date' 290 * 291 * where $author_name, $author_email and $author_date are quoted. We are strict 292 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 293 * script, and thus if the file differs from what this function expects, it is 294 * better to bail out than to do something that the user does not expect. 295 */ 296static intread_author_script(struct am_state *state) 297{ 298const char*filename =am_path(state,"author-script"); 299FILE*fp; 300 301assert(!state->author_name); 302assert(!state->author_email); 303assert(!state->author_date); 304 305 fp =fopen(filename,"r"); 306if(!fp) { 307if(errno == ENOENT) 308return0; 309die_errno(_("could not open '%s' for reading"), filename); 310} 311 312 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 313if(!state->author_name) { 314fclose(fp); 315return-1; 316} 317 318 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 319if(!state->author_email) { 320fclose(fp); 321return-1; 322} 323 324 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 325if(!state->author_date) { 326fclose(fp); 327return-1; 328} 329 330if(fgetc(fp) != EOF) { 331fclose(fp); 332return-1; 333} 334 335fclose(fp); 336return0; 337} 338 339/** 340 * Saves state->author_name, state->author_email and state->author_date in the 341 * state directory's "author-script" file. 342 */ 343static voidwrite_author_script(const struct am_state *state) 344{ 345struct strbuf sb = STRBUF_INIT; 346 347strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 348sq_quote_buf(&sb, state->author_name); 349strbuf_addch(&sb,'\n'); 350 351strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 352sq_quote_buf(&sb, state->author_email); 353strbuf_addch(&sb,'\n'); 354 355strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 356sq_quote_buf(&sb, state->author_date); 357strbuf_addch(&sb,'\n'); 358 359write_file(am_path(state,"author-script"),1,"%s", sb.buf); 360 361strbuf_release(&sb); 362} 363 364/** 365 * Reads the commit message from the state directory's "final-commit" file, 366 * setting state->msg to its contents and state->msg_len to the length of its 367 * contents in bytes. 368 * 369 * Returns 0 on success, -1 if the file does not exist. 370 */ 371static intread_commit_msg(struct am_state *state) 372{ 373struct strbuf sb = STRBUF_INIT; 374 375assert(!state->msg); 376 377if(read_state_file(&sb, state,"final-commit",0) <0) { 378strbuf_release(&sb); 379return-1; 380} 381 382 state->msg =strbuf_detach(&sb, &state->msg_len); 383return0; 384} 385 386/** 387 * Saves state->msg in the state directory's "final-commit" file. 388 */ 389static voidwrite_commit_msg(const struct am_state *state) 390{ 391int fd; 392const char*filename =am_path(state,"final-commit"); 393 394 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 395if(write_in_full(fd, state->msg, state->msg_len) <0) 396die_errno(_("could not write to%s"), filename); 397close(fd); 398} 399 400/** 401 * Loads state from disk. 402 */ 403static voidam_load(struct am_state *state) 404{ 405struct strbuf sb = STRBUF_INIT; 406 407if(read_state_file(&sb, state,"next",1) <0) 408die("BUG: state file 'next' does not exist"); 409 state->cur =strtol(sb.buf, NULL,10); 410 411if(read_state_file(&sb, state,"last",1) <0) 412die("BUG: state file 'last' does not exist"); 413 state->last =strtol(sb.buf, NULL,10); 414 415if(read_author_script(state) <0) 416die(_("could not parse author script")); 417 418read_commit_msg(state); 419 420if(read_state_file(&sb, state,"original-commit",1) <0) 421hashclr(state->orig_commit); 422else if(get_sha1_hex(sb.buf, state->orig_commit) <0) 423die(_("could not parse%s"),am_path(state,"original-commit")); 424 425read_state_file(&sb, state,"threeway",1); 426 state->threeway = !strcmp(sb.buf,"t"); 427 428read_state_file(&sb, state,"quiet",1); 429 state->quiet = !strcmp(sb.buf,"t"); 430 431read_state_file(&sb, state,"sign",1); 432 state->signoff = !strcmp(sb.buf,"t"); 433 434read_state_file(&sb, state,"utf8",1); 435 state->utf8 = !strcmp(sb.buf,"t"); 436 437read_state_file(&sb, state,"keep",1); 438if(!strcmp(sb.buf,"t")) 439 state->keep = KEEP_TRUE; 440else if(!strcmp(sb.buf,"b")) 441 state->keep = KEEP_NON_PATCH; 442else 443 state->keep = KEEP_FALSE; 444 445read_state_file(&sb, state,"messageid",1); 446 state->message_id = !strcmp(sb.buf,"t"); 447 448read_state_file(&sb, state,"scissors",1); 449if(!strcmp(sb.buf,"t")) 450 state->scissors = SCISSORS_TRUE; 451else if(!strcmp(sb.buf,"f")) 452 state->scissors = SCISSORS_FALSE; 453else 454 state->scissors = SCISSORS_UNSET; 455 456read_state_file(&sb, state,"apply-opt",1); 457argv_array_clear(&state->git_apply_opts); 458if(sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) <0) 459die(_("could not parse%s"),am_path(state,"apply-opt")); 460 461 state->rebasing = !!file_exists(am_path(state,"rebasing")); 462 463strbuf_release(&sb); 464} 465 466/** 467 * Removes the am_state directory, forcefully terminating the current am 468 * session. 469 */ 470static voidam_destroy(const struct am_state *state) 471{ 472struct strbuf sb = STRBUF_INIT; 473 474strbuf_addstr(&sb, state->dir); 475remove_dir_recursively(&sb,0); 476strbuf_release(&sb); 477} 478 479/** 480 * Runs applypatch-msg hook. Returns its exit code. 481 */ 482static intrun_applypatch_msg_hook(struct am_state *state) 483{ 484int ret; 485 486assert(state->msg); 487 ret =run_hook_le(NULL,"applypatch-msg",am_path(state,"final-commit"), NULL); 488 489if(!ret) { 490free(state->msg); 491 state->msg = NULL; 492if(read_commit_msg(state) <0) 493die(_("'%s' was deleted by the applypatch-msg hook"), 494am_path(state,"final-commit")); 495} 496 497return ret; 498} 499 500/** 501 * Runs post-rewrite hook. Returns it exit code. 502 */ 503static intrun_post_rewrite_hook(const struct am_state *state) 504{ 505struct child_process cp = CHILD_PROCESS_INIT; 506const char*hook =find_hook("post-rewrite"); 507int ret; 508 509if(!hook) 510return0; 511 512argv_array_push(&cp.args, hook); 513argv_array_push(&cp.args,"rebase"); 514 515 cp.in =xopen(am_path(state,"rewritten"), O_RDONLY); 516 cp.stdout_to_stderr =1; 517 518 ret =run_command(&cp); 519 520close(cp.in); 521return ret; 522} 523 524/** 525 * Reads the state directory's "rewritten" file, and copies notes from the old 526 * commits listed in the file to their rewritten commits. 527 * 528 * Returns 0 on success, -1 on failure. 529 */ 530static intcopy_notes_for_rebase(const struct am_state *state) 531{ 532struct notes_rewrite_cfg *c; 533struct strbuf sb = STRBUF_INIT; 534const char*invalid_line =_("Malformed input line: '%s'."); 535const char*msg ="Notes added by 'git rebase'"; 536FILE*fp; 537int ret =0; 538 539assert(state->rebasing); 540 541 c =init_copy_notes_for_rewrite("rebase"); 542if(!c) 543return0; 544 545 fp =xfopen(am_path(state,"rewritten"),"r"); 546 547while(!strbuf_getline(&sb, fp,'\n')) { 548unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; 549 550if(sb.len != GIT_SHA1_HEXSZ *2+1) { 551 ret =error(invalid_line, sb.buf); 552goto finish; 553} 554 555if(get_sha1_hex(sb.buf, from_obj)) { 556 ret =error(invalid_line, sb.buf); 557goto finish; 558} 559 560if(sb.buf[GIT_SHA1_HEXSZ] !=' ') { 561 ret =error(invalid_line, sb.buf); 562goto finish; 563} 564 565if(get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ +1, to_obj)) { 566 ret =error(invalid_line, sb.buf); 567goto finish; 568} 569 570if(copy_note_for_rewrite(c, from_obj, to_obj)) 571 ret =error(_("Failed to copy notes from '%s' to '%s'"), 572sha1_to_hex(from_obj),sha1_to_hex(to_obj)); 573} 574 575finish: 576finish_copy_notes_for_rewrite(c, msg); 577fclose(fp); 578strbuf_release(&sb); 579return ret; 580} 581 582/** 583 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 584 * non-indented lines and checking if they look like they begin with valid 585 * header field names. 586 * 587 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 588 */ 589static intis_mail(FILE*fp) 590{ 591const char*header_regex ="^[!-9;-~]+:"; 592struct strbuf sb = STRBUF_INIT; 593 regex_t regex; 594int ret =1; 595 596if(fseek(fp,0L, SEEK_SET)) 597die_errno(_("fseek failed")); 598 599if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 600die("invalid pattern:%s", header_regex); 601 602while(!strbuf_getline_crlf(&sb, fp)) { 603if(!sb.len) 604break;/* End of header */ 605 606/* Ignore indented folded lines */ 607if(*sb.buf =='\t'|| *sb.buf ==' ') 608continue; 609 610/* It's a header if it matches header_regex */ 611if(regexec(®ex, sb.buf,0, NULL,0)) { 612 ret =0; 613goto done; 614} 615} 616 617done: 618regfree(®ex); 619strbuf_release(&sb); 620return ret; 621} 622 623/** 624 * Attempts to detect the patch_format of the patches contained in `paths`, 625 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 626 * detection fails. 627 */ 628static intdetect_patch_format(const char**paths) 629{ 630enum patch_format ret = PATCH_FORMAT_UNKNOWN; 631struct strbuf l1 = STRBUF_INIT; 632struct strbuf l2 = STRBUF_INIT; 633struct strbuf l3 = STRBUF_INIT; 634FILE*fp; 635 636/* 637 * We default to mbox format if input is from stdin and for directories 638 */ 639if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 640return PATCH_FORMAT_MBOX; 641 642/* 643 * Otherwise, check the first few lines of the first patch, starting 644 * from the first non-blank line, to try to detect its format. 645 */ 646 647 fp =xfopen(*paths,"r"); 648 649while(!strbuf_getline_crlf(&l1, fp)) { 650if(l1.len) 651break; 652} 653 654if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 655 ret = PATCH_FORMAT_MBOX; 656goto done; 657} 658 659if(starts_with(l1.buf,"# This series applies on GIT commit")) { 660 ret = PATCH_FORMAT_STGIT_SERIES; 661goto done; 662} 663 664if(!strcmp(l1.buf,"# HG changeset patch")) { 665 ret = PATCH_FORMAT_HG; 666goto done; 667} 668 669strbuf_reset(&l2); 670strbuf_getline_crlf(&l2, fp); 671strbuf_reset(&l3); 672strbuf_getline_crlf(&l3, fp); 673 674/* 675 * If the second line is empty and the third is a From, Author or Date 676 * entry, this is likely an StGit patch. 677 */ 678if(l1.len && !l2.len && 679(starts_with(l3.buf,"From:") || 680starts_with(l3.buf,"Author:") || 681starts_with(l3.buf,"Date:"))) { 682 ret = PATCH_FORMAT_STGIT; 683goto done; 684} 685 686if(l1.len &&is_mail(fp)) { 687 ret = PATCH_FORMAT_MBOX; 688goto done; 689} 690 691done: 692fclose(fp); 693strbuf_release(&l1); 694return ret; 695} 696 697/** 698 * Splits out individual email patches from `paths`, where each path is either 699 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 700 */ 701static intsplit_mail_mbox(struct am_state *state,const char**paths,int keep_cr) 702{ 703struct child_process cp = CHILD_PROCESS_INIT; 704struct strbuf last = STRBUF_INIT; 705 706 cp.git_cmd =1; 707argv_array_push(&cp.args,"mailsplit"); 708argv_array_pushf(&cp.args,"-d%d", state->prec); 709argv_array_pushf(&cp.args,"-o%s", state->dir); 710argv_array_push(&cp.args,"-b"); 711if(keep_cr) 712argv_array_push(&cp.args,"--keep-cr"); 713argv_array_push(&cp.args,"--"); 714argv_array_pushv(&cp.args, paths); 715 716if(capture_command(&cp, &last,8)) 717return-1; 718 719 state->cur =1; 720 state->last =strtol(last.buf, NULL,10); 721 722return0; 723} 724 725/** 726 * Callback signature for split_mail_conv(). The foreign patch should be 727 * read from `in`, and the converted patch (in RFC2822 mail format) should be 728 * written to `out`. Return 0 on success, or -1 on failure. 729 */ 730typedefint(*mail_conv_fn)(FILE*out,FILE*in,int keep_cr); 731 732/** 733 * Calls `fn` for each file in `paths` to convert the foreign patch to the 734 * RFC2822 mail format suitable for parsing with git-mailinfo. 735 * 736 * Returns 0 on success, -1 on failure. 737 */ 738static intsplit_mail_conv(mail_conv_fn fn,struct am_state *state, 739const char**paths,int keep_cr) 740{ 741static const char*stdin_only[] = {"-", NULL}; 742int i; 743 744if(!*paths) 745 paths = stdin_only; 746 747for(i =0; *paths; paths++, i++) { 748FILE*in, *out; 749const char*mail; 750int ret; 751 752if(!strcmp(*paths,"-")) 753 in = stdin; 754else 755 in =fopen(*paths,"r"); 756 757if(!in) 758returnerror(_("could not open '%s' for reading:%s"), 759*paths,strerror(errno)); 760 761 mail =mkpath("%s/%0*d", state->dir, state->prec, i +1); 762 763 out =fopen(mail,"w"); 764if(!out) 765returnerror(_("could not open '%s' for writing:%s"), 766 mail,strerror(errno)); 767 768 ret =fn(out, in, keep_cr); 769 770fclose(out); 771fclose(in); 772 773if(ret) 774returnerror(_("could not parse patch '%s'"), *paths); 775} 776 777 state->cur =1; 778 state->last = i; 779return0; 780} 781 782/** 783 * A split_mail_conv() callback that converts an StGit patch to an RFC2822 784 * message suitable for parsing with git-mailinfo. 785 */ 786static intstgit_patch_to_mail(FILE*out,FILE*in,int keep_cr) 787{ 788struct strbuf sb = STRBUF_INIT; 789int subject_printed =0; 790 791while(!strbuf_getline(&sb, in,'\n')) { 792const char*str; 793 794if(str_isspace(sb.buf)) 795continue; 796else if(skip_prefix(sb.buf,"Author:", &str)) 797fprintf(out,"From:%s\n", str); 798else if(starts_with(sb.buf,"From") ||starts_with(sb.buf,"Date")) 799fprintf(out,"%s\n", sb.buf); 800else if(!subject_printed) { 801fprintf(out,"Subject:%s\n", sb.buf); 802 subject_printed =1; 803}else{ 804fprintf(out,"\n%s\n", sb.buf); 805break; 806} 807} 808 809strbuf_reset(&sb); 810while(strbuf_fread(&sb,8192, in) >0) { 811fwrite(sb.buf,1, sb.len, out); 812strbuf_reset(&sb); 813} 814 815strbuf_release(&sb); 816return0; 817} 818 819/** 820 * This function only supports a single StGit series file in `paths`. 821 * 822 * Given an StGit series file, converts the StGit patches in the series into 823 * RFC2822 messages suitable for parsing with git-mailinfo, and queues them in 824 * the state directory. 825 * 826 * Returns 0 on success, -1 on failure. 827 */ 828static intsplit_mail_stgit_series(struct am_state *state,const char**paths, 829int keep_cr) 830{ 831const char*series_dir; 832char*series_dir_buf; 833FILE*fp; 834struct argv_array patches = ARGV_ARRAY_INIT; 835struct strbuf sb = STRBUF_INIT; 836int ret; 837 838if(!paths[0] || paths[1]) 839returnerror(_("Only one StGIT patch series can be applied at once")); 840 841 series_dir_buf =xstrdup(*paths); 842 series_dir =dirname(series_dir_buf); 843 844 fp =fopen(*paths,"r"); 845if(!fp) 846returnerror(_("could not open '%s' for reading:%s"), *paths, 847strerror(errno)); 848 849while(!strbuf_getline(&sb, fp,'\n')) { 850if(*sb.buf =='#') 851continue;/* skip comment lines */ 852 853argv_array_push(&patches,mkpath("%s/%s", series_dir, sb.buf)); 854} 855 856fclose(fp); 857strbuf_release(&sb); 858free(series_dir_buf); 859 860 ret =split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); 861 862argv_array_clear(&patches); 863return ret; 864} 865 866/** 867 * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 868 * message suitable for parsing with git-mailinfo. 869 */ 870static inthg_patch_to_mail(FILE*out,FILE*in,int keep_cr) 871{ 872struct strbuf sb = STRBUF_INIT; 873 874while(!strbuf_getline(&sb, in,'\n')) { 875const char*str; 876 877if(skip_prefix(sb.buf,"# User ", &str)) 878fprintf(out,"From:%s\n", str); 879else if(skip_prefix(sb.buf,"# Date ", &str)) { 880unsigned long timestamp; 881long tz, tz2; 882char*end; 883 884 errno =0; 885 timestamp =strtoul(str, &end,10); 886if(errno) 887returnerror(_("invalid timestamp")); 888 889if(!skip_prefix(end," ", &str)) 890returnerror(_("invalid Date line")); 891 892 errno =0; 893 tz =strtol(str, &end,10); 894if(errno) 895returnerror(_("invalid timezone offset")); 896 897if(*end) 898returnerror(_("invalid Date line")); 899 900/* 901 * mercurial's timezone is in seconds west of UTC, 902 * however git's timezone is in hours + minutes east of 903 * UTC. Convert it. 904 */ 905 tz2 =labs(tz) /3600*100+labs(tz) %3600/60; 906if(tz >0) 907 tz2 = -tz2; 908 909fprintf(out,"Date:%s\n",show_date(timestamp, tz2,DATE_MODE(RFC2822))); 910}else if(starts_with(sb.buf,"# ")) { 911continue; 912}else{ 913fprintf(out,"\n%s\n", sb.buf); 914break; 915} 916} 917 918strbuf_reset(&sb); 919while(strbuf_fread(&sb,8192, in) >0) { 920fwrite(sb.buf,1, sb.len, out); 921strbuf_reset(&sb); 922} 923 924strbuf_release(&sb); 925return0; 926} 927 928/** 929 * Splits a list of files/directories into individual email patches. Each path 930 * in `paths` must be a file/directory that is formatted according to 931 * `patch_format`. 932 * 933 * Once split out, the individual email patches will be stored in the state 934 * directory, with each patch's filename being its index, padded to state->prec 935 * digits. 936 * 937 * state->cur will be set to the index of the first mail, and state->last will 938 * be set to the index of the last mail. 939 * 940 * Set keep_cr to 0 to convert all lines ending with \r\n to end with \n, 1 941 * to disable this behavior, -1 to use the default configured setting. 942 * 943 * Returns 0 on success, -1 on failure. 944 */ 945static intsplit_mail(struct am_state *state,enum patch_format patch_format, 946const char**paths,int keep_cr) 947{ 948if(keep_cr <0) { 949 keep_cr =0; 950git_config_get_bool("am.keepcr", &keep_cr); 951} 952 953switch(patch_format) { 954case PATCH_FORMAT_MBOX: 955returnsplit_mail_mbox(state, paths, keep_cr); 956case PATCH_FORMAT_STGIT: 957returnsplit_mail_conv(stgit_patch_to_mail, state, paths, keep_cr); 958case PATCH_FORMAT_STGIT_SERIES: 959returnsplit_mail_stgit_series(state, paths, keep_cr); 960case PATCH_FORMAT_HG: 961returnsplit_mail_conv(hg_patch_to_mail, state, paths, keep_cr); 962default: 963die("BUG: invalid patch_format"); 964} 965return-1; 966} 967 968/** 969 * Setup a new am session for applying patches 970 */ 971static voidam_setup(struct am_state *state,enum patch_format patch_format, 972const char**paths,int keep_cr) 973{ 974unsigned char curr_head[GIT_SHA1_RAWSZ]; 975const char*str; 976struct strbuf sb = STRBUF_INIT; 977 978if(!patch_format) 979 patch_format =detect_patch_format(paths); 980 981if(!patch_format) { 982fprintf_ln(stderr,_("Patch format detection failed.")); 983exit(128); 984} 985 986if(mkdir(state->dir,0777) <0&& errno != EEXIST) 987die_errno(_("failed to create directory '%s'"), state->dir); 988 989if(split_mail(state, patch_format, paths, keep_cr) <0) { 990am_destroy(state); 991die(_("Failed to split patches.")); 992} 993 994if(state->rebasing) 995 state->threeway =1; 996 997write_file(am_path(state,"threeway"),1, state->threeway ?"t":"f"); 998 999write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f");10001001write_file(am_path(state,"sign"),1, state->signoff ?"t":"f");10021003write_file(am_path(state,"utf8"),1, state->utf8 ?"t":"f");10041005switch(state->keep) {1006case KEEP_FALSE:1007 str ="f";1008break;1009case KEEP_TRUE:1010 str ="t";1011break;1012case KEEP_NON_PATCH:1013 str ="b";1014break;1015default:1016die("BUG: invalid value for state->keep");1017}10181019write_file(am_path(state,"keep"),1,"%s", str);10201021write_file(am_path(state,"messageid"),1, state->message_id ?"t":"f");10221023switch(state->scissors) {1024case SCISSORS_UNSET:1025 str ="";1026break;1027case SCISSORS_FALSE:1028 str ="f";1029break;1030case SCISSORS_TRUE:1031 str ="t";1032break;1033default:1034die("BUG: invalid value for state->scissors");1035}10361037write_file(am_path(state,"scissors"),1,"%s", str);10381039sq_quote_argv(&sb, state->git_apply_opts.argv,0);1040write_file(am_path(state,"apply-opt"),1,"%s", sb.buf);10411042if(state->rebasing)1043write_file(am_path(state,"rebasing"),1,"%s","");1044else1045write_file(am_path(state,"applying"),1,"%s","");10461047if(!get_sha1("HEAD", curr_head)) {1048write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head));1049if(!state->rebasing)1050update_ref("am","ORIG_HEAD", curr_head, NULL,0,1051 UPDATE_REFS_DIE_ON_ERR);1052}else{1053write_file(am_path(state,"abort-safety"),1,"%s","");1054if(!state->rebasing)1055delete_ref("ORIG_HEAD", NULL,0);1056}10571058/*1059 * NOTE: Since the "next" and "last" files determine if an am_state1060 * session is in progress, they should be written last.1061 */10621063write_file(am_path(state,"next"),1,"%d", state->cur);10641065write_file(am_path(state,"last"),1,"%d", state->last);10661067strbuf_release(&sb);1068}10691070/**1071 * Increments the patch pointer, and cleans am_state for the application of the1072 * next patch.1073 */1074static voidam_next(struct am_state *state)1075{1076unsigned char head[GIT_SHA1_RAWSZ];10771078free(state->author_name);1079 state->author_name = NULL;10801081free(state->author_email);1082 state->author_email = NULL;10831084free(state->author_date);1085 state->author_date = NULL;10861087free(state->msg);1088 state->msg = NULL;1089 state->msg_len =0;10901091unlink(am_path(state,"author-script"));1092unlink(am_path(state,"final-commit"));10931094hashclr(state->orig_commit);1095unlink(am_path(state,"original-commit"));10961097if(!get_sha1("HEAD", head))1098write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head));1099else1100write_file(am_path(state,"abort-safety"),1,"%s","");11011102 state->cur++;1103write_file(am_path(state,"next"),1,"%d", state->cur);1104}11051106/**1107 * Returns the filename of the current patch email.1108 */1109static const char*msgnum(const struct am_state *state)1110{1111static struct strbuf sb = STRBUF_INIT;11121113strbuf_reset(&sb);1114strbuf_addf(&sb,"%0*d", state->prec, state->cur);11151116return sb.buf;1117}11181119/**1120 * Refresh and write index.1121 */1122static voidrefresh_and_write_cache(void)1123{1124struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file));11251126hold_locked_index(lock_file,1);1127refresh_cache(REFRESH_QUIET);1128if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1129die(_("unable to write index file"));1130}11311132/**1133 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn1134 * branch, returns 1 if there are entries in the index, 0 otherwise. If an1135 * strbuf is provided, the space-separated list of files that differ will be1136 * appended to it.1137 */1138static intindex_has_changes(struct strbuf *sb)1139{1140unsigned char head[GIT_SHA1_RAWSZ];1141int i;11421143if(!get_sha1_tree("HEAD", head)) {1144struct diff_options opt;11451146diff_setup(&opt);1147DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);1148if(!sb)1149DIFF_OPT_SET(&opt, QUICK);1150do_diff_cache(head, &opt);1151diffcore_std(&opt);1152for(i =0; sb && i < diff_queued_diff.nr; i++) {1153if(i)1154strbuf_addch(sb,' ');1155strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);1156}1157diff_flush(&opt);1158returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0;1159}else{1160for(i =0; sb && i < active_nr; i++) {1161if(i)1162strbuf_addch(sb,' ');1163strbuf_addstr(sb, active_cache[i]->name);1164}1165return!!active_nr;1166}1167}11681169/**1170 * Dies with a user-friendly message on how to proceed after resolving the1171 * problem. This message can be overridden with state->resolvemsg.1172 */1173static void NORETURN die_user_resolve(const struct am_state *state)1174{1175if(state->resolvemsg) {1176printf_ln("%s", state->resolvemsg);1177}else{1178const char*cmdline = state->interactive ?"git am -i":"git am";11791180printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline);1181printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline);1182printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline);1183}11841185exit(128);1186}11871188/**1189 * Parses `mail` using git-mailinfo, extracting its patch and authorship info.1190 * state->msg will be set to the patch message. state->author_name,1191 * state->author_email and state->author_date will be set to the patch author's1192 * name, email and date respectively. The patch body will be written to the1193 * state directory's "patch" file.1194 *1195 * Returns 1 if the patch should be skipped, 0 otherwise.1196 */1197static intparse_mail(struct am_state *state,const char*mail)1198{1199FILE*fp;1200struct child_process cp = CHILD_PROCESS_INIT;1201struct strbuf sb = STRBUF_INIT;1202struct strbuf msg = STRBUF_INIT;1203struct strbuf author_name = STRBUF_INIT;1204struct strbuf author_date = STRBUF_INIT;1205struct strbuf author_email = STRBUF_INIT;1206int ret =0;12071208 cp.git_cmd =1;1209 cp.in =xopen(mail, O_RDONLY,0);1210 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777);12111212argv_array_push(&cp.args,"mailinfo");1213argv_array_push(&cp.args, state->utf8 ?"-u":"-n");12141215switch(state->keep) {1216case KEEP_FALSE:1217break;1218case KEEP_TRUE:1219argv_array_push(&cp.args,"-k");1220break;1221case KEEP_NON_PATCH:1222argv_array_push(&cp.args,"-b");1223break;1224default:1225die("BUG: invalid value for state->keep");1226}12271228if(state->message_id)1229argv_array_push(&cp.args,"-m");12301231switch(state->scissors) {1232case SCISSORS_UNSET:1233break;1234case SCISSORS_FALSE:1235argv_array_push(&cp.args,"--no-scissors");1236break;1237case SCISSORS_TRUE:1238argv_array_push(&cp.args,"--scissors");1239break;1240default:1241die("BUG: invalid value for state->scissors");1242}12431244argv_array_push(&cp.args,am_path(state,"msg"));1245argv_array_push(&cp.args,am_path(state,"patch"));12461247if(run_command(&cp) <0)1248die("could not parse patch");12491250close(cp.in);1251close(cp.out);12521253/* Extract message and author information */1254 fp =xfopen(am_path(state,"info"),"r");1255while(!strbuf_getline(&sb, fp,'\n')) {1256const char*x;12571258if(skip_prefix(sb.buf,"Subject: ", &x)) {1259if(msg.len)1260strbuf_addch(&msg,'\n');1261strbuf_addstr(&msg, x);1262}else if(skip_prefix(sb.buf,"Author: ", &x))1263strbuf_addstr(&author_name, x);1264else if(skip_prefix(sb.buf,"Email: ", &x))1265strbuf_addstr(&author_email, x);1266else if(skip_prefix(sb.buf,"Date: ", &x))1267strbuf_addstr(&author_date, x);1268}1269fclose(fp);12701271/* Skip pine's internal folder data */1272if(!strcmp(author_name.buf,"Mail System Internal Data")) {1273 ret =1;1274goto finish;1275}12761277if(is_empty_file(am_path(state,"patch"))) {1278printf_ln(_("Patch is empty. Was it split wrong?"));1279die_user_resolve(state);1280}12811282strbuf_addstr(&msg,"\n\n");1283if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0)1284die_errno(_("could not read '%s'"),am_path(state,"msg"));1285stripspace(&msg,0);12861287if(state->signoff)1288append_signoff(&msg,0,0);12891290assert(!state->author_name);1291 state->author_name =strbuf_detach(&author_name, NULL);12921293assert(!state->author_email);1294 state->author_email =strbuf_detach(&author_email, NULL);12951296assert(!state->author_date);1297 state->author_date =strbuf_detach(&author_date, NULL);12981299assert(!state->msg);1300 state->msg =strbuf_detach(&msg, &state->msg_len);13011302finish:1303strbuf_release(&msg);1304strbuf_release(&author_date);1305strbuf_release(&author_email);1306strbuf_release(&author_name);1307strbuf_release(&sb);1308return ret;1309}13101311/**1312 * Sets commit_id to the commit hash where the mail was generated from.1313 * Returns 0 on success, -1 on failure.1314 */1315static intget_mail_commit_sha1(unsigned char*commit_id,const char*mail)1316{1317struct strbuf sb = STRBUF_INIT;1318FILE*fp =xfopen(mail,"r");1319const char*x;13201321if(strbuf_getline(&sb, fp,'\n'))1322return-1;13231324if(!skip_prefix(sb.buf,"From ", &x))1325return-1;13261327if(get_sha1_hex(x, commit_id) <0)1328return-1;13291330strbuf_release(&sb);1331fclose(fp);1332return0;1333}13341335/**1336 * Sets state->msg, state->author_name, state->author_email, state->author_date1337 * to the commit's respective info.1338 */1339static voidget_commit_info(struct am_state *state,struct commit *commit)1340{1341const char*buffer, *ident_line, *author_date, *msg;1342size_t ident_len;1343struct ident_split ident_split;1344struct strbuf sb = STRBUF_INIT;13451346 buffer =logmsg_reencode(commit, NULL,get_commit_output_encoding());13471348 ident_line =find_commit_header(buffer,"author", &ident_len);13491350if(split_ident_line(&ident_split, ident_line, ident_len) <0) {1351strbuf_add(&sb, ident_line, ident_len);1352die(_("invalid ident line:%s"), sb.buf);1353}13541355assert(!state->author_name);1356if(ident_split.name_begin) {1357strbuf_add(&sb, ident_split.name_begin,1358 ident_split.name_end - ident_split.name_begin);1359 state->author_name =strbuf_detach(&sb, NULL);1360}else1361 state->author_name =xstrdup("");13621363assert(!state->author_email);1364if(ident_split.mail_begin) {1365strbuf_add(&sb, ident_split.mail_begin,1366 ident_split.mail_end - ident_split.mail_begin);1367 state->author_email =strbuf_detach(&sb, NULL);1368}else1369 state->author_email =xstrdup("");13701371 author_date =show_ident_date(&ident_split,DATE_MODE(NORMAL));1372strbuf_addstr(&sb, author_date);1373assert(!state->author_date);1374 state->author_date =strbuf_detach(&sb, NULL);13751376assert(!state->msg);1377 msg =strstr(buffer,"\n\n");1378if(!msg)1379die(_("unable to parse commit%s"),sha1_to_hex(commit->object.sha1));1380 state->msg =xstrdup(msg +2);1381 state->msg_len =strlen(state->msg);1382}13831384/**1385 * Writes `commit` as a patch to the state directory's "patch" file.1386 */1387static voidwrite_commit_patch(const struct am_state *state,struct commit *commit)1388{1389struct rev_info rev_info;1390FILE*fp;13911392 fp =xfopen(am_path(state,"patch"),"w");1393init_revisions(&rev_info, NULL);1394 rev_info.diff =1;1395 rev_info.abbrev =0;1396 rev_info.disable_stdin =1;1397 rev_info.show_root_diff =1;1398 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1399 rev_info.no_commit_id =1;1400DIFF_OPT_SET(&rev_info.diffopt, BINARY);1401DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX);1402 rev_info.diffopt.use_color =0;1403 rev_info.diffopt.file = fp;1404 rev_info.diffopt.close_file =1;1405add_pending_object(&rev_info, &commit->object,"");1406diff_setup_done(&rev_info.diffopt);1407log_tree_commit(&rev_info, commit);1408}14091410/**1411 * Writes the diff of the index against HEAD as a patch to the state1412 * directory's "patch" file.1413 */1414static voidwrite_index_patch(const struct am_state *state)1415{1416struct tree *tree;1417unsigned char head[GIT_SHA1_RAWSZ];1418struct rev_info rev_info;1419FILE*fp;14201421if(!get_sha1_tree("HEAD", head))1422 tree =lookup_tree(head);1423else1424 tree =lookup_tree(EMPTY_TREE_SHA1_BIN);14251426 fp =xfopen(am_path(state,"patch"),"w");1427init_revisions(&rev_info, NULL);1428 rev_info.diff =1;1429 rev_info.disable_stdin =1;1430 rev_info.no_commit_id =1;1431 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;1432 rev_info.diffopt.use_color =0;1433 rev_info.diffopt.file = fp;1434 rev_info.diffopt.close_file =1;1435add_pending_object(&rev_info, &tree->object,"");1436diff_setup_done(&rev_info.diffopt);1437run_diff_index(&rev_info,1);1438}14391440/**1441 * Like parse_mail(), but parses the mail by looking up its commit ID1442 * directly. This is used in --rebasing mode to bypass git-mailinfo's munging1443 * of patches.1444 *1445 * state->orig_commit will be set to the original commit ID.1446 *1447 * Will always return 0 as the patch should never be skipped.1448 */1449static intparse_mail_rebase(struct am_state *state,const char*mail)1450{1451struct commit *commit;1452unsigned char commit_sha1[GIT_SHA1_RAWSZ];14531454if(get_mail_commit_sha1(commit_sha1, mail) <0)1455die(_("could not parse%s"), mail);14561457 commit =lookup_commit_or_die(commit_sha1, mail);14581459get_commit_info(state, commit);14601461write_commit_patch(state, commit);14621463hashcpy(state->orig_commit, commit_sha1);1464write_file(am_path(state,"original-commit"),1,"%s",1465sha1_to_hex(commit_sha1));14661467return0;1468}14691470/**1471 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. If1472 * `index_file` is not NULL, the patch will be applied to that index.1473 */1474static intrun_apply(const struct am_state *state,const char*index_file)1475{1476struct child_process cp = CHILD_PROCESS_INIT;14771478 cp.git_cmd =1;14791480if(index_file)1481argv_array_pushf(&cp.env_array,"GIT_INDEX_FILE=%s", index_file);14821483/*1484 * If we are allowed to fall back on 3-way merge, don't give false1485 * errors during the initial attempt.1486 */1487if(state->threeway && !index_file) {1488 cp.no_stdout =1;1489 cp.no_stderr =1;1490}14911492argv_array_push(&cp.args,"apply");14931494argv_array_pushv(&cp.args, state->git_apply_opts.argv);14951496if(index_file)1497argv_array_push(&cp.args,"--cached");1498else1499argv_array_push(&cp.args,"--index");15001501argv_array_push(&cp.args,am_path(state,"patch"));15021503if(run_command(&cp))1504return-1;15051506/* Reload index as git-apply will have modified it. */1507discard_cache();1508read_cache_from(index_file ? index_file :get_index_file());15091510return0;1511}15121513/**1514 * Builds an index that contains just the blobs needed for a 3way merge.1515 */1516static intbuild_fake_ancestor(const struct am_state *state,const char*index_file)1517{1518struct child_process cp = CHILD_PROCESS_INIT;15191520 cp.git_cmd =1;1521argv_array_push(&cp.args,"apply");1522argv_array_pushv(&cp.args, state->git_apply_opts.argv);1523argv_array_pushf(&cp.args,"--build-fake-ancestor=%s", index_file);1524argv_array_push(&cp.args,am_path(state,"patch"));15251526if(run_command(&cp))1527return-1;15281529return0;1530}15311532/**1533 * Attempt a threeway merge, using index_path as the temporary index.1534 */1535static intfall_back_threeway(const struct am_state *state,const char*index_path)1536{1537unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],1538 our_tree[GIT_SHA1_RAWSZ];1539const unsigned char*bases[1] = {orig_tree};1540struct merge_options o;1541struct commit *result;1542char*his_tree_name;15431544if(get_sha1("HEAD", our_tree) <0)1545hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);15461547if(build_fake_ancestor(state, index_path))1548returnerror("could not build fake ancestor");15491550discard_cache();1551read_cache_from(index_path);15521553if(write_index_as_tree(orig_tree, &the_index, index_path,0, NULL))1554returnerror(_("Repository lacks necessary blobs to fall back on 3-way merge."));15551556say(state, stdout,_("Using index info to reconstruct a base tree..."));15571558if(!state->quiet) {1559/*1560 * List paths that needed 3-way fallback, so that the user can1561 * review them with extra care to spot mismerges.1562 */1563struct rev_info rev_info;1564const char*diff_filter_str ="--diff-filter=AM";15651566init_revisions(&rev_info, NULL);1567 rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;1568diff_opt_parse(&rev_info.diffopt, &diff_filter_str,1);1569add_pending_sha1(&rev_info,"HEAD", our_tree,0);1570diff_setup_done(&rev_info.diffopt);1571run_diff_index(&rev_info,1);1572}15731574if(run_apply(state, index_path))1575returnerror(_("Did you hand edit your patch?\n"1576"It does not apply to blobs recorded in its index."));15771578if(write_index_as_tree(his_tree, &the_index, index_path,0, NULL))1579returnerror("could not write tree");15801581say(state, stdout,_("Falling back to patching base and 3-way merge..."));15821583discard_cache();1584read_cache();15851586/*1587 * This is not so wrong. Depending on which base we picked, orig_tree1588 * may be wildly different from ours, but his_tree has the same set of1589 * wildly different changes in parts the patch did not touch, so1590 * recursive ends up canceling them, saying that we reverted all those1591 * changes.1592 */15931594init_merge_options(&o);15951596 o.branch1 ="HEAD";1597 his_tree_name =xstrfmt("%.*s",linelen(state->msg), state->msg);1598 o.branch2 = his_tree_name;15991600if(state->quiet)1601 o.verbosity =0;16021603if(merge_recursive_generic(&o, our_tree, his_tree,1, bases, &result)) {1604rerere(state->allow_rerere_autoupdate);1605free(his_tree_name);1606returnerror(_("Failed to merge in the changes."));1607}16081609free(his_tree_name);1610return0;1611}16121613/**1614 * Commits the current index with state->msg as the commit message and1615 * state->author_name, state->author_email and state->author_date as the author1616 * information.1617 */1618static voiddo_commit(const struct am_state *state)1619{1620unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],1621 commit[GIT_SHA1_RAWSZ];1622unsigned char*ptr;1623struct commit_list *parents = NULL;1624const char*reflog_msg, *author;1625struct strbuf sb = STRBUF_INIT;16261627if(run_hook_le(NULL,"pre-applypatch", NULL))1628exit(1);16291630if(write_cache_as_tree(tree,0, NULL))1631die(_("git write-tree failed to write a tree"));16321633if(!get_sha1_commit("HEAD", parent)) {1634 ptr = parent;1635commit_list_insert(lookup_commit(parent), &parents);1636}else{1637 ptr = NULL;1638say(state, stderr,_("applying to an empty history"));1639}16401641 author =fmt_ident(state->author_name, state->author_email,1642 state->ignore_date ? NULL : state->author_date,1643 IDENT_STRICT);16441645if(state->committer_date_is_author_date)1646setenv("GIT_COMMITTER_DATE",1647 state->ignore_date ?"": state->author_date,1);16481649if(commit_tree(state->msg, state->msg_len, tree, parents, commit,1650 author, state->sign_commit))1651die(_("failed to write commit object"));16521653 reflog_msg =getenv("GIT_REFLOG_ACTION");1654if(!reflog_msg)1655 reflog_msg ="am";16561657strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg),1658 state->msg);16591660update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR);16611662if(state->rebasing) {1663FILE*fp =xfopen(am_path(state,"rewritten"),"a");16641665assert(!is_null_sha1(state->orig_commit));1666fprintf(fp,"%s",sha1_to_hex(state->orig_commit));1667fprintf(fp,"%s\n",sha1_to_hex(commit));1668fclose(fp);1669}16701671run_hook_le(NULL,"post-applypatch", NULL);16721673strbuf_release(&sb);1674}16751676/**1677 * Validates the am_state for resuming -- the "msg" and authorship fields must1678 * be filled up.1679 */1680static voidvalidate_resume_state(const struct am_state *state)1681{1682if(!state->msg)1683die(_("cannot resume:%sdoes not exist."),1684am_path(state,"final-commit"));16851686if(!state->author_name || !state->author_email || !state->author_date)1687die(_("cannot resume:%sdoes not exist."),1688am_path(state,"author-script"));1689}16901691/**1692 * Interactively prompt the user on whether the current patch should be1693 * applied.1694 *1695 * Returns 0 if the user chooses to apply the patch, 1 if the user chooses to1696 * skip it.1697 */1698static intdo_interactive(struct am_state *state)1699{1700assert(state->msg);17011702if(!isatty(0))1703die(_("cannot be interactive without stdin connected to a terminal."));17041705for(;;) {1706const char*reply;17071708puts(_("Commit Body is:"));1709puts("--------------------------");1710printf("%s", state->msg);1711puts("--------------------------");17121713/*1714 * TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]1715 * in your translation. The program will only accept English1716 * input at this point.1717 */1718 reply =git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO);17191720if(!reply) {1721continue;1722}else if(*reply =='y'|| *reply =='Y') {1723return0;1724}else if(*reply =='a'|| *reply =='A') {1725 state->interactive =0;1726return0;1727}else if(*reply =='n'|| *reply =='N') {1728return1;1729}else if(*reply =='e'|| *reply =='E') {1730struct strbuf msg = STRBUF_INIT;17311732if(!launch_editor(am_path(state,"final-commit"), &msg, NULL)) {1733free(state->msg);1734 state->msg =strbuf_detach(&msg, &state->msg_len);1735}1736strbuf_release(&msg);1737}else if(*reply =='v'|| *reply =='V') {1738const char*pager =git_pager(1);1739struct child_process cp = CHILD_PROCESS_INIT;17401741if(!pager)1742 pager ="cat";1743argv_array_push(&cp.args, pager);1744argv_array_push(&cp.args,am_path(state,"patch"));1745run_command(&cp);1746}1747}1748}17491750/**1751 * Applies all queued mail.1752 *1753 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as1754 * well as the state directory's "patch" file is used as-is for applying the1755 * patch and committing it.1756 */1757static voidam_run(struct am_state *state,int resume)1758{1759const char*argv_gc_auto[] = {"gc","--auto", NULL};1760struct strbuf sb = STRBUF_INIT;17611762unlink(am_path(state,"dirtyindex"));17631764refresh_and_write_cache();17651766if(index_has_changes(&sb)) {1767write_file(am_path(state,"dirtyindex"),1,"t");1768die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf);1769}17701771strbuf_release(&sb);17721773while(state->cur <= state->last) {1774const char*mail =am_path(state,msgnum(state));1775int apply_status;17761777if(!file_exists(mail))1778goto next;17791780if(resume) {1781validate_resume_state(state);1782 resume =0;1783}else{1784int skip;17851786if(state->rebasing)1787 skip =parse_mail_rebase(state, mail);1788else1789 skip =parse_mail(state, mail);17901791if(skip)1792goto next;/* mail should be skipped */17931794write_author_script(state);1795write_commit_msg(state);1796}17971798if(state->interactive &&do_interactive(state))1799goto next;18001801if(run_applypatch_msg_hook(state))1802exit(1);18031804say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18051806 apply_status =run_apply(state, NULL);18071808if(apply_status && state->threeway) {1809struct strbuf sb = STRBUF_INIT;18101811strbuf_addstr(&sb,am_path(state,"patch-merge-index"));1812 apply_status =fall_back_threeway(state, sb.buf);1813strbuf_release(&sb);18141815/*1816 * Applying the patch to an earlier tree and merging1817 * the result may have produced the same tree as ours.1818 */1819if(!apply_status && !index_has_changes(NULL)) {1820say(state, stdout,_("No changes -- Patch already applied."));1821goto next;1822}1823}18241825if(apply_status) {1826int advice_amworkdir =1;18271828printf_ln(_("Patch failed at%s%.*s"),msgnum(state),1829linelen(state->msg), state->msg);18301831git_config_get_bool("advice.amworkdir", &advice_amworkdir);18321833if(advice_amworkdir)1834printf_ln(_("The copy of the patch that failed is found in:%s"),1835am_path(state,"patch"));18361837die_user_resolve(state);1838}18391840do_commit(state);18411842next:1843am_next(state);1844}18451846if(!is_empty_file(am_path(state,"rewritten"))) {1847assert(state->rebasing);1848copy_notes_for_rebase(state);1849run_post_rewrite_hook(state);1850}18511852/*1853 * In rebasing mode, it's up to the caller to take care of1854 * housekeeping.1855 */1856if(!state->rebasing) {1857am_destroy(state);1858run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);1859}1860}18611862/**1863 * Resume the current am session after patch application failure. The user did1864 * all the hard work, and we do not have to do any patch application. Just1865 * trust and commit what the user has in the index and working tree.1866 */1867static voidam_resolve(struct am_state *state)1868{1869validate_resume_state(state);18701871say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg);18721873if(!index_has_changes(NULL)) {1874printf_ln(_("No changes - did you forget to use 'git add'?\n"1875"If there is nothing left to stage, chances are that something else\n"1876"already introduced the same changes; you might want to skip this patch."));1877die_user_resolve(state);1878}18791880if(unmerged_cache()) {1881printf_ln(_("You still have unmerged paths in your index.\n"1882"Did you forget to use 'git add'?"));1883die_user_resolve(state);1884}18851886if(state->interactive) {1887write_index_patch(state);1888if(do_interactive(state))1889goto next;1890}18911892rerere(0);18931894do_commit(state);18951896next:1897am_next(state);1898am_run(state,0);1899}19001901/**1902 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is1903 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on1904 * failure.1905 */1906static intfast_forward_to(struct tree *head,struct tree *remote,int reset)1907{1908struct lock_file *lock_file;1909struct unpack_trees_options opts;1910struct tree_desc t[2];19111912if(parse_tree(head) ||parse_tree(remote))1913return-1;19141915 lock_file =xcalloc(1,sizeof(struct lock_file));1916hold_locked_index(lock_file,1);19171918refresh_cache(REFRESH_QUIET);19191920memset(&opts,0,sizeof(opts));1921 opts.head_idx =1;1922 opts.src_index = &the_index;1923 opts.dst_index = &the_index;1924 opts.update =1;1925 opts.merge =1;1926 opts.reset = reset;1927 opts.fn = twoway_merge;1928init_tree_desc(&t[0], head->buffer, head->size);1929init_tree_desc(&t[1], remote->buffer, remote->size);19301931if(unpack_trees(2, t, &opts)) {1932rollback_lock_file(lock_file);1933return-1;1934}19351936if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1937die(_("unable to write new index file"));19381939return0;1940}19411942/**1943 * Clean the index without touching entries that are not modified between1944 * `head` and `remote`.1945 */1946static intclean_index(const unsigned char*head,const unsigned char*remote)1947{1948struct lock_file *lock_file;1949struct tree *head_tree, *remote_tree, *index_tree;1950unsigned char index[GIT_SHA1_RAWSZ];1951struct pathspec pathspec;19521953 head_tree =parse_tree_indirect(head);1954if(!head_tree)1955returnerror(_("Could not parse object '%s'."),sha1_to_hex(head));19561957 remote_tree =parse_tree_indirect(remote);1958if(!remote_tree)1959returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote));19601961read_cache_unmerged();19621963if(fast_forward_to(head_tree, head_tree,1))1964return-1;19651966if(write_cache_as_tree(index,0, NULL))1967return-1;19681969 index_tree =parse_tree_indirect(index);1970if(!index_tree)1971returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));19721973if(fast_forward_to(index_tree, remote_tree,0))1974return-1;19751976memset(&pathspec,0,sizeof(pathspec));19771978 lock_file =xcalloc(1,sizeof(struct lock_file));1979hold_locked_index(lock_file,1);19801981if(read_tree(remote_tree,0, &pathspec)) {1982rollback_lock_file(lock_file);1983return-1;1984}19851986if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1987die(_("unable to write new index file"));19881989remove_branch_state();19901991return0;1992}19931994/**1995 * Resets rerere's merge resolution metadata.1996 */1997static voidam_rerere_clear(void)1998{1999struct string_list merge_rr = STRING_LIST_INIT_DUP;2000int fd =setup_rerere(&merge_rr,0);20012002if(fd <0)2003return;20042005rerere_clear(&merge_rr);2006string_list_clear(&merge_rr,1);2007}20082009/**2010 * Resume the current am session by skipping the current patch.2011 */2012static voidam_skip(struct am_state *state)2013{2014unsigned char head[GIT_SHA1_RAWSZ];20152016am_rerere_clear();20172018if(get_sha1("HEAD", head))2019hashcpy(head, EMPTY_TREE_SHA1_BIN);20202021if(clean_index(head, head))2022die(_("failed to clean index"));20232024am_next(state);2025am_run(state,0);2026}20272028/**2029 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.2030 *2031 * It is not safe to reset HEAD when:2032 * 1. git-am previously failed because the index was dirty.2033 * 2. HEAD has moved since git-am previously failed.2034 */2035static intsafe_to_abort(const struct am_state *state)2036{2037struct strbuf sb = STRBUF_INIT;2038unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];20392040if(file_exists(am_path(state,"dirtyindex")))2041return0;20422043if(read_state_file(&sb, state,"abort-safety",1) >0) {2044if(get_sha1_hex(sb.buf, abort_safety))2045die(_("could not parse%s"),am_path(state,"abort_safety"));2046}else2047hashclr(abort_safety);20482049if(get_sha1("HEAD", head))2050hashclr(head);20512052if(!hashcmp(head, abort_safety))2053return1;20542055error(_("You seem to have moved HEAD since the last 'am' failure.\n"2056"Not rewinding to ORIG_HEAD"));20572058return0;2059}20602061/**2062 * Aborts the current am session if it is safe to do so.2063 */2064static voidam_abort(struct am_state *state)2065{2066unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];2067int has_curr_head, has_orig_head;2068char*curr_branch;20692070if(!safe_to_abort(state)) {2071am_destroy(state);2072return;2073}20742075am_rerere_clear();20762077 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);2078 has_curr_head = !is_null_sha1(curr_head);2079if(!has_curr_head)2080hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);20812082 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);2083if(!has_orig_head)2084hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);20852086clean_index(curr_head, orig_head);20872088if(has_orig_head)2089update_ref("am --abort","HEAD", orig_head,2090 has_curr_head ? curr_head : NULL,0,2091 UPDATE_REFS_DIE_ON_ERR);2092else if(curr_branch)2093delete_ref(curr_branch, NULL, REF_NODEREF);20942095free(curr_branch);2096am_destroy(state);2097}20982099/**2100 * parse_options() callback that validates and sets opt->value to the2101 * PATCH_FORMAT_* enum value corresponding to `arg`.2102 */2103static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)2104{2105int*opt_value = opt->value;21062107if(!strcmp(arg,"mbox"))2108*opt_value = PATCH_FORMAT_MBOX;2109else if(!strcmp(arg,"stgit"))2110*opt_value = PATCH_FORMAT_STGIT;2111else if(!strcmp(arg,"stgit-series"))2112*opt_value = PATCH_FORMAT_STGIT_SERIES;2113else if(!strcmp(arg,"hg"))2114*opt_value = PATCH_FORMAT_HG;2115else2116returnerror(_("Invalid value for --patch-format:%s"), arg);2117return0;2118}21192120enum resume_mode {2121 RESUME_FALSE =0,2122 RESUME_APPLY,2123 RESUME_RESOLVED,2124 RESUME_SKIP,2125 RESUME_ABORT2126};21272128intcmd_am(int argc,const char**argv,const char*prefix)2129{2130struct am_state state;2131int binary = -1;2132int keep_cr = -1;2133int patch_format = PATCH_FORMAT_UNKNOWN;2134enum resume_mode resume = RESUME_FALSE;21352136const char*const usage[] = {2137N_("git am [options] [(<mbox>|<Maildir>)...]"),2138N_("git am [options] (--continue | --skip | --abort)"),2139 NULL2140};21412142struct option options[] = {2143OPT_BOOL('i',"interactive", &state.interactive,2144N_("run interactively")),2145OPT_HIDDEN_BOOL('b',"binary", &binary,2146N_("(historical option -- no-op")),2147OPT_BOOL('3',"3way", &state.threeway,2148N_("allow fall back on 3way merging if needed")),2149OPT__QUIET(&state.quiet,N_("be quiet")),2150OPT_BOOL('s',"signoff", &state.signoff,2151N_("add a Signed-off-by line to the commit message")),2152OPT_BOOL('u',"utf8", &state.utf8,2153N_("recode into utf8 (default)")),2154OPT_SET_INT('k',"keep", &state.keep,2155N_("pass -k flag to git-mailinfo"), KEEP_TRUE),2156OPT_SET_INT(0,"keep-non-patch", &state.keep,2157N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),2158OPT_BOOL('m',"message-id", &state.message_id,2159N_("pass -m flag to git-mailinfo")),2160{ OPTION_SET_INT,0,"keep-cr", &keep_cr, NULL,2161N_("pass --keep-cr flag to git-mailsplit for mbox format"),2162 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,1},2163{ OPTION_SET_INT,0,"no-keep-cr", &keep_cr, NULL,2164N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),2165 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL,0},2166OPT_BOOL('c',"scissors", &state.scissors,2167N_("strip everything before a scissors line")),2168OPT_PASSTHRU_ARGV(0,"whitespace", &state.git_apply_opts,N_("action"),2169N_("pass it through git-apply"),21700),2171OPT_PASSTHRU_ARGV(0,"ignore-space-change", &state.git_apply_opts, NULL,2172N_("pass it through git-apply"),2173 PARSE_OPT_NOARG),2174OPT_PASSTHRU_ARGV(0,"ignore-whitespace", &state.git_apply_opts, NULL,2175N_("pass it through git-apply"),2176 PARSE_OPT_NOARG),2177OPT_PASSTHRU_ARGV(0,"directory", &state.git_apply_opts,N_("root"),2178N_("pass it through git-apply"),21790),2180OPT_PASSTHRU_ARGV(0,"exclude", &state.git_apply_opts,N_("path"),2181N_("pass it through git-apply"),21820),2183OPT_PASSTHRU_ARGV(0,"include", &state.git_apply_opts,N_("path"),2184N_("pass it through git-apply"),21850),2186OPT_PASSTHRU_ARGV('C', NULL, &state.git_apply_opts,N_("n"),2187N_("pass it through git-apply"),21880),2189OPT_PASSTHRU_ARGV('p', NULL, &state.git_apply_opts,N_("num"),2190N_("pass it through git-apply"),21910),2192OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),2193N_("format the patch(es) are in"),2194 parse_opt_patchformat),2195OPT_PASSTHRU_ARGV(0,"reject", &state.git_apply_opts, NULL,2196N_("pass it through git-apply"),2197 PARSE_OPT_NOARG),2198OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,2199N_("override error message when patch failure occurs")),2200OPT_CMDMODE(0,"continue", &resume,2201N_("continue applying patches after resolving a conflict"),2202 RESUME_RESOLVED),2203OPT_CMDMODE('r',"resolved", &resume,2204N_("synonyms for --continue"),2205 RESUME_RESOLVED),2206OPT_CMDMODE(0,"skip", &resume,2207N_("skip the current patch"),2208 RESUME_SKIP),2209OPT_CMDMODE(0,"abort", &resume,2210N_("restore the original branch and abort the patching operation."),2211 RESUME_ABORT),2212OPT_BOOL(0,"committer-date-is-author-date",2213&state.committer_date_is_author_date,2214N_("lie about committer date")),2215OPT_BOOL(0,"ignore-date", &state.ignore_date,2216N_("use current timestamp for author date")),2217OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),2218{ OPTION_STRING,'S',"gpg-sign", &state.sign_commit,N_("key-id"),2219N_("GPG-sign commits"),2220 PARSE_OPT_OPTARG, NULL, (intptr_t)""},2221OPT_HIDDEN_BOOL(0,"rebasing", &state.rebasing,2222N_("(internal use for git-rebase)")),2223OPT_END()2224};22252226git_config(git_default_config, NULL);22272228am_state_init(&state,git_path("rebase-apply"));22292230 argc =parse_options(argc, argv, prefix, options, usage,0);22312232if(binary >=0)2233fprintf_ln(stderr,_("The -b/--binary option has been a no-op for long time, and\n"2234"it will be removed. Please do not use it anymore."));22352236/* Ensure a valid committer ident can be constructed */2237git_committer_info(IDENT_STRICT);22382239if(read_index_preload(&the_index, NULL) <0)2240die(_("failed to read the index"));22412242if(am_in_progress(&state)) {2243/*2244 * Catch user error to feed us patches when there is a session2245 * in progress:2246 *2247 * 1. mbox path(s) are provided on the command-line.2248 * 2. stdin is not a tty: the user is trying to feed us a patch2249 * from standard input. This is somewhat unreliable -- stdin2250 * could be /dev/null for example and the caller did not2251 * intend to feed us a patch but wanted to continue2252 * unattended.2253 */2254if(argc || (resume == RESUME_FALSE && !isatty(0)))2255die(_("previous rebase directory%sstill exists but mbox given."),2256 state.dir);22572258if(resume == RESUME_FALSE)2259 resume = RESUME_APPLY;22602261am_load(&state);2262}else{2263struct argv_array paths = ARGV_ARRAY_INIT;2264int i;22652266/*2267 * Handle stray state directory in the independent-run case. In2268 * the --rebasing case, it is up to the caller to take care of2269 * stray directories.2270 */2271if(file_exists(state.dir) && !state.rebasing) {2272if(resume == RESUME_ABORT) {2273am_destroy(&state);2274am_state_release(&state);2275return0;2276}22772278die(_("Stray%sdirectory found.\n"2279"Use\"git am --abort\"to remove it."),2280 state.dir);2281}22822283if(resume)2284die(_("Resolve operation not in progress, we are not resuming."));22852286for(i =0; i < argc; i++) {2287if(is_absolute_path(argv[i]) || !prefix)2288argv_array_push(&paths, argv[i]);2289else2290argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));2291}22922293am_setup(&state, patch_format, paths.argv, keep_cr);22942295argv_array_clear(&paths);2296}22972298switch(resume) {2299case RESUME_FALSE:2300am_run(&state,0);2301break;2302case RESUME_APPLY:2303am_run(&state,1);2304break;2305case RESUME_RESOLVED:2306am_resolve(&state);2307break;2308case RESUME_SKIP:2309am_skip(&state);2310break;2311case RESUME_ABORT:2312am_abort(&state);2313break;2314default:2315die("BUG: invalid resume value");2316}23172318am_state_release(&state);23192320return0;2321}