]> git.ipfire.org Git - thirdparty/git.git/blob - diff-merges.c
hash-ll.h: split out of hash.h to remove dependency on repository.h
[thirdparty/git.git] / diff-merges.c
1 #include "git-compat-util.h"
2 #include "diff-merges.h"
3
4 #include "gettext.h"
5 #include "revision.h"
6
7 typedef void (*diff_merges_setup_func_t)(struct rev_info *);
8 static void set_separate(struct rev_info *revs);
9
10 static diff_merges_setup_func_t set_to_default = set_separate;
11 static int suppress_m_parsing;
12
13 static void suppress(struct rev_info *revs)
14 {
15 revs->separate_merges = 0;
16 revs->first_parent_merges = 0;
17 revs->combine_merges = 0;
18 revs->dense_combined_merges = 0;
19 revs->combined_all_paths = 0;
20 revs->merges_imply_patch = 0;
21 revs->merges_need_diff = 0;
22 revs->remerge_diff = 0;
23 }
24
25 static void common_setup(struct rev_info *revs)
26 {
27 suppress(revs);
28 revs->merges_need_diff = 1;
29 }
30
31 static void set_none(struct rev_info *revs)
32 {
33 suppress(revs);
34 }
35
36 static void set_separate(struct rev_info *revs)
37 {
38 common_setup(revs);
39 revs->separate_merges = 1;
40 revs->simplify_history = 0;
41 }
42
43 static void set_first_parent(struct rev_info *revs)
44 {
45 set_separate(revs);
46 revs->first_parent_merges = 1;
47 }
48
49 static void set_combined(struct rev_info *revs)
50 {
51 common_setup(revs);
52 revs->combine_merges = 1;
53 revs->dense_combined_merges = 0;
54 }
55
56 static void set_dense_combined(struct rev_info *revs)
57 {
58 common_setup(revs);
59 revs->combine_merges = 1;
60 revs->dense_combined_merges = 1;
61 }
62
63 static void set_remerge_diff(struct rev_info *revs)
64 {
65 common_setup(revs);
66 revs->remerge_diff = 1;
67 revs->simplify_history = 0;
68 }
69
70 static diff_merges_setup_func_t func_by_opt(const char *optarg)
71 {
72 if (!strcmp(optarg, "off") || !strcmp(optarg, "none"))
73 return set_none;
74 if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent"))
75 return set_first_parent;
76 if (!strcmp(optarg, "separate"))
77 return set_separate;
78 if (!strcmp(optarg, "c") || !strcmp(optarg, "combined"))
79 return set_combined;
80 if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined"))
81 return set_dense_combined;
82 if (!strcmp(optarg, "r") || !strcmp(optarg, "remerge"))
83 return set_remerge_diff;
84 if (!strcmp(optarg, "m") || !strcmp(optarg, "on"))
85 return set_to_default;
86 return NULL;
87 }
88
89 static void set_diff_merges(struct rev_info *revs, const char *optarg)
90 {
91 diff_merges_setup_func_t func = func_by_opt(optarg);
92
93 if (!func)
94 die(_("invalid value for '%s': '%s'"), "--diff-merges", optarg);
95
96 func(revs);
97 }
98
99 /*
100 * Public functions. They are in the order they are called.
101 */
102
103 int 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
114 void diff_merges_suppress_m_parsing(void)
115 {
116 suppress_m_parsing = 1;
117 }
118
119 int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
120 {
121 int argcount = 1;
122 const char *optarg;
123 const char *arg = argv[0];
124
125 if (!suppress_m_parsing && !strcmp(arg, "-m")) {
126 set_to_default(revs);
127 revs->merges_need_diff = 0;
128 } else if (!strcmp(arg, "-c")) {
129 set_combined(revs);
130 revs->merges_imply_patch = 1;
131 } else if (!strcmp(arg, "--cc")) {
132 set_dense_combined(revs);
133 revs->merges_imply_patch = 1;
134 } else if (!strcmp(arg, "--remerge-diff")) {
135 set_remerge_diff(revs);
136 revs->merges_imply_patch = 1;
137 } else if (!strcmp(arg, "--no-diff-merges")) {
138 set_none(revs);
139 } else if (!strcmp(arg, "--combined-all-paths")) {
140 revs->combined_all_paths = 1;
141 } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) {
142 set_diff_merges(revs, optarg);
143 } else
144 return 0;
145
146 revs->explicit_diff_merges = 1;
147 return argcount;
148 }
149
150 void diff_merges_suppress(struct rev_info *revs)
151 {
152 set_none(revs);
153 }
154
155 void diff_merges_default_to_first_parent(struct rev_info *revs)
156 {
157 if (!revs->explicit_diff_merges)
158 revs->separate_merges = 1;
159 if (revs->separate_merges)
160 revs->first_parent_merges = 1;
161 }
162
163 void diff_merges_default_to_dense_combined(struct rev_info *revs)
164 {
165 if (!revs->explicit_diff_merges)
166 set_dense_combined(revs);
167 }
168
169 void diff_merges_set_dense_combined_if_unset(struct rev_info *revs)
170 {
171 if (!revs->combine_merges)
172 set_dense_combined(revs);
173 }
174
175 void diff_merges_setup_revs(struct rev_info *revs)
176 {
177 if (revs->combine_merges == 0)
178 revs->dense_combined_merges = 0;
179 if (revs->separate_merges == 0)
180 revs->first_parent_merges = 0;
181 if (revs->combined_all_paths && !revs->combine_merges)
182 die("--combined-all-paths makes no sense without -c or --cc");
183 if (revs->merges_imply_patch)
184 revs->diff = 1;
185 if (revs->merges_imply_patch || revs->merges_need_diff) {
186 if (!revs->diffopt.output_format)
187 revs->diffopt.output_format = DIFF_FORMAT_PATCH;
188 }
189 }