1 /*
2  * ggit-merge-options.c
3  * This file is part of libgit2-glib
4  *
5  * Copyright (C) 2013 - Ignacio Casal Quinteiro
6  *
7  * libgit2-glib is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * libgit2-glib is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with libgit2-glib. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "ggit-merge-options.h"
22 #include "ggit-diff-similarity-metric.h"
23 
24 struct _GgitMergeOptions
25 {
26 	GgitDiffSimilarityMetric *metric;
27 	git_merge_options merge_options;
28 };
29 
G_DEFINE_BOXED_TYPE(GgitMergeOptions,ggit_merge_options,ggit_merge_options_copy,ggit_merge_options_free)30 G_DEFINE_BOXED_TYPE (GgitMergeOptions, ggit_merge_options,
31                      ggit_merge_options_copy, ggit_merge_options_free)
32 
33 const git_merge_options *
34 _ggit_merge_options_get_merge_options (GgitMergeOptions *merge_options)
35 {
36 	/* NULL is common for merge_options as it specifies to use the default
37 	 * so handle a NULL merge_options here instead of in every caller.
38 	 */
39 	if (merge_options == NULL)
40 	{
41 		return NULL;
42 	}
43 
44 	return (const git_merge_options *)&merge_options->merge_options;
45 }
46 
47 /**
48  * ggit_merge_options_copy:
49  * @merge_options: a #GgitMergeOptions.
50  *
51  * Copies @merge_options into a newly allocated #GgitMergeOptions.
52  *
53  * Returns: (transfer full) (nullable): a newly allocated #GgitMergeOptions or %NULL.
54  */
55 GgitMergeOptions *
ggit_merge_options_copy(GgitMergeOptions * merge_options)56 ggit_merge_options_copy (GgitMergeOptions *merge_options)
57 {
58 	GgitMergeOptions *new_merge_options;
59 
60 	g_return_val_if_fail (merge_options != NULL, NULL);
61 
62 	new_merge_options = g_slice_new0 (GgitMergeOptions);
63 	new_merge_options->merge_options = merge_options->merge_options;
64 
65 	new_merge_options->merge_options.metric = NULL;
66 	ggit_merge_options_set_similarity_metric (new_merge_options, merge_options->metric);
67 
68 	return new_merge_options;
69 }
70 
71 /**
72  * ggit_merge_options_free:
73  * @merge_options: a #GgitMergeOptions.
74  *
75  * Frees @merge_options.
76  */
77 void
ggit_merge_options_free(GgitMergeOptions * merge_options)78 ggit_merge_options_free (GgitMergeOptions *merge_options)
79 {
80 	g_return_if_fail (merge_options != NULL);
81 
82 	if (merge_options->metric != NULL)
83 	{
84 		ggit_diff_similarity_metric_free (merge_options->metric);
85 		merge_options->metric = NULL;
86 	}
87 
88 	g_slice_free (GgitMergeOptions, merge_options);
89 }
90 
91 /**
92  * ggit_merge_options_new:
93  *
94  * Creates a new #GgitMergeOptions.
95  *
96  * Returns: a newly allocated #GgitMergeOptions.
97  */
98 GgitMergeOptions *
ggit_merge_options_new(void)99 ggit_merge_options_new (void)
100 {
101 	GgitMergeOptions *merge_options;
102 	git_merge_options gmerge_options = GIT_MERGE_OPTIONS_INIT;
103 
104 	merge_options = g_slice_new0 (GgitMergeOptions);
105 	merge_options->merge_options = gmerge_options;
106 
107 	return merge_options;
108 }
109 
110 /**
111  * ggit_merge_options_set_tree_flags:
112  * @merge_options: a #GgitMergeOptions.
113  * @flags: the flags.
114  *
115  * Set the flags to use for merging.
116  *
117  **/
118 void
ggit_merge_options_set_flags(GgitMergeOptions * merge_options,GgitMergeFlags flags)119 ggit_merge_options_set_flags (GgitMergeOptions   *merge_options,
120                               GgitMergeFlags      flags)
121 {
122 	g_return_if_fail (merge_options != NULL);
123 	merge_options->merge_options.flags = (git_merge_flag_t)flags;
124 }
125 
126 /**
127  * ggit_merge_options_get_flags:
128  * @merge_options: a #GgitMergeOptions.
129  *
130  * Get the tree flags to use for merging.
131  *
132  * Returns: the flags.
133  *
134  **/
135 GgitMergeFlags
ggit_merge_options_get_flags(GgitMergeOptions * merge_options)136 ggit_merge_options_get_flags (GgitMergeOptions *merge_options)
137 {
138 	g_return_val_if_fail (merge_options != NULL, 0);
139 	return (GgitMergeFlags)merge_options->merge_options.flags;
140 }
141 
142 /**
143  * ggit_merge_options_set_rename_threshold:
144  * @merge_options: a #GgitMergeOptions.
145  * @rename_threshold: similarity to consider a file renamed.
146  *
147  * Set the rename threshold (defaults to 50). If %GGIT_MERGE_TREE_FIND_RENAMES
148  * is enabled, added files will be compared with deleted files to
149  * determine their similarity. Files that are more similar than the rename
150  * threshold (percentage-wise) will be treated as a rename.
151  *
152  **/
153 void
ggit_merge_options_set_rename_threshold(GgitMergeOptions * merge_options,guint rename_threshold)154 ggit_merge_options_set_rename_threshold (GgitMergeOptions *merge_options,
155                                          guint             rename_threshold)
156 {
157 	g_return_if_fail (merge_options != NULL);
158 	merge_options->merge_options.rename_threshold = rename_threshold;
159 }
160 
161 /**
162  * ggit_merge_options_get_rename_threshold:
163  * @merge_options: a #GgitMergeOptions.
164  *
165  * Get the rename threshold (defaults to 50). If %GGIT_MERGE_TREE_FIND_RENAMES
166  * is enabled, added files will be compared with deleted files to
167  * determine their similarity. Files that are more similar than the rename
168  * threshold (percentage-wise) will be treated as a rename.
169  *
170  * Returns: the rename threshold.
171  *
172  **/
173 guint
ggit_merge_options_get_rename_threshold(GgitMergeOptions * merge_options)174 ggit_merge_options_get_rename_threshold (GgitMergeOptions *merge_options)
175 {
176 	g_return_val_if_fail (merge_options != NULL, 0);
177 	return merge_options->merge_options.rename_threshold;
178 }
179 
180 /**
181  * ggit_merge_options_set_target_limit:
182  * @merge_options: a #GgitMergeOptions.
183  * @target_limit: maximum similarity source to examine for renames.
184  *
185  * Set the maximum number of similarity sources to examine for renames (defaults to 200).
186  * If the number of rename candidates (add / delete pairs) is greater than
187  * this value, inexact rename detection is aborted.
188  *
189  **/
190 void
ggit_merge_options_set_target_limit(GgitMergeOptions * merge_options,guint target_limit)191 ggit_merge_options_set_target_limit (GgitMergeOptions *merge_options,
192                                      guint             target_limit)
193 {
194 	g_return_if_fail (merge_options != NULL);
195 	merge_options->merge_options.target_limit = target_limit;
196 }
197 
198 /**
199  * ggit_merge_options_get_target_limit:
200  * @merge_options: a #GgitMergeOptions.
201  *
202  * Get the maximum number of similarity sources to examine for renames (defaults to 200).
203  * If the number of rename candidates (add / delete pairs) is greater than
204  * this value, inexact rename detection is aborted.
205  *
206  * Returns: the target limit.
207  *
208  **/
209 guint
ggit_merge_options_get_target_limit(GgitMergeOptions * merge_options)210 ggit_merge_options_get_target_limit (GgitMergeOptions *merge_options)
211 {
212 	g_return_val_if_fail (merge_options != NULL, 0);
213 	return merge_options->merge_options.target_limit;
214 }
215 
216 /**
217  * ggit_merge_options_set_similarity_metric:
218  * @merge_options: a #GgitMergeOptions.
219  * @metric: a #GgitSimilarityMetric.
220  *
221  * Set the similarity metric, or %NULL for the default similarity metric.
222  *
223  **/
224 void
ggit_merge_options_set_similarity_metric(GgitMergeOptions * merge_options,GgitDiffSimilarityMetric * metric)225 ggit_merge_options_set_similarity_metric (GgitMergeOptions         *merge_options,
226                                           GgitDiffSimilarityMetric *metric)
227 {
228 	g_return_if_fail (merge_options != NULL);
229 
230 	if (merge_options->metric)
231 	{
232 		ggit_diff_similarity_metric_free (merge_options->metric);
233 	}
234 
235 	merge_options->metric = metric != NULL ? ggit_diff_similarity_metric_copy (metric) : NULL;
236 	merge_options->merge_options.metric = _ggit_diff_similarity_metric_get_similarity_metric (metric);
237 }
238 
239 /**
240  * ggit_merge_options_get_similarity_metric:
241  * @merge_options: a #GgitMergeOptions.
242  *
243  * Get the similarity metric.
244  *
245  * Returns: (transfer none) (nullable): the similarity metric, or %NULL.
246  *
247  **/
248 GgitDiffSimilarityMetric *
ggit_merge_options_get_similarity_metric(GgitMergeOptions * merge_options)249 ggit_merge_options_get_similarity_metric (GgitMergeOptions *merge_options)
250 {
251 	g_return_val_if_fail (merge_options != NULL, NULL);
252 	return merge_options->metric;
253 }
254 
255 /**
256  * ggit_merge_options_set_file_favor:
257  * @merge_options: a #GgitMergeOptions.
258  * @file_favor: the file favor.
259  *
260  * Set flags for handling conflicting content.
261  *
262  **/
263 void
ggit_merge_options_set_file_favor(GgitMergeOptions * merge_options,GgitMergeFileFavor file_favor)264 ggit_merge_options_set_file_favor (GgitMergeOptions   *merge_options,
265                                    GgitMergeFileFavor  file_favor)
266 {
267 	g_return_if_fail (merge_options != NULL);
268 	merge_options->merge_options.file_favor = (git_merge_file_favor_t)file_favor;
269 }
270 
271 /**
272  * ggit_merge_options_get_file_favor:
273  * @merge_options: a #GgitMergeOptions.
274  *
275  * Get flags for handling conflicting content.
276  *
277  * Returns: the file favor.
278  *
279  **/
280 GgitMergeFileFavor
ggit_merge_options_get_file_favor(GgitMergeOptions * merge_options)281 ggit_merge_options_get_file_favor (GgitMergeOptions *merge_options)
282 {
283 	g_return_val_if_fail (merge_options != NULL, 0);
284 	return (GgitMergeFileFavor)merge_options->merge_options.file_favor;
285 }
286 
287 /**
288  * ggit_merge_options_set_file_flags:
289  * @merge_options: a #GgitMergeOptions.
290  * @file_flags: the file flags.
291  *
292  * Set file merging flags.
293  *
294  **/
295 void
ggit_merge_options_set_file_flags(GgitMergeOptions * merge_options,GgitMergeFileFlags file_flags)296 ggit_merge_options_set_file_flags (GgitMergeOptions   *merge_options,
297                                    GgitMergeFileFlags  file_flags)
298 {
299 	g_return_if_fail (merge_options != NULL);
300 	merge_options->merge_options.file_flags = (git_merge_file_flag_t)file_flags;
301 }
302 
303 /**
304  * ggit_merge_options_get_file_flags:
305  * @merge_options: a #GgitMergeOptions.
306  *
307  * Get file merging flags.
308  *
309  * Returns: the file merging flags.
310  *
311  **/
312 GgitMergeFileFlags
ggit_merge_options_get_file_flags(GgitMergeOptions * merge_options)313 ggit_merge_options_get_file_flags (GgitMergeOptions *merge_options)
314 {
315 	g_return_val_if_fail (merge_options != NULL, 0);
316 	return (GgitMergeFileFlags)merge_options->merge_options.file_flags;
317 }
318 
319 /* ex:set ts=8 noet: */
320