blob: 45507588a2797b8d3618e3a19a2854d12051157b [file] [log] [blame]
Elijah Newren8bff5ca2023-02-24 00:09:20 +00001#include "git-compat-util.h"
Sergey Organova37eec62020-12-21 18:19:33 +03002#include "diff-merges.h"
3
Elijah Newrena64215b2023-02-24 00:09:30 +00004#include "gettext.h"
Sergey Organova37eec62020-12-21 18:19:33 +03005#include "revision.h"
6
Sergey Organov43208152021-04-13 14:41:14 +03007typedef void (*diff_merges_setup_func_t)(struct rev_info *);
8static void set_separate(struct rev_info *revs);
9
10static diff_merges_setup_func_t set_to_default = set_separate;
Sergey Organov5acffd32021-09-01 19:52:20 +030011static int suppress_m_parsing;
Sergey Organov43208152021-04-13 14:41:14 +030012
Sergey Organov09322b12020-12-21 18:19:38 +030013static void suppress(struct rev_info *revs)
14{
Sergey Organov1a2c4d82020-12-21 18:19:46 +030015 revs->separate_merges = 0;
Sergey Organov09322b12020-12-21 18:19:38 +030016 revs->first_parent_merges = 0;
17 revs->combine_merges = 0;
18 revs->dense_combined_merges = 0;
Sergey Organov255a4da2020-12-21 18:19:50 +030019 revs->combined_all_paths = 0;
Sergey Organovfd16a392021-05-21 00:47:02 +030020 revs->merges_imply_patch = 0;
Sergey Organova6d19ec2020-12-21 18:19:53 +030021 revs->merges_need_diff = 0;
Elijah Newrendb757e82022-02-02 02:37:28 +000022 revs->remerge_diff = 0;
Sergey Organov09322b12020-12-21 18:19:38 +030023}
24
Sergey Organov563005e2022-09-14 22:31:01 +030025static void common_setup(struct rev_info *revs)
Sergey Organov3d2b5f22020-12-21 18:19:49 +030026{
27 suppress(revs);
Sergey Organov563005e2022-09-14 22:31:01 +030028 revs->merges_need_diff = 1;
29}
30
31static void set_none(struct rev_info *revs)
32{
33 suppress(revs);
34}
35
36static void set_separate(struct rev_info *revs)
37{
38 common_setup(revs);
Sergey Organov3d2b5f22020-12-21 18:19:49 +030039 revs->separate_merges = 1;
Elijah Newren0dec3222022-02-02 02:37:37 +000040 revs->simplify_history = 0;
Sergey Organov3d2b5f22020-12-21 18:19:49 +030041}
42
Sergey Organov8c0ba522020-12-21 18:19:51 +030043static void set_first_parent(struct rev_info *revs)
44{
45 set_separate(revs);
46 revs->first_parent_merges = 1;
47}
48
Sergey Organov3d2b5f22020-12-21 18:19:49 +030049static void set_combined(struct rev_info *revs)
50{
Sergey Organov563005e2022-09-14 22:31:01 +030051 common_setup(revs);
Sergey Organov3d2b5f22020-12-21 18:19:49 +030052 revs->combine_merges = 1;
53 revs->dense_combined_merges = 0;
54}
55
Sergey Organov3b6c17b2020-12-21 18:19:39 +030056static void set_dense_combined(struct rev_info *revs)
57{
Sergey Organov563005e2022-09-14 22:31:01 +030058 common_setup(revs);
Sergey Organov3b6c17b2020-12-21 18:19:39 +030059 revs->combine_merges = 1;
60 revs->dense_combined_merges = 1;
61}
62
Elijah Newrendb757e82022-02-02 02:37:28 +000063static void set_remerge_diff(struct rev_info *revs)
64{
Sergey Organov563005e2022-09-14 22:31:01 +030065 common_setup(revs);
Elijah Newrendb757e82022-02-02 02:37:28 +000066 revs->remerge_diff = 1;
Elijah Newren0dec3222022-02-02 02:37:37 +000067 revs->simplify_history = 0;
Elijah Newrendb757e82022-02-02 02:37:28 +000068}
69
Sergey Organov26a0f582021-04-13 14:41:15 +030070static diff_merges_setup_func_t func_by_opt(const char *optarg)
71{
72 if (!strcmp(optarg, "off") || !strcmp(optarg, "none"))
Sergey Organov563005e2022-09-14 22:31:01 +030073 return set_none;
Sergey Organov26a0f582021-04-13 14:41:15 +030074 if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent"))
75 return set_first_parent;
Sergey Organovc7c4f762022-09-14 22:31:00 +030076 if (!strcmp(optarg, "separate"))
Sergey Organov26a0f582021-04-13 14:41:15 +030077 return set_separate;
Sergey Organovc7c4f762022-09-14 22:31:00 +030078 if (!strcmp(optarg, "c") || !strcmp(optarg, "combined"))
Sergey Organov26a0f582021-04-13 14:41:15 +030079 return set_combined;
Sergey Organovc7c4f762022-09-14 22:31:00 +030080 if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined"))
Sergey Organov26a0f582021-04-13 14:41:15 +030081 return set_dense_combined;
Sergey Organovc7c4f762022-09-14 22:31:00 +030082 if (!strcmp(optarg, "r") || !strcmp(optarg, "remerge"))
Elijah Newrendb757e82022-02-02 02:37:28 +000083 return set_remerge_diff;
Sergey Organovc7c4f762022-09-14 22:31:00 +030084 if (!strcmp(optarg, "m") || !strcmp(optarg, "on"))
Sergey Organov26a0f582021-04-13 14:41:15 +030085 return set_to_default;
86 return NULL;
87}
88
Sergey Organov3d2b5f22020-12-21 18:19:49 +030089static void set_diff_merges(struct rev_info *revs, const char *optarg)
90{
Sergey Organov26a0f582021-04-13 14:41:15 +030091 diff_merges_setup_func_t func = func_by_opt(optarg);
Sergey Organova6d19ec2020-12-21 18:19:53 +030092
Sergey Organov26a0f582021-04-13 14:41:15 +030093 if (!func)
Jean-Noël Avila1a8aea82022-01-31 22:07:47 +000094 die(_("invalid value for '%s': '%s'"), "--diff-merges", optarg);
Sergey Organova6d19ec2020-12-21 18:19:53 +030095
Sergey Organov26a0f582021-04-13 14:41:15 +030096 func(revs);
Sergey Organov3d2b5f22020-12-21 18:19:49 +030097}
Sergey Organov3b6c17b2020-12-21 18:19:39 +030098
Sergey Organov564a4fc2020-12-21 18:19:37 +030099/*
100 * Public functions. They are in the order they are called.
101 */
102
Sergey Organov17c13e62021-04-13 14:41:17 +0300103int diff_merges_config(const char *value)
104{
105 diff_merges_setup_func_t func = func_by_opt(value);
106
107 if (!func)
108 return -1;
109
110 set_to_default = func;
111 return 0;
112}
113
Sergey Organov5acffd32021-09-01 19:52:20 +0300114void diff_merges_suppress_m_parsing(void)
Sergey Organov19b25172021-05-21 00:46:59 +0300115{
Sergey Organov5acffd32021-09-01 19:52:20 +0300116 suppress_m_parsing = 1;
Sergey Organov19b25172021-05-21 00:46:59 +0300117}
118
Sergey Organov18f09472020-12-21 18:19:34 +0300119int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
Sergey Organova37eec62020-12-21 18:19:33 +0300120{
121 int argcount = 1;
122 const char *optarg;
123 const char *arg = argv[0];
124
Sergey Organov5acffd32021-09-01 19:52:20 +0300125 if (!suppress_m_parsing && !strcmp(arg, "-m")) {
Sergey Organov19b25172021-05-21 00:46:59 +0300126 set_to_default(revs);
Sergey Organov563005e2022-09-14 22:31:01 +0300127 revs->merges_need_diff = 0;
Sergey Organov5733b202020-12-21 18:19:52 +0300128 } else if (!strcmp(arg, "-c")) {
Sergey Organov3d2b5f22020-12-21 18:19:49 +0300129 set_combined(revs);
Sergey Organovfd16a392021-05-21 00:47:02 +0300130 revs->merges_imply_patch = 1;
Sergey Organov5733b202020-12-21 18:19:52 +0300131 } else if (!strcmp(arg, "--cc")) {
Sergey Organov3b6c17b2020-12-21 18:19:39 +0300132 set_dense_combined(revs);
Sergey Organovfd16a392021-05-21 00:47:02 +0300133 revs->merges_imply_patch = 1;
Sergey Organovc8e5cb02023-10-09 19:05:34 +0300134 } else if (!strcmp(arg, "--dd")) {
135 set_first_parent(revs);
136 revs->merges_imply_patch = 1;
Elijah Newrendb757e82022-02-02 02:37:28 +0000137 } else if (!strcmp(arg, "--remerge-diff")) {
138 set_remerge_diff(revs);
139 revs->merges_imply_patch = 1;
Sergey Organov5733b202020-12-21 18:19:52 +0300140 } else if (!strcmp(arg, "--no-diff-merges")) {
Sergey Organov563005e2022-09-14 22:31:01 +0300141 set_none(revs);
Sergey Organov5733b202020-12-21 18:19:52 +0300142 } else if (!strcmp(arg, "--combined-all-paths")) {
Sergey Organova37eec62020-12-21 18:19:33 +0300143 revs->combined_all_paths = 1;
Sergey Organov5733b202020-12-21 18:19:52 +0300144 } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) {
Sergey Organov3d2b5f22020-12-21 18:19:49 +0300145 set_diff_merges(revs, optarg);
Sergey Organov5733b202020-12-21 18:19:52 +0300146 } else
Sergey Organov1a2c4d82020-12-21 18:19:46 +0300147 return 0;
Sergey Organova37eec62020-12-21 18:19:33 +0300148
Sergey Organov1a2c4d82020-12-21 18:19:46 +0300149 revs->explicit_diff_merges = 1;
Sergey Organova37eec62020-12-21 18:19:33 +0300150 return argcount;
151}
152
Sergey Organov09322b12020-12-21 18:19:38 +0300153void diff_merges_suppress(struct rev_info *revs)
154{
Sergey Organov563005e2022-09-14 22:31:01 +0300155 set_none(revs);
Sergey Organov09322b12020-12-21 18:19:38 +0300156}
157
Sergey Organov4f545442020-12-21 18:19:36 +0300158void diff_merges_default_to_first_parent(struct rev_info *revs)
Sergey Organova37eec62020-12-21 18:19:33 +0300159{
Sergey Organov1a2c4d82020-12-21 18:19:46 +0300160 if (!revs->explicit_diff_merges)
161 revs->separate_merges = 1;
162 if (revs->separate_merges)
Sergey Organov3291eea2020-12-21 18:19:40 +0300163 revs->first_parent_merges = 1;
Sergey Organova37eec62020-12-21 18:19:33 +0300164}
165
Sergey Organov18f09472020-12-21 18:19:34 +0300166void diff_merges_default_to_dense_combined(struct rev_info *revs)
Sergey Organova37eec62020-12-21 18:19:33 +0300167{
Sergey Organov1a2c4d82020-12-21 18:19:46 +0300168 if (!revs->explicit_diff_merges)
169 set_dense_combined(revs);
Sergey Organova37eec62020-12-21 18:19:33 +0300170}
Sergey Organov564a4fc2020-12-21 18:19:37 +0300171
Sergey Organov3b6c17b2020-12-21 18:19:39 +0300172void diff_merges_set_dense_combined_if_unset(struct rev_info *revs)
173{
174 if (!revs->combine_merges)
175 set_dense_combined(revs);
176}
177
Sergey Organov564a4fc2020-12-21 18:19:37 +0300178void diff_merges_setup_revs(struct rev_info *revs)
179{
Sergey Organov1a2c4d82020-12-21 18:19:46 +0300180 if (revs->combine_merges == 0)
181 revs->dense_combined_merges = 0;
182 if (revs->separate_merges == 0)
183 revs->first_parent_merges = 0;
Sergey Organov564a4fc2020-12-21 18:19:37 +0300184 if (revs->combined_all_paths && !revs->combine_merges)
185 die("--combined-all-paths makes no sense without -c or --cc");
Sergey Organovfd16a392021-05-21 00:47:02 +0300186 if (revs->merges_imply_patch)
Sergey Organove121b4b2020-12-21 18:19:42 +0300187 revs->diff = 1;
Sergey Organovfd16a392021-05-21 00:47:02 +0300188 if (revs->merges_imply_patch || revs->merges_need_diff) {
Sergey Organov0c627f52020-12-21 18:19:41 +0300189 if (!revs->diffopt.output_format)
190 revs->diffopt.output_format = DIFF_FORMAT_PATCH;
191 }
Sergey Organov564a4fc2020-12-21 18:19:37 +0300192}