|
1 | 1 | #include "cache.h" |
| 2 | +#include "commit-reach.h" |
2 | 3 | #include "config.h" |
3 | 4 | #include "diff.h" |
4 | 5 | #include "object-store.h" |
|
7 | 8 | #include "tag.h" |
8 | 9 | #include "graph.h" |
9 | 10 | #include "log-tree.h" |
| 11 | +#include "merge-ort.h" |
10 | 12 | #include "reflog-walk.h" |
11 | 13 | #include "refs.h" |
12 | 14 | #include "string-list.h" |
@@ -904,6 +906,51 @@ static int do_diff_combined(struct rev_info *opt, struct commit *commit) |
904 | 906 | return !opt->loginfo; |
905 | 907 | } |
906 | 908 |
|
| 909 | +static int do_remerge_diff(struct rev_info *opt, |
| 910 | + struct commit_list *parents, |
| 911 | + struct object_id *oid, |
| 912 | + struct commit *commit) |
| 913 | +{ |
| 914 | + struct merge_options o; |
| 915 | + struct commit_list *bases; |
| 916 | + struct merge_result res = {0}; |
| 917 | + struct pretty_print_context ctx = {0}; |
| 918 | + struct commit *parent1 = parents->item; |
| 919 | + struct commit *parent2 = parents->next->item; |
| 920 | + struct strbuf parent1_desc = STRBUF_INIT; |
| 921 | + struct strbuf parent2_desc = STRBUF_INIT; |
| 922 | + |
| 923 | + /* Setup merge options */ |
| 924 | + init_merge_options(&o, the_repository); |
| 925 | + o.show_rename_progress = 0; |
| 926 | + |
| 927 | + ctx.abbrev = DEFAULT_ABBREV; |
| 928 | + format_commit_message(parent1, "%h (%s)", &parent1_desc, &ctx); |
| 929 | + format_commit_message(parent2, "%h (%s)", &parent2_desc, &ctx); |
| 930 | + o.branch1 = parent1_desc.buf; |
| 931 | + o.branch2 = parent2_desc.buf; |
| 932 | + |
| 933 | + /* Parse the relevant commits and get the merge bases */ |
| 934 | + parse_commit_or_die(parent1); |
| 935 | + parse_commit_or_die(parent2); |
| 936 | + bases = get_merge_bases(parent1, parent2); |
| 937 | + |
| 938 | + /* Re-merge the parents */ |
| 939 | + merge_incore_recursive(&o, bases, parent1, parent2, &res); |
| 940 | + |
| 941 | + /* Show the diff */ |
| 942 | + diff_tree_oid(&res.tree->object.oid, oid, "", &opt->diffopt); |
| 943 | + log_tree_diff_flush(opt); |
| 944 | + |
| 945 | + /* Cleanup */ |
| 946 | + strbuf_release(&parent1_desc); |
| 947 | + strbuf_release(&parent2_desc); |
| 948 | + merge_finalize(&o, &res); |
| 949 | + /* TODO: clean up the temporary object directory */ |
| 950 | + |
| 951 | + return !opt->loginfo; |
| 952 | +} |
| 953 | + |
907 | 954 | /* |
908 | 955 | * Show the diff of a commit. |
909 | 956 | * |
@@ -938,6 +985,18 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log |
938 | 985 | } |
939 | 986 |
|
940 | 987 | if (is_merge) { |
| 988 | + int octopus = (parents->next->next != NULL); |
| 989 | + |
| 990 | + if (opt->remerge_diff) { |
| 991 | + if (octopus) { |
| 992 | + show_log(opt); |
| 993 | + fprintf(opt->diffopt.file, |
| 994 | + "diff: warning: Skipping remerge-diff " |
| 995 | + "for octopus merges.\n"); |
| 996 | + return 1; |
| 997 | + } |
| 998 | + return do_remerge_diff(opt, parents, oid, commit); |
| 999 | + } |
941 | 1000 | if (opt->combine_merges) |
942 | 1001 | return do_diff_combined(opt, commit); |
943 | 1002 | if (opt->separate_merges) { |
|
0 commit comments