1307
TODO_EXEC,
1308
TODO_LABEL,
1309
TODO_RESET,
1310
+ TODO_MERGE,
1311
/* commands that do nothing but are counted for reporting progress */
1312
TODO_NOOP,
1313
TODO_DROP,
1328
{ 'x', "exec" },
1329
{ 'l', "label" },
1330
{ 't', "reset" },
1331
+ { 'm', "merge" },
1332
{ 0, "noop" },
1333
{ 'd', "drop" },
1334
{ 0, NULL }
1756
return 0;
1757
}
1758
1759
+enum todo_item_flags {
1760
+ TODO_EDIT_MERGE_MSG = 1
1761
+};
1762
+
1763
struct todo_item {
1764
enum todo_command command;
1765
struct commit *commit;
1766
+ unsigned int flags;
1767
const char *arg;
1768
int arg_len;
1769
size_t offset_in_buf;
1798
char *end_of_object_name;
1799
int i, saved, status, padding;
1800
1801
+ item->flags = 0;
1802
+
1803
/* left-trim */
1804
bol += strspn(bol, " \t");
1805
1849
return 0;
1850
}
1851
1852
+ if (item->command == TODO_MERGE) {
1853
+ if (skip_prefix(bol, "-C", &bol))
1854
+ bol += strspn(bol, " \t");
1855
+ else if (skip_prefix(bol, "-c", &bol)) {
1856
+ bol += strspn(bol, " \t");
1857
+ item->flags |= TODO_EDIT_MERGE_MSG;
1858
+ } else {
1859
+ item->flags |= TODO_EDIT_MERGE_MSG;
1860
+ item->commit = NULL;
1861
+ item->arg = bol;
1862
+ item->arg_len = (int)(eol - bol);
1863
+ return 0;
1864
+ }
1865
+ }
1866
+
1867
end_of_object_name = (char *) bol + strcspn(bol, " \t\n");
1868
saved = *end_of_object_name;
1869
*end_of_object_name = '\0';
2678
return ret;
2679
}
2680
2681
+static int do_merge(struct commit *commit, const char *arg, int arg_len,
2682
+ int flags, struct replay_opts *opts)
2683
+{
2684
+ int run_commit_flags = (flags & TODO_EDIT_MERGE_MSG) ?
2685
+ EDIT_MSG | VERIFY_MSG : 0;
2686
+ struct strbuf ref_name = STRBUF_INIT;
2687
+ struct commit *head_commit, *merge_commit, *i;
2688
+ struct commit_list *bases, *j, *reversed = NULL;
2689
+ struct merge_options o;
2690
+ int merge_arg_len, oneline_offset, ret;
2691
+ static struct lock_file lock;
2692
+ const char *p;
2693
+
2694
+ if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) {
2695
+ ret = -1;
2696
+ goto leave_merge;
2697
+ }
2698
+
2699
+ head_commit = lookup_commit_reference_by_name("HEAD");
2700
+ if (!head_commit) {
2701
+ ret = error(_("cannot merge without a current revision"));
2702
+ goto leave_merge;
2703
+ }
2704
+
2705
+ oneline_offset = arg_len;
2706
+ merge_arg_len = strcspn(arg, " \t\n");
2707
+ p = arg + merge_arg_len;
2708
+ p += strspn(p, " \t\n");
2709
+ if (*p == '#' && (!p[1] || isspace(p[1]))) {
2710
+ p += 1 + strspn(p + 1, " \t\n");
2711
+ oneline_offset = p - arg;
2712
+ } else if (p - arg < arg_len)
2713
+ BUG("octopus merges are not supported yet: '%s'", p);
2714
+
2715
+ strbuf_addf(&ref_name, "refs/rewritten/%.*s", merge_arg_len, arg);
2716
+ merge_commit = lookup_commit_reference_by_name(ref_name.buf);
2717
+ if (!merge_commit) {
2718
+ /* fall back to non-rewritten ref or commit */
2719
+ strbuf_splice(&ref_name, 0, strlen("refs/rewritten/"), "", 0);
2720
+ merge_commit = lookup_commit_reference_by_name(ref_name.buf);
2721
+ }
2722
+
2723
+ if (!merge_commit) {
2724
+ ret = error(_("could not resolve '%s'"), ref_name.buf);
2725
+ goto leave_merge;
2726
+ }
2727
+
2728
+ if (commit) {
2729
+ const char *message = get_commit_buffer(commit, NULL);
2730
+ const char *body;
2731
+ int len;
2732
+
2733
+ if (!message) {
2734
+ ret = error(_("could not get commit message of '%s'"),
2735
+ oid_to_hex(&commit->object.oid));
2736
+ goto leave_merge;
2737
+ }
2738
+ write_author_script(message);
2739
+ find_commit_subject(message, &body);
2740
+ len = strlen(body);
2741
+ ret = write_message(body, len, git_path_merge_msg(), 0);
2742
+ unuse_commit_buffer(commit, message);
2743
+ if (ret) {
2744
+ error_errno(_("could not write '%s'"),
2745
+ git_path_merge_msg());
2746
+ goto leave_merge;
2747
+ }
2748
+ } else {
2749
+ struct strbuf buf = STRBUF_INIT;
2750
+ int len;
2751
+
2752
+ strbuf_addf(&buf, "author %s", git_author_info(0));
2753
+ write_author_script(buf.buf);
2754
+ strbuf_reset(&buf);
2755
+
2756
+ if (oneline_offset < arg_len) {
2757
+ p = arg + oneline_offset;
2758
+ len = arg_len - oneline_offset;
2759
+ } else {
2760
+ strbuf_addf(&buf, "Merge branch '%.*s'",
2761
+ merge_arg_len, arg);
2762
+ p = buf.buf;
2763
+ len = buf.len;
2764
+ }
2765
+
2766
+ ret = write_message(p, len, git_path_merge_msg(), 0);
2767
+ strbuf_release(&buf);
2768
+ if (ret) {
2769
+ error_errno(_("could not write '%s'"),
2770
+ git_path_merge_msg());
2771
+ goto leave_merge;
2772
+ }
2773
+ }
2774
+
2775
+ write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
2776
+ git_path_merge_head(), 0);
2777
+ write_message("no-ff", 5, git_path_merge_mode(), 0);
2778
+
2779
+ bases = get_merge_bases(head_commit, merge_commit);
2780
+ for (j = bases; j; j = j->next)
2781
+ commit_list_insert(j->item, &reversed);
2782
+ free_commit_list(bases);
2783
+
2784
+ read_cache();
2785
+ init_merge_options(&o);
2786
+ o.branch1 = "HEAD";
2787
+ o.branch2 = ref_name.buf;
2788
+ o.buffer_output = 2;
2789
+
2790
+ ret = merge_recursive(&o, head_commit, merge_commit, reversed, &i);
2791
+ if (ret <= 0)
2792
+ fputs(o.obuf.buf, stdout);
2793
+ strbuf_release(&o.obuf);
2794
+ if (ret < 0) {
2795
+ error(_("could not even attempt to merge '%.*s'"),
2796
+ merge_arg_len, arg);
2797
+ goto leave_merge;
2798
+ }
2799
+ /*
2800
+ * The return value of merge_recursive() is 1 on clean, and 0 on
2801
+ * unclean merge.
2802
+ *
2803
+ * Let's reverse that, so that do_merge() returns 0 upon success and
2804
+ * 1 upon failed merge (keeping the return value -1 for the cases where
2805
+ * we will want to reschedule the `merge` command).
2806
+ */
2807
+ ret = !ret;
2808
+
2809
+ if (active_cache_changed &&
2810
+ write_locked_index(&the_index, &lock, COMMIT_LOCK)) {
2811
+ ret = error(_("merge: Unable to write new index file"));
2812
+ goto leave_merge;
2813
+ }
2814
+
2815
+ rollback_lock_file(&lock);
2816
+ if (ret)
2817
+ rerere(opts->allow_rerere_auto);
2818
+ else
2819
+ /*
2820
+ * In case of problems, we now want to return a positive
2821
+ * value (a negative one would indicate that the `merge`
2822
+ * command needs to be rescheduled).
2823
+ */
2824
+ ret = !!run_git_commit(git_path_merge_msg(), opts,
2825
+ run_commit_flags);
2826
+
2827
+leave_merge:
2828
+ strbuf_release(&ref_name);
2829
+ rollback_lock_file(&lock);
2830
+ return ret;
2831
+}
2832
+
2833
static int is_final_fixup(struct todo_list *todo_list)
2834
{
2835
int i = todo_list->current;
3036
} else if (item->command == TODO_RESET) {
3037
if ((res = do_reset(item->arg, item->arg_len, opts)))
3038
reschedule = 1;
3039
+ } else if (item->command == TODO_MERGE) {
3040
+ if ((res = do_merge(item->commit,
3041
+ item->arg, item->arg_len,
3042
+ item->flags, opts)) < 0)
3043
+ reschedule = 1;
3044
+ else if (res > 0)
3045
+ /* failed with merge conflicts */
3046
+ return error_with_patch(item->commit,
3047
+ item->arg,
3048
+ item->arg_len, opts,
3049
+ res, 0);
3050
} else if (!is_noop(item->command))
3051
return error(_("unknown command %d"), item->command);
3052
3058
todo_list->current--;
3059
if (save_todo(todo_list, opts))
3060
return -1;
3061
+ if (item->commit)
3062
+ return error_with_patch(item->commit,
3063
+ item->arg,
3064
+ item->arg_len, opts,
3065
+ res, 0);
3066
}
3067
3068
todo_list->current++;
3548
short_commit_name(item->commit) :
3549
oid_to_hex(&item->commit->object.oid);
3550
3551
+ if (item->command == TODO_MERGE) {
3552
+ if (item->flags & TODO_EDIT_MERGE_MSG)
3553
+ strbuf_addstr(&buf, " -c");
3554
+ else
3555
+ strbuf_addstr(&buf, " -C");
3556
+ }
3557
+
3558
strbuf_addf(&buf, " %s", oid);
3559
}
3560
+
3561
/* add all the rest */
3562
if (!item->arg_len)
3563
strbuf_addch(&buf, '\n');