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 22/** 23 * Returns 1 if the file is empty or does not exist, 0 otherwise. 24 */ 25static intis_empty_file(const char*filename) 26{ 27struct stat st; 28 29if(stat(filename, &st) <0) { 30if(errno == ENOENT) 31return1; 32die_errno(_("could not stat%s"), filename); 33} 34 35return!st.st_size; 36} 37 38/** 39 * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. 40 */ 41static intstrbuf_getline_crlf(struct strbuf *sb,FILE*fp) 42{ 43if(strbuf_getwholeline(sb, fp,'\n')) 44return EOF; 45if(sb->buf[sb->len -1] =='\n') { 46strbuf_setlen(sb, sb->len -1); 47if(sb->len >0&& sb->buf[sb->len -1] =='\r') 48strbuf_setlen(sb, sb->len -1); 49} 50return0; 51} 52 53/** 54 * Returns the length of the first line of msg. 55 */ 56static intlinelen(const char*msg) 57{ 58returnstrchrnul(msg,'\n') - msg; 59} 60 61enum patch_format { 62 PATCH_FORMAT_UNKNOWN =0, 63 PATCH_FORMAT_MBOX 64}; 65 66struct am_state { 67/* state directory path */ 68char*dir; 69 70/* current and last patch numbers, 1-indexed */ 71int cur; 72int last; 73 74/* commit metadata and message */ 75char*author_name; 76char*author_email; 77char*author_date; 78char*msg; 79size_t msg_len; 80 81/* number of digits in patch filename */ 82int prec; 83 84/* various operating modes and command line options */ 85int quiet; 86const char*resolvemsg; 87}; 88 89/** 90 * Initializes am_state with the default values. The state directory is set to 91 * dir. 92 */ 93static voidam_state_init(struct am_state *state,const char*dir) 94{ 95memset(state,0,sizeof(*state)); 96 97assert(dir); 98 state->dir =xstrdup(dir); 99 100 state->prec =4; 101} 102 103/** 104 * Releases memory allocated by an am_state. 105 */ 106static voidam_state_release(struct am_state *state) 107{ 108free(state->dir); 109free(state->author_name); 110free(state->author_email); 111free(state->author_date); 112free(state->msg); 113} 114 115/** 116 * Returns path relative to the am_state directory. 117 */ 118staticinlineconst char*am_path(const struct am_state *state,const char*path) 119{ 120returnmkpath("%s/%s", state->dir, path); 121} 122 123/** 124 * If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline 125 * at the end. 126 */ 127static voidsay(const struct am_state *state,FILE*fp,const char*fmt, ...) 128{ 129va_list ap; 130 131va_start(ap, fmt); 132if(!state->quiet) { 133vfprintf(fp, fmt, ap); 134putc('\n', fp); 135} 136va_end(ap); 137} 138 139/** 140 * Returns 1 if there is an am session in progress, 0 otherwise. 141 */ 142static intam_in_progress(const struct am_state *state) 143{ 144struct stat st; 145 146if(lstat(state->dir, &st) <0|| !S_ISDIR(st.st_mode)) 147return0; 148if(lstat(am_path(state,"last"), &st) || !S_ISREG(st.st_mode)) 149return0; 150if(lstat(am_path(state,"next"), &st) || !S_ISREG(st.st_mode)) 151return0; 152return1; 153} 154 155/** 156 * Reads the contents of `file` in the `state` directory into `sb`. Returns the 157 * number of bytes read on success, -1 if the file does not exist. If `trim` is 158 * set, trailing whitespace will be removed. 159 */ 160static intread_state_file(struct strbuf *sb,const struct am_state *state, 161const char*file,int trim) 162{ 163strbuf_reset(sb); 164 165if(strbuf_read_file(sb,am_path(state, file),0) >=0) { 166if(trim) 167strbuf_trim(sb); 168 169return sb->len; 170} 171 172if(errno == ENOENT) 173return-1; 174 175die_errno(_("could not read '%s'"),am_path(state, file)); 176} 177 178/** 179 * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE 180 * as a newly-allocated string. VALUE must be a quoted string, and the KEY must 181 * match `key`. Returns NULL on failure. 182 * 183 * This is used by read_author_script() to read the GIT_AUTHOR_* variables from 184 * the author-script. 185 */ 186static char*read_shell_var(FILE*fp,const char*key) 187{ 188struct strbuf sb = STRBUF_INIT; 189const char*str; 190 191if(strbuf_getline(&sb, fp,'\n')) 192goto fail; 193 194if(!skip_prefix(sb.buf, key, &str)) 195goto fail; 196 197if(!skip_prefix(str,"=", &str)) 198goto fail; 199 200strbuf_remove(&sb,0, str - sb.buf); 201 202 str =sq_dequote(sb.buf); 203if(!str) 204goto fail; 205 206returnstrbuf_detach(&sb, NULL); 207 208fail: 209strbuf_release(&sb); 210return NULL; 211} 212 213/** 214 * Reads and parses the state directory's "author-script" file, and sets 215 * state->author_name, state->author_email and state->author_date accordingly. 216 * Returns 0 on success, -1 if the file could not be parsed. 217 * 218 * The author script is of the format: 219 * 220 * GIT_AUTHOR_NAME='$author_name' 221 * GIT_AUTHOR_EMAIL='$author_email' 222 * GIT_AUTHOR_DATE='$author_date' 223 * 224 * where $author_name, $author_email and $author_date are quoted. We are strict 225 * with our parsing, as the file was meant to be eval'd in the old git-am.sh 226 * script, and thus if the file differs from what this function expects, it is 227 * better to bail out than to do something that the user does not expect. 228 */ 229static intread_author_script(struct am_state *state) 230{ 231const char*filename =am_path(state,"author-script"); 232FILE*fp; 233 234assert(!state->author_name); 235assert(!state->author_email); 236assert(!state->author_date); 237 238 fp =fopen(filename,"r"); 239if(!fp) { 240if(errno == ENOENT) 241return0; 242die_errno(_("could not open '%s' for reading"), filename); 243} 244 245 state->author_name =read_shell_var(fp,"GIT_AUTHOR_NAME"); 246if(!state->author_name) { 247fclose(fp); 248return-1; 249} 250 251 state->author_email =read_shell_var(fp,"GIT_AUTHOR_EMAIL"); 252if(!state->author_email) { 253fclose(fp); 254return-1; 255} 256 257 state->author_date =read_shell_var(fp,"GIT_AUTHOR_DATE"); 258if(!state->author_date) { 259fclose(fp); 260return-1; 261} 262 263if(fgetc(fp) != EOF) { 264fclose(fp); 265return-1; 266} 267 268fclose(fp); 269return0; 270} 271 272/** 273 * Saves state->author_name, state->author_email and state->author_date in the 274 * state directory's "author-script" file. 275 */ 276static voidwrite_author_script(const struct am_state *state) 277{ 278struct strbuf sb = STRBUF_INIT; 279 280strbuf_addstr(&sb,"GIT_AUTHOR_NAME="); 281sq_quote_buf(&sb, state->author_name); 282strbuf_addch(&sb,'\n'); 283 284strbuf_addstr(&sb,"GIT_AUTHOR_EMAIL="); 285sq_quote_buf(&sb, state->author_email); 286strbuf_addch(&sb,'\n'); 287 288strbuf_addstr(&sb,"GIT_AUTHOR_DATE="); 289sq_quote_buf(&sb, state->author_date); 290strbuf_addch(&sb,'\n'); 291 292write_file(am_path(state,"author-script"),1,"%s", sb.buf); 293 294strbuf_release(&sb); 295} 296 297/** 298 * Reads the commit message from the state directory's "final-commit" file, 299 * setting state->msg to its contents and state->msg_len to the length of its 300 * contents in bytes. 301 * 302 * Returns 0 on success, -1 if the file does not exist. 303 */ 304static intread_commit_msg(struct am_state *state) 305{ 306struct strbuf sb = STRBUF_INIT; 307 308assert(!state->msg); 309 310if(read_state_file(&sb, state,"final-commit",0) <0) { 311strbuf_release(&sb); 312return-1; 313} 314 315 state->msg =strbuf_detach(&sb, &state->msg_len); 316return0; 317} 318 319/** 320 * Saves state->msg in the state directory's "final-commit" file. 321 */ 322static voidwrite_commit_msg(const struct am_state *state) 323{ 324int fd; 325const char*filename =am_path(state,"final-commit"); 326 327 fd =xopen(filename, O_WRONLY | O_CREAT,0666); 328if(write_in_full(fd, state->msg, state->msg_len) <0) 329die_errno(_("could not write to%s"), filename); 330close(fd); 331} 332 333/** 334 * Loads state from disk. 335 */ 336static voidam_load(struct am_state *state) 337{ 338struct strbuf sb = STRBUF_INIT; 339 340if(read_state_file(&sb, state,"next",1) <0) 341die("BUG: state file 'next' does not exist"); 342 state->cur =strtol(sb.buf, NULL,10); 343 344if(read_state_file(&sb, state,"last",1) <0) 345die("BUG: state file 'last' does not exist"); 346 state->last =strtol(sb.buf, NULL,10); 347 348if(read_author_script(state) <0) 349die(_("could not parse author script")); 350 351read_commit_msg(state); 352 353read_state_file(&sb, state,"quiet",1); 354 state->quiet = !strcmp(sb.buf,"t"); 355 356strbuf_release(&sb); 357} 358 359/** 360 * Removes the am_state directory, forcefully terminating the current am 361 * session. 362 */ 363static voidam_destroy(const struct am_state *state) 364{ 365struct strbuf sb = STRBUF_INIT; 366 367strbuf_addstr(&sb, state->dir); 368remove_dir_recursively(&sb,0); 369strbuf_release(&sb); 370} 371 372/** 373 * Determines if the file looks like a piece of RFC2822 mail by grabbing all 374 * non-indented lines and checking if they look like they begin with valid 375 * header field names. 376 * 377 * Returns 1 if the file looks like a piece of mail, 0 otherwise. 378 */ 379static intis_mail(FILE*fp) 380{ 381const char*header_regex ="^[!-9;-~]+:"; 382struct strbuf sb = STRBUF_INIT; 383 regex_t regex; 384int ret =1; 385 386if(fseek(fp,0L, SEEK_SET)) 387die_errno(_("fseek failed")); 388 389if(regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) 390die("invalid pattern:%s", header_regex); 391 392while(!strbuf_getline_crlf(&sb, fp)) { 393if(!sb.len) 394break;/* End of header */ 395 396/* Ignore indented folded lines */ 397if(*sb.buf =='\t'|| *sb.buf ==' ') 398continue; 399 400/* It's a header if it matches header_regex */ 401if(regexec(®ex, sb.buf,0, NULL,0)) { 402 ret =0; 403goto done; 404} 405} 406 407done: 408regfree(®ex); 409strbuf_release(&sb); 410return ret; 411} 412 413/** 414 * Attempts to detect the patch_format of the patches contained in `paths`, 415 * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if 416 * detection fails. 417 */ 418static intdetect_patch_format(const char**paths) 419{ 420enum patch_format ret = PATCH_FORMAT_UNKNOWN; 421struct strbuf l1 = STRBUF_INIT; 422FILE*fp; 423 424/* 425 * We default to mbox format if input is from stdin and for directories 426 */ 427if(!*paths || !strcmp(*paths,"-") ||is_directory(*paths)) 428return PATCH_FORMAT_MBOX; 429 430/* 431 * Otherwise, check the first few lines of the first patch, starting 432 * from the first non-blank line, to try to detect its format. 433 */ 434 435 fp =xfopen(*paths,"r"); 436 437while(!strbuf_getline_crlf(&l1, fp)) { 438if(l1.len) 439break; 440} 441 442if(starts_with(l1.buf,"From ") ||starts_with(l1.buf,"From: ")) { 443 ret = PATCH_FORMAT_MBOX; 444goto done; 445} 446 447if(l1.len &&is_mail(fp)) { 448 ret = PATCH_FORMAT_MBOX; 449goto done; 450} 451 452done: 453fclose(fp); 454strbuf_release(&l1); 455return ret; 456} 457 458/** 459 * Splits out individual email patches from `paths`, where each path is either 460 * a mbox file or a Maildir. Returns 0 on success, -1 on failure. 461 */ 462static intsplit_mail_mbox(struct am_state *state,const char**paths) 463{ 464struct child_process cp = CHILD_PROCESS_INIT; 465struct strbuf last = STRBUF_INIT; 466 467 cp.git_cmd =1; 468argv_array_push(&cp.args,"mailsplit"); 469argv_array_pushf(&cp.args,"-d%d", state->prec); 470argv_array_pushf(&cp.args,"-o%s", state->dir); 471argv_array_push(&cp.args,"-b"); 472argv_array_push(&cp.args,"--"); 473argv_array_pushv(&cp.args, paths); 474 475if(capture_command(&cp, &last,8)) 476return-1; 477 478 state->cur =1; 479 state->last =strtol(last.buf, NULL,10); 480 481return0; 482} 483 484/** 485 * Splits a list of files/directories into individual email patches. Each path 486 * in `paths` must be a file/directory that is formatted according to 487 * `patch_format`. 488 * 489 * Once split out, the individual email patches will be stored in the state 490 * directory, with each patch's filename being its index, padded to state->prec 491 * digits. 492 * 493 * state->cur will be set to the index of the first mail, and state->last will 494 * be set to the index of the last mail. 495 * 496 * Returns 0 on success, -1 on failure. 497 */ 498static intsplit_mail(struct am_state *state,enum patch_format patch_format, 499const char**paths) 500{ 501switch(patch_format) { 502case PATCH_FORMAT_MBOX: 503returnsplit_mail_mbox(state, paths); 504default: 505die("BUG: invalid patch_format"); 506} 507return-1; 508} 509 510/** 511 * Setup a new am session for applying patches 512 */ 513static voidam_setup(struct am_state *state,enum patch_format patch_format, 514const char**paths) 515{ 516unsigned char curr_head[GIT_SHA1_RAWSZ]; 517 518if(!patch_format) 519 patch_format =detect_patch_format(paths); 520 521if(!patch_format) { 522fprintf_ln(stderr,_("Patch format detection failed.")); 523exit(128); 524} 525 526if(mkdir(state->dir,0777) <0&& errno != EEXIST) 527die_errno(_("failed to create directory '%s'"), state->dir); 528 529if(split_mail(state, patch_format, paths) <0) { 530am_destroy(state); 531die(_("Failed to split patches.")); 532} 533 534write_file(am_path(state,"quiet"),1, state->quiet ?"t":"f"); 535 536if(!get_sha1("HEAD", curr_head)) { 537write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(curr_head)); 538update_ref("am","ORIG_HEAD", curr_head, NULL,0, UPDATE_REFS_DIE_ON_ERR); 539}else{ 540write_file(am_path(state,"abort-safety"),1,"%s",""); 541delete_ref("ORIG_HEAD", NULL,0); 542} 543 544/* 545 * NOTE: Since the "next" and "last" files determine if an am_state 546 * session is in progress, they should be written last. 547 */ 548 549write_file(am_path(state,"next"),1,"%d", state->cur); 550 551write_file(am_path(state,"last"),1,"%d", state->last); 552} 553 554/** 555 * Increments the patch pointer, and cleans am_state for the application of the 556 * next patch. 557 */ 558static voidam_next(struct am_state *state) 559{ 560unsigned char head[GIT_SHA1_RAWSZ]; 561 562free(state->author_name); 563 state->author_name = NULL; 564 565free(state->author_email); 566 state->author_email = NULL; 567 568free(state->author_date); 569 state->author_date = NULL; 570 571free(state->msg); 572 state->msg = NULL; 573 state->msg_len =0; 574 575unlink(am_path(state,"author-script")); 576unlink(am_path(state,"final-commit")); 577 578if(!get_sha1("HEAD", head)) 579write_file(am_path(state,"abort-safety"),1,"%s",sha1_to_hex(head)); 580else 581write_file(am_path(state,"abort-safety"),1,"%s",""); 582 583 state->cur++; 584write_file(am_path(state,"next"),1,"%d", state->cur); 585} 586 587/** 588 * Returns the filename of the current patch email. 589 */ 590static const char*msgnum(const struct am_state *state) 591{ 592static struct strbuf sb = STRBUF_INIT; 593 594strbuf_reset(&sb); 595strbuf_addf(&sb,"%0*d", state->prec, state->cur); 596 597return sb.buf; 598} 599 600/** 601 * Refresh and write index. 602 */ 603static voidrefresh_and_write_cache(void) 604{ 605struct lock_file *lock_file =xcalloc(1,sizeof(struct lock_file)); 606 607hold_locked_index(lock_file,1); 608refresh_cache(REFRESH_QUIET); 609if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 610die(_("unable to write index file")); 611} 612 613/** 614 * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn 615 * branch, returns 1 if there are entries in the index, 0 otherwise. If an 616 * strbuf is provided, the space-separated list of files that differ will be 617 * appended to it. 618 */ 619static intindex_has_changes(struct strbuf *sb) 620{ 621unsigned char head[GIT_SHA1_RAWSZ]; 622int i; 623 624if(!get_sha1_tree("HEAD", head)) { 625struct diff_options opt; 626 627diff_setup(&opt); 628DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); 629if(!sb) 630DIFF_OPT_SET(&opt, QUICK); 631do_diff_cache(head, &opt); 632diffcore_std(&opt); 633for(i =0; sb && i < diff_queued_diff.nr; i++) { 634if(i) 635strbuf_addch(sb,' '); 636strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); 637} 638diff_flush(&opt); 639returnDIFF_OPT_TST(&opt, HAS_CHANGES) !=0; 640}else{ 641for(i =0; sb && i < active_nr; i++) { 642if(i) 643strbuf_addch(sb,' '); 644strbuf_addstr(sb, active_cache[i]->name); 645} 646return!!active_nr; 647} 648} 649 650/** 651 * Dies with a user-friendly message on how to proceed after resolving the 652 * problem. This message can be overridden with state->resolvemsg. 653 */ 654static void NORETURN die_user_resolve(const struct am_state *state) 655{ 656if(state->resolvemsg) { 657printf_ln("%s", state->resolvemsg); 658}else{ 659const char*cmdline ="git am"; 660 661printf_ln(_("When you have resolved this problem, run\"%s--continue\"."), cmdline); 662printf_ln(_("If you prefer to skip this patch, run\"%s--skip\"instead."), cmdline); 663printf_ln(_("To restore the original branch and stop patching, run\"%s--abort\"."), cmdline); 664} 665 666exit(128); 667} 668 669/** 670 * Parses `mail` using git-mailinfo, extracting its patch and authorship info. 671 * state->msg will be set to the patch message. state->author_name, 672 * state->author_email and state->author_date will be set to the patch author's 673 * name, email and date respectively. The patch body will be written to the 674 * state directory's "patch" file. 675 * 676 * Returns 1 if the patch should be skipped, 0 otherwise. 677 */ 678static intparse_mail(struct am_state *state,const char*mail) 679{ 680FILE*fp; 681struct child_process cp = CHILD_PROCESS_INIT; 682struct strbuf sb = STRBUF_INIT; 683struct strbuf msg = STRBUF_INIT; 684struct strbuf author_name = STRBUF_INIT; 685struct strbuf author_date = STRBUF_INIT; 686struct strbuf author_email = STRBUF_INIT; 687int ret =0; 688 689 cp.git_cmd =1; 690 cp.in =xopen(mail, O_RDONLY,0); 691 cp.out =xopen(am_path(state,"info"), O_WRONLY | O_CREAT,0777); 692 693argv_array_push(&cp.args,"mailinfo"); 694argv_array_push(&cp.args,am_path(state,"msg")); 695argv_array_push(&cp.args,am_path(state,"patch")); 696 697if(run_command(&cp) <0) 698die("could not parse patch"); 699 700close(cp.in); 701close(cp.out); 702 703/* Extract message and author information */ 704 fp =xfopen(am_path(state,"info"),"r"); 705while(!strbuf_getline(&sb, fp,'\n')) { 706const char*x; 707 708if(skip_prefix(sb.buf,"Subject: ", &x)) { 709if(msg.len) 710strbuf_addch(&msg,'\n'); 711strbuf_addstr(&msg, x); 712}else if(skip_prefix(sb.buf,"Author: ", &x)) 713strbuf_addstr(&author_name, x); 714else if(skip_prefix(sb.buf,"Email: ", &x)) 715strbuf_addstr(&author_email, x); 716else if(skip_prefix(sb.buf,"Date: ", &x)) 717strbuf_addstr(&author_date, x); 718} 719fclose(fp); 720 721/* Skip pine's internal folder data */ 722if(!strcmp(author_name.buf,"Mail System Internal Data")) { 723 ret =1; 724goto finish; 725} 726 727if(is_empty_file(am_path(state,"patch"))) { 728printf_ln(_("Patch is empty. Was it split wrong?")); 729die_user_resolve(state); 730} 731 732strbuf_addstr(&msg,"\n\n"); 733if(strbuf_read_file(&msg,am_path(state,"msg"),0) <0) 734die_errno(_("could not read '%s'"),am_path(state,"msg")); 735stripspace(&msg,0); 736 737assert(!state->author_name); 738 state->author_name =strbuf_detach(&author_name, NULL); 739 740assert(!state->author_email); 741 state->author_email =strbuf_detach(&author_email, NULL); 742 743assert(!state->author_date); 744 state->author_date =strbuf_detach(&author_date, NULL); 745 746assert(!state->msg); 747 state->msg =strbuf_detach(&msg, &state->msg_len); 748 749finish: 750strbuf_release(&msg); 751strbuf_release(&author_date); 752strbuf_release(&author_email); 753strbuf_release(&author_name); 754strbuf_release(&sb); 755return ret; 756} 757 758/** 759 * Applies current patch with git-apply. Returns 0 on success, -1 otherwise. 760 */ 761static intrun_apply(const struct am_state *state) 762{ 763struct child_process cp = CHILD_PROCESS_INIT; 764 765 cp.git_cmd =1; 766 767argv_array_push(&cp.args,"apply"); 768argv_array_push(&cp.args,"--index"); 769argv_array_push(&cp.args,am_path(state,"patch")); 770 771if(run_command(&cp)) 772return-1; 773 774/* Reload index as git-apply will have modified it. */ 775discard_cache(); 776read_cache(); 777 778return0; 779} 780 781/** 782 * Commits the current index with state->msg as the commit message and 783 * state->author_name, state->author_email and state->author_date as the author 784 * information. 785 */ 786static voiddo_commit(const struct am_state *state) 787{ 788unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ], 789 commit[GIT_SHA1_RAWSZ]; 790unsigned char*ptr; 791struct commit_list *parents = NULL; 792const char*reflog_msg, *author; 793struct strbuf sb = STRBUF_INIT; 794 795if(write_cache_as_tree(tree,0, NULL)) 796die(_("git write-tree failed to write a tree")); 797 798if(!get_sha1_commit("HEAD", parent)) { 799 ptr = parent; 800commit_list_insert(lookup_commit(parent), &parents); 801}else{ 802 ptr = NULL; 803say(state, stderr,_("applying to an empty history")); 804} 805 806 author =fmt_ident(state->author_name, state->author_email, 807 state->author_date, IDENT_STRICT); 808 809if(commit_tree(state->msg, state->msg_len, tree, parents, commit, 810 author, NULL)) 811die(_("failed to write commit object")); 812 813 reflog_msg =getenv("GIT_REFLOG_ACTION"); 814if(!reflog_msg) 815 reflog_msg ="am"; 816 817strbuf_addf(&sb,"%s: %.*s", reflog_msg,linelen(state->msg), 818 state->msg); 819 820update_ref(sb.buf,"HEAD", commit, ptr,0, UPDATE_REFS_DIE_ON_ERR); 821 822strbuf_release(&sb); 823} 824 825/** 826 * Validates the am_state for resuming -- the "msg" and authorship fields must 827 * be filled up. 828 */ 829static voidvalidate_resume_state(const struct am_state *state) 830{ 831if(!state->msg) 832die(_("cannot resume:%sdoes not exist."), 833am_path(state,"final-commit")); 834 835if(!state->author_name || !state->author_email || !state->author_date) 836die(_("cannot resume:%sdoes not exist."), 837am_path(state,"author-script")); 838} 839 840/** 841 * Applies all queued mail. 842 * 843 * If `resume` is true, we are "resuming". The "msg" and authorship fields, as 844 * well as the state directory's "patch" file is used as-is for applying the 845 * patch and committing it. 846 */ 847static voidam_run(struct am_state *state,int resume) 848{ 849const char*argv_gc_auto[] = {"gc","--auto", NULL}; 850struct strbuf sb = STRBUF_INIT; 851 852unlink(am_path(state,"dirtyindex")); 853 854refresh_and_write_cache(); 855 856if(index_has_changes(&sb)) { 857write_file(am_path(state,"dirtyindex"),1,"t"); 858die(_("Dirty index: cannot apply patches (dirty:%s)"), sb.buf); 859} 860 861strbuf_release(&sb); 862 863while(state->cur <= state->last) { 864const char*mail =am_path(state,msgnum(state)); 865 866if(!file_exists(mail)) 867goto next; 868 869if(resume) { 870validate_resume_state(state); 871 resume =0; 872}else{ 873if(parse_mail(state, mail)) 874goto next;/* mail should be skipped */ 875 876write_author_script(state); 877write_commit_msg(state); 878} 879 880say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg); 881 882if(run_apply(state) <0) { 883int advice_amworkdir =1; 884 885printf_ln(_("Patch failed at%s%.*s"),msgnum(state), 886linelen(state->msg), state->msg); 887 888git_config_get_bool("advice.amworkdir", &advice_amworkdir); 889 890if(advice_amworkdir) 891printf_ln(_("The copy of the patch that failed is found in:%s"), 892am_path(state,"patch")); 893 894die_user_resolve(state); 895} 896 897do_commit(state); 898 899next: 900am_next(state); 901} 902 903am_destroy(state); 904run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); 905} 906 907/** 908 * Resume the current am session after patch application failure. The user did 909 * all the hard work, and we do not have to do any patch application. Just 910 * trust and commit what the user has in the index and working tree. 911 */ 912static voidam_resolve(struct am_state *state) 913{ 914validate_resume_state(state); 915 916say(state, stdout,_("Applying: %.*s"),linelen(state->msg), state->msg); 917 918if(!index_has_changes(NULL)) { 919printf_ln(_("No changes - did you forget to use 'git add'?\n" 920"If there is nothing left to stage, chances are that something else\n" 921"already introduced the same changes; you might want to skip this patch.")); 922die_user_resolve(state); 923} 924 925if(unmerged_cache()) { 926printf_ln(_("You still have unmerged paths in your index.\n" 927"Did you forget to use 'git add'?")); 928die_user_resolve(state); 929} 930 931do_commit(state); 932 933am_next(state); 934am_run(state,0); 935} 936 937/** 938 * Performs a checkout fast-forward from `head` to `remote`. If `reset` is 939 * true, any unmerged entries will be discarded. Returns 0 on success, -1 on 940 * failure. 941 */ 942static intfast_forward_to(struct tree *head,struct tree *remote,int reset) 943{ 944struct lock_file *lock_file; 945struct unpack_trees_options opts; 946struct tree_desc t[2]; 947 948if(parse_tree(head) ||parse_tree(remote)) 949return-1; 950 951 lock_file =xcalloc(1,sizeof(struct lock_file)); 952hold_locked_index(lock_file,1); 953 954refresh_cache(REFRESH_QUIET); 955 956memset(&opts,0,sizeof(opts)); 957 opts.head_idx =1; 958 opts.src_index = &the_index; 959 opts.dst_index = &the_index; 960 opts.update =1; 961 opts.merge =1; 962 opts.reset = reset; 963 opts.fn = twoway_merge; 964init_tree_desc(&t[0], head->buffer, head->size); 965init_tree_desc(&t[1], remote->buffer, remote->size); 966 967if(unpack_trees(2, t, &opts)) { 968rollback_lock_file(lock_file); 969return-1; 970} 971 972if(write_locked_index(&the_index, lock_file, COMMIT_LOCK)) 973die(_("unable to write new index file")); 974 975return0; 976} 977 978/** 979 * Clean the index without touching entries that are not modified between 980 * `head` and `remote`. 981 */ 982static intclean_index(const unsigned char*head,const unsigned char*remote) 983{ 984struct lock_file *lock_file; 985struct tree *head_tree, *remote_tree, *index_tree; 986unsigned char index[GIT_SHA1_RAWSZ]; 987struct pathspec pathspec; 988 989 head_tree =parse_tree_indirect(head); 990if(!head_tree) 991returnerror(_("Could not parse object '%s'."),sha1_to_hex(head)); 992 993 remote_tree =parse_tree_indirect(remote); 994if(!remote_tree) 995returnerror(_("Could not parse object '%s'."),sha1_to_hex(remote)); 996 997read_cache_unmerged(); 998 999if(fast_forward_to(head_tree, head_tree,1))1000return-1;10011002if(write_cache_as_tree(index,0, NULL))1003return-1;10041005 index_tree =parse_tree_indirect(index);1006if(!index_tree)1007returnerror(_("Could not parse object '%s'."),sha1_to_hex(index));10081009if(fast_forward_to(index_tree, remote_tree,0))1010return-1;10111012memset(&pathspec,0,sizeof(pathspec));10131014 lock_file =xcalloc(1,sizeof(struct lock_file));1015hold_locked_index(lock_file,1);10161017if(read_tree(remote_tree,0, &pathspec)) {1018rollback_lock_file(lock_file);1019return-1;1020}10211022if(write_locked_index(&the_index, lock_file, COMMIT_LOCK))1023die(_("unable to write new index file"));10241025remove_branch_state();10261027return0;1028}10291030/**1031 * Resume the current am session by skipping the current patch.1032 */1033static voidam_skip(struct am_state *state)1034{1035unsigned char head[GIT_SHA1_RAWSZ];10361037if(get_sha1("HEAD", head))1038hashcpy(head, EMPTY_TREE_SHA1_BIN);10391040if(clean_index(head, head))1041die(_("failed to clean index"));10421043am_next(state);1044am_run(state,0);1045}10461047/**1048 * Returns true if it is safe to reset HEAD to the ORIG_HEAD, false otherwise.1049 *1050 * It is not safe to reset HEAD when:1051 * 1. git-am previously failed because the index was dirty.1052 * 2. HEAD has moved since git-am previously failed.1053 */1054static intsafe_to_abort(const struct am_state *state)1055{1056struct strbuf sb = STRBUF_INIT;1057unsigned char abort_safety[GIT_SHA1_RAWSZ], head[GIT_SHA1_RAWSZ];10581059if(file_exists(am_path(state,"dirtyindex")))1060return0;10611062if(read_state_file(&sb, state,"abort-safety",1) >0) {1063if(get_sha1_hex(sb.buf, abort_safety))1064die(_("could not parse%s"),am_path(state,"abort_safety"));1065}else1066hashclr(abort_safety);10671068if(get_sha1("HEAD", head))1069hashclr(head);10701071if(!hashcmp(head, abort_safety))1072return1;10731074error(_("You seem to have moved HEAD since the last 'am' failure.\n"1075"Not rewinding to ORIG_HEAD"));10761077return0;1078}10791080/**1081 * Aborts the current am session if it is safe to do so.1082 */1083static voidam_abort(struct am_state *state)1084{1085unsigned char curr_head[GIT_SHA1_RAWSZ], orig_head[GIT_SHA1_RAWSZ];1086int has_curr_head, has_orig_head;1087char*curr_branch;10881089if(!safe_to_abort(state)) {1090am_destroy(state);1091return;1092}10931094 curr_branch =resolve_refdup("HEAD",0, curr_head, NULL);1095 has_curr_head = !is_null_sha1(curr_head);1096if(!has_curr_head)1097hashcpy(curr_head, EMPTY_TREE_SHA1_BIN);10981099 has_orig_head = !get_sha1("ORIG_HEAD", orig_head);1100if(!has_orig_head)1101hashcpy(orig_head, EMPTY_TREE_SHA1_BIN);11021103clean_index(curr_head, orig_head);11041105if(has_orig_head)1106update_ref("am --abort","HEAD", orig_head,1107 has_curr_head ? curr_head : NULL,0,1108 UPDATE_REFS_DIE_ON_ERR);1109else if(curr_branch)1110delete_ref(curr_branch, NULL, REF_NODEREF);11111112free(curr_branch);1113am_destroy(state);1114}11151116/**1117 * parse_options() callback that validates and sets opt->value to the1118 * PATCH_FORMAT_* enum value corresponding to `arg`.1119 */1120static intparse_opt_patchformat(const struct option *opt,const char*arg,int unset)1121{1122int*opt_value = opt->value;11231124if(!strcmp(arg,"mbox"))1125*opt_value = PATCH_FORMAT_MBOX;1126else1127returnerror(_("Invalid value for --patch-format:%s"), arg);1128return0;1129}11301131enum resume_mode {1132 RESUME_FALSE =0,1133 RESUME_APPLY,1134 RESUME_RESOLVED,1135 RESUME_SKIP,1136 RESUME_ABORT1137};11381139intcmd_am(int argc,const char**argv,const char*prefix)1140{1141struct am_state state;1142int patch_format = PATCH_FORMAT_UNKNOWN;1143enum resume_mode resume = RESUME_FALSE;11441145const char*const usage[] = {1146N_("git am [options] [(<mbox>|<Maildir>)...]"),1147N_("git am [options] (--continue | --skip | --abort)"),1148 NULL1149};11501151struct option options[] = {1152OPT__QUIET(&state.quiet,N_("be quiet")),1153OPT_CALLBACK(0,"patch-format", &patch_format,N_("format"),1154N_("format the patch(es) are in"),1155 parse_opt_patchformat),1156OPT_STRING(0,"resolvemsg", &state.resolvemsg, NULL,1157N_("override error message when patch failure occurs")),1158OPT_CMDMODE(0,"continue", &resume,1159N_("continue applying patches after resolving a conflict"),1160 RESUME_RESOLVED),1161OPT_CMDMODE('r',"resolved", &resume,1162N_("synonyms for --continue"),1163 RESUME_RESOLVED),1164OPT_CMDMODE(0,"skip", &resume,1165N_("skip the current patch"),1166 RESUME_SKIP),1167OPT_CMDMODE(0,"abort", &resume,1168N_("restore the original branch and abort the patching operation."),1169 RESUME_ABORT),1170OPT_END()1171};11721173/*1174 * NEEDSWORK: Once all the features of git-am.sh have been1175 * re-implemented in builtin/am.c, this preamble can be removed.1176 */1177if(!getenv("_GIT_USE_BUILTIN_AM")) {1178const char*path =mkpath("%s/git-am",git_exec_path());11791180if(sane_execvp(path, (char**)argv) <0)1181die_errno("could not exec%s", path);1182}else{1183 prefix =setup_git_directory();1184trace_repo_setup(prefix);1185setup_work_tree();1186}11871188git_config(git_default_config, NULL);11891190am_state_init(&state,git_path("rebase-apply"));11911192 argc =parse_options(argc, argv, prefix, options, usage,0);11931194if(read_index_preload(&the_index, NULL) <0)1195die(_("failed to read the index"));11961197if(am_in_progress(&state)) {1198/*1199 * Catch user error to feed us patches when there is a session1200 * in progress:1201 *1202 * 1. mbox path(s) are provided on the command-line.1203 * 2. stdin is not a tty: the user is trying to feed us a patch1204 * from standard input. This is somewhat unreliable -- stdin1205 * could be /dev/null for example and the caller did not1206 * intend to feed us a patch but wanted to continue1207 * unattended.1208 */1209if(argc || (resume == RESUME_FALSE && !isatty(0)))1210die(_("previous rebase directory%sstill exists but mbox given."),1211 state.dir);12121213if(resume == RESUME_FALSE)1214 resume = RESUME_APPLY;12151216am_load(&state);1217}else{1218struct argv_array paths = ARGV_ARRAY_INIT;1219int i;12201221if(resume)1222die(_("Resolve operation not in progress, we are not resuming."));12231224for(i =0; i < argc; i++) {1225if(is_absolute_path(argv[i]) || !prefix)1226argv_array_push(&paths, argv[i]);1227else1228argv_array_push(&paths,mkpath("%s/%s", prefix, argv[i]));1229}12301231am_setup(&state, patch_format, paths.argv);12321233argv_array_clear(&paths);1234}12351236switch(resume) {1237case RESUME_FALSE:1238am_run(&state,0);1239break;1240case RESUME_APPLY:1241am_run(&state,1);1242break;1243case RESUME_RESOLVED:1244am_resolve(&state);1245break;1246case RESUME_SKIP:1247am_skip(&state);1248break;1249case RESUME_ABORT:1250am_abort(&state);1251break;1252default:1253die("BUG: invalid resume value");1254}12551256am_state_release(&state);12571258return0;1259}