]>
Commit | Line | Data |
---|---|---|
114f5a6c RB |
1 | /* |
2 | * Copyright (C) the libgit2 contributors. All rights reserved. | |
3 | * | |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with | |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
6 | */ | |
7 | #include "common.h" | |
8 | ||
9 | #include "git2/attr.h" | |
10 | ||
11 | #include "diff.h" | |
12 | #include "diff_patch.h" | |
13 | #include "diff_driver.h" | |
14 | #include "strmap.h" | |
114f5a6c RB |
15 | #include "map.h" |
16 | #include "buf_text.h" | |
9f77b3f6 | 17 | #include "config.h" |
5dc98298 | 18 | #include "repository.h" |
114f5a6c | 19 | |
c8e02b87 | 20 | GIT__USE_STRMAP |
3eadfecd | 21 | |
114f5a6c RB |
22 | typedef enum { |
23 | DIFF_DRIVER_AUTO = 0, | |
5dc98298 RB |
24 | DIFF_DRIVER_BINARY = 1, |
25 | DIFF_DRIVER_TEXT = 2, | |
26 | DIFF_DRIVER_PATTERNLIST = 3, | |
114f5a6c RB |
27 | } git_diff_driver_t; |
28 | ||
a5a38643 RB |
29 | typedef struct { |
30 | regex_t re; | |
31 | int flags; | |
32 | } git_diff_driver_pattern; | |
33 | ||
114f5a6c | 34 | enum { |
a5a38643 | 35 | REG_NEGATE = (1 << 15) /* get out of the way of existing flags */ |
114f5a6c RB |
36 | }; |
37 | ||
38 | /* data for finding function context for a given file type */ | |
39 | struct git_diff_driver { | |
40 | git_diff_driver_t type; | |
5dc98298 RB |
41 | uint32_t binary_flags; |
42 | uint32_t other_flags; | |
a5a38643 | 43 | git_array_t(git_diff_driver_pattern) fn_patterns; |
5dc98298 | 44 | regex_t word_pattern; |
42e6cf78 | 45 | char name[GIT_FLEX_ARRAY]; |
114f5a6c RB |
46 | }; |
47 | ||
c7c260a5 | 48 | #include "userdiff.h" |
2c65602e | 49 | |
114f5a6c RB |
50 | struct git_diff_driver_registry { |
51 | git_strmap *drivers; | |
114f5a6c RB |
52 | }; |
53 | ||
5dc98298 RB |
54 | #define FORCE_DIFFABLE (GIT_DIFF_FORCE_TEXT | GIT_DIFF_FORCE_BINARY) |
55 | ||
114f5a6c | 56 | static git_diff_driver global_drivers[3] = { |
5dc98298 RB |
57 | { DIFF_DRIVER_AUTO, 0, 0, }, |
58 | { DIFF_DRIVER_BINARY, GIT_DIFF_FORCE_BINARY, 0 }, | |
59 | { DIFF_DRIVER_TEXT, GIT_DIFF_FORCE_TEXT, 0 }, | |
114f5a6c RB |
60 | }; |
61 | ||
62 | git_diff_driver_registry *git_diff_driver_registry_new() | |
63 | { | |
3eadfecd RB |
64 | git_diff_driver_registry *reg = |
65 | git__calloc(1, sizeof(git_diff_driver_registry)); | |
66 | if (!reg) | |
67 | return NULL; | |
68 | ||
40ed4990 | 69 | if (git_strmap_alloc(®->drivers) < 0) { |
3eadfecd RB |
70 | git_diff_driver_registry_free(reg); |
71 | return NULL; | |
72 | } | |
73 | ||
74 | return reg; | |
114f5a6c RB |
75 | } |
76 | ||
77 | void git_diff_driver_registry_free(git_diff_driver_registry *reg) | |
78 | { | |
5dc98298 RB |
79 | git_diff_driver *drv; |
80 | ||
3eadfecd RB |
81 | if (!reg) |
82 | return; | |
83 | ||
5dc98298 | 84 | git_strmap_foreach_value(reg->drivers, drv, git_diff_driver_free(drv)); |
3eadfecd | 85 | git_strmap_free(reg->drivers); |
114f5a6c RB |
86 | git__free(reg); |
87 | } | |
88 | ||
a5a38643 RB |
89 | static int diff_driver_add_patterns( |
90 | git_diff_driver *drv, const char *regex_str, int regex_flags) | |
5dc98298 | 91 | { |
a5a38643 RB |
92 | int error = 0; |
93 | const char *scan, *end; | |
94 | git_diff_driver_pattern *pat = NULL; | |
95 | git_buf buf = GIT_BUF_INIT; | |
96 | ||
97 | for (scan = regex_str; scan; scan = end) { | |
98 | /* get pattern to fill in */ | |
99 | if ((pat = git_array_alloc(drv->fn_patterns)) == NULL) { | |
100 | error = -1; | |
101 | break; | |
102 | } | |
5dc98298 | 103 | |
a5a38643 RB |
104 | pat->flags = regex_flags; |
105 | if (*scan == '!') { | |
106 | pat->flags |= REG_NEGATE; | |
107 | ++scan; | |
108 | } | |
109 | ||
110 | if ((end = strchr(scan, '\n')) != NULL) { | |
111 | error = git_buf_set(&buf, scan, end - scan); | |
112 | end++; | |
113 | } else { | |
114 | error = git_buf_sets(&buf, scan); | |
115 | } | |
116 | if (error < 0) | |
117 | break; | |
118 | ||
119 | if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) < 0) { | |
120 | /* if regex fails to compile, warn? fail? */ | |
121 | error = giterr_set_regex(&pat->re, error); | |
122 | regfree(&pat->re); | |
123 | break; | |
124 | } | |
5dc98298 RB |
125 | } |
126 | ||
a5a38643 RB |
127 | if (error && pat != NULL) |
128 | (void)git_array_pop(drv->fn_patterns); /* release last item */ | |
129 | git_buf_free(&buf); | |
5dc98298 | 130 | |
a5a38643 | 131 | return error; |
5dc98298 RB |
132 | } |
133 | ||
134 | static int diff_driver_xfuncname(const git_config_entry *entry, void *payload) | |
135 | { | |
a5a38643 | 136 | return diff_driver_add_patterns(payload, entry->value, REG_EXTENDED); |
5dc98298 RB |
137 | } |
138 | ||
139 | static int diff_driver_funcname(const git_config_entry *entry, void *payload) | |
140 | { | |
a5a38643 | 141 | return diff_driver_add_patterns(payload, entry->value, 0); |
5dc98298 RB |
142 | } |
143 | ||
144 | static git_diff_driver_registry *git_repository_driver_registry( | |
145 | git_repository *repo) | |
146 | { | |
147 | if (!repo->diff_drivers) { | |
148 | git_diff_driver_registry *reg = git_diff_driver_registry_new(); | |
149 | reg = git__compare_and_swap(&repo->diff_drivers, NULL, reg); | |
150 | ||
151 | if (reg != NULL) /* if we race, free losing allocation */ | |
152 | git_diff_driver_registry_free(reg); | |
153 | } | |
154 | ||
155 | if (!repo->diff_drivers) | |
156 | giterr_set(GITERR_REPOSITORY, "Unable to create diff driver registry"); | |
157 | ||
158 | return repo->diff_drivers; | |
159 | } | |
160 | ||
392702ee ET |
161 | static int diff_driver_alloc( |
162 | git_diff_driver **out, size_t *namelen_out, const char *name) | |
163 | { | |
164 | git_diff_driver *driver; | |
165 | size_t driverlen = sizeof(git_diff_driver), | |
f1453c59 ET |
166 | namelen = strlen(name), |
167 | alloclen; | |
392702ee | 168 | |
f1453c59 ET |
169 | GITERR_CHECK_ALLOC_ADD(&alloclen, driverlen, namelen); |
170 | GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1); | |
392702ee | 171 | |
f1453c59 | 172 | driver = git__calloc(1, alloclen); |
392702ee ET |
173 | GITERR_CHECK_ALLOC(driver); |
174 | ||
175 | memcpy(driver->name, name, namelen); | |
176 | ||
177 | *out = driver; | |
178 | ||
179 | if (namelen_out) | |
180 | *namelen_out = namelen; | |
181 | ||
182 | return 0; | |
183 | } | |
184 | ||
a5a38643 RB |
185 | static int git_diff_driver_builtin( |
186 | git_diff_driver **out, | |
187 | git_diff_driver_registry *reg, | |
188 | const char *driver_name) | |
189 | { | |
190 | int error = 0; | |
191 | git_diff_driver_definition *ddef = NULL; | |
192 | git_diff_driver *drv = NULL; | |
392702ee | 193 | size_t idx; |
a5a38643 RB |
194 | |
195 | for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) { | |
196 | if (!strcasecmp(driver_name, builtin_defs[idx].name)) { | |
197 | ddef = &builtin_defs[idx]; | |
198 | break; | |
199 | } | |
200 | } | |
201 | if (!ddef) | |
202 | goto done; | |
203 | ||
392702ee ET |
204 | if ((error = diff_driver_alloc(&drv, NULL, ddef->name)) < 0) |
205 | goto done; | |
a5a38643 RB |
206 | |
207 | drv->type = DIFF_DRIVER_PATTERNLIST; | |
a5a38643 RB |
208 | |
209 | if (ddef->fns && | |
210 | (error = diff_driver_add_patterns( | |
211 | drv, ddef->fns, ddef->flags | REG_EXTENDED)) < 0) | |
212 | goto done; | |
213 | ||
214 | if (ddef->words && | |
215 | (error = regcomp( | |
216 | &drv->word_pattern, ddef->words, ddef->flags | REG_EXTENDED))) | |
217 | { | |
218 | error = giterr_set_regex(&drv->word_pattern, error); | |
219 | goto done; | |
220 | } | |
221 | ||
222 | git_strmap_insert(reg->drivers, drv->name, drv, error); | |
2c65602e RB |
223 | if (error > 0) |
224 | error = 0; | |
a5a38643 RB |
225 | |
226 | done: | |
2c65602e | 227 | if (error && drv) |
a5a38643 | 228 | git_diff_driver_free(drv); |
2c65602e | 229 | else |
a5a38643 | 230 | *out = drv; |
a5a38643 RB |
231 | |
232 | return error; | |
233 | } | |
234 | ||
3eadfecd | 235 | static int git_diff_driver_load( |
5dc98298 | 236 | git_diff_driver **out, git_repository *repo, const char *driver_name) |
3eadfecd | 237 | { |
9f77b3f6 | 238 | int error = 0; |
5dc98298 | 239 | git_diff_driver_registry *reg; |
a5a38643 | 240 | git_diff_driver *drv = NULL; |
392702ee | 241 | size_t namelen; |
42e6cf78 | 242 | khiter_t pos; |
392702ee | 243 | git_config *cfg = NULL; |
5dc98298 | 244 | git_buf name = GIT_BUF_INIT; |
9f77b3f6 | 245 | const git_config_entry *ce; |
42e6cf78 | 246 | bool found_driver = false; |
5dc98298 | 247 | |
a5a38643 | 248 | if ((reg = git_repository_driver_registry(repo)) == NULL) |
5dc98298 | 249 | return -1; |
a5a38643 RB |
250 | |
251 | pos = git_strmap_lookup_index(reg->drivers, driver_name); | |
252 | if (git_strmap_valid_index(reg->drivers, pos)) { | |
253 | *out = git_strmap_value_at(reg->drivers, pos); | |
254 | return 0; | |
5dc98298 RB |
255 | } |
256 | ||
392702ee ET |
257 | if ((error = diff_driver_alloc(&drv, &namelen, driver_name)) < 0) |
258 | goto done; | |
259 | ||
a37aa82e | 260 | drv->type = DIFF_DRIVER_AUTO; |
a37aa82e | 261 | |
5dc98298 | 262 | /* if you can't read config for repo, just use default driver */ |
ac99d86b | 263 | if (git_repository_config_snapshot(&cfg, repo) < 0) { |
5dc98298 | 264 | giterr_clear(); |
a5a38643 | 265 | goto done; |
5dc98298 RB |
266 | } |
267 | ||
5dc98298 | 268 | if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0) |
54faddd2 | 269 | goto done; |
9f77b3f6 RB |
270 | |
271 | switch (git_config__get_bool_force(cfg, name.ptr, -1)) { | |
272 | case true: | |
5dc98298 | 273 | /* if diff.<driver>.binary is true, just return the binary driver */ |
5dc98298 | 274 | *out = &global_drivers[DIFF_DRIVER_BINARY]; |
54faddd2 | 275 | goto done; |
9f77b3f6 | 276 | case false: |
5dc98298 RB |
277 | /* if diff.<driver>.binary is false, force binary checks off */ |
278 | /* but still may have custom function context patterns, etc. */ | |
279 | drv->binary_flags = GIT_DIFF_FORCE_TEXT; | |
42e6cf78 | 280 | found_driver = true; |
9f77b3f6 RB |
281 | break; |
282 | default: | |
a5a38643 | 283 | /* diff.<driver>.binary unspecified or "auto", so just continue */ |
9f77b3f6 | 284 | break; |
5dc98298 RB |
285 | } |
286 | ||
287 | /* TODO: warn if diff.<name>.command or diff.<name>.textconv are set */ | |
288 | ||
42e6cf78 RB |
289 | git_buf_truncate(&name, namelen + strlen("diff..")); |
290 | git_buf_put(&name, "xfuncname", strlen("xfuncname")); | |
4efa3290 | 291 | if ((error = git_config_get_multivar_foreach( |
5dc98298 RB |
292 | cfg, name.ptr, NULL, diff_driver_xfuncname, drv)) < 0) { |
293 | if (error != GIT_ENOTFOUND) | |
54faddd2 | 294 | goto done; |
42e6cf78 | 295 | giterr_clear(); /* no diff.<driver>.xfuncname, so just continue */ |
5dc98298 | 296 | } |
3eadfecd | 297 | |
42e6cf78 RB |
298 | git_buf_truncate(&name, namelen + strlen("diff..")); |
299 | git_buf_put(&name, "funcname", strlen("funcname")); | |
4efa3290 | 300 | if ((error = git_config_get_multivar_foreach( |
5dc98298 RB |
301 | cfg, name.ptr, NULL, diff_driver_funcname, drv)) < 0) { |
302 | if (error != GIT_ENOTFOUND) | |
54faddd2 | 303 | goto done; |
42e6cf78 | 304 | giterr_clear(); /* no diff.<driver>.funcname, so just continue */ |
5dc98298 RB |
305 | } |
306 | ||
307 | /* if we found any patterns, set driver type to use correct callback */ | |
42e6cf78 | 308 | if (git_array_size(drv->fn_patterns) > 0) { |
5dc98298 | 309 | drv->type = DIFF_DRIVER_PATTERNLIST; |
42e6cf78 RB |
310 | found_driver = true; |
311 | } | |
5dc98298 | 312 | |
42e6cf78 RB |
313 | git_buf_truncate(&name, namelen + strlen("diff..")); |
314 | git_buf_put(&name, "wordregex", strlen("wordregex")); | |
9f77b3f6 | 315 | if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0) |
54faddd2 | 316 | goto done; |
9f77b3f6 RB |
317 | if (!ce || !ce->value) |
318 | /* no diff.<driver>.wordregex, so just continue */; | |
319 | else if (!(error = regcomp(&drv->word_pattern, ce->value, REG_EXTENDED))) | |
42e6cf78 | 320 | found_driver = true; |
9f77b3f6 RB |
321 | else { |
322 | /* TODO: warn about bad regex instead of failure */ | |
323 | error = giterr_set_regex(&drv->word_pattern, error); | |
324 | goto done; | |
5dc98298 RB |
325 | } |
326 | ||
327 | /* TODO: look up diff.<driver>.algorithm to turn on minimal / patience | |
328 | * diff in drv->other_flags | |
329 | */ | |
330 | ||
54faddd2 | 331 | /* if no driver config found at all, fall back on AUTO driver */ |
42e6cf78 | 332 | if (!found_driver) |
54faddd2 | 333 | goto done; |
42e6cf78 RB |
334 | |
335 | /* store driver in registry */ | |
336 | git_strmap_insert(reg->drivers, drv->name, drv, error); | |
337 | if (error < 0) | |
54faddd2 | 338 | goto done; |
2c65602e | 339 | error = 0; |
42e6cf78 | 340 | |
5dc98298 | 341 | *out = drv; |
5dc98298 | 342 | |
54faddd2 RB |
343 | done: |
344 | git_buf_free(&name); | |
29c4cb09 | 345 | git_config_free(cfg); |
54faddd2 | 346 | |
a5a38643 RB |
347 | if (!*out) { |
348 | int error2 = git_diff_driver_builtin(out, reg, driver_name); | |
349 | if (!error) | |
350 | error = error2; | |
351 | } | |
54faddd2 RB |
352 | |
353 | if (drv && drv != *out) | |
354 | git_diff_driver_free(drv); | |
355 | ||
5dc98298 | 356 | return error; |
3eadfecd RB |
357 | } |
358 | ||
114f5a6c RB |
359 | int git_diff_driver_lookup( |
360 | git_diff_driver **out, git_repository *repo, const char *path) | |
361 | { | |
3eadfecd | 362 | int error = 0; |
114f5a6c RB |
363 | const char *value; |
364 | ||
365 | assert(out); | |
2c65602e | 366 | *out = NULL; |
114f5a6c RB |
367 | |
368 | if (!repo || !path || !strlen(path)) | |
2c65602e RB |
369 | /* just use the auto value */; |
370 | else if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0) | |
371 | /* return error below */; | |
372 | else if (GIT_ATTR_UNSPECIFIED(value)) | |
42e6cf78 RB |
373 | /* just use the auto value */; |
374 | else if (GIT_ATTR_FALSE(value)) | |
5dc98298 | 375 | *out = &global_drivers[DIFF_DRIVER_BINARY]; |
42e6cf78 | 376 | else if (GIT_ATTR_TRUE(value)) |
5dc98298 | 377 | *out = &global_drivers[DIFF_DRIVER_TEXT]; |
114f5a6c RB |
378 | |
379 | /* otherwise look for driver information in config and build driver */ | |
42e6cf78 | 380 | else if ((error = git_diff_driver_load(out, repo, value)) < 0) { |
2c65602e RB |
381 | if (error == GIT_ENOTFOUND) { |
382 | error = 0; | |
3eadfecd | 383 | giterr_clear(); |
2c65602e | 384 | } |
3eadfecd | 385 | } |
114f5a6c | 386 | |
42e6cf78 RB |
387 | if (!*out) |
388 | *out = &global_drivers[DIFF_DRIVER_AUTO]; | |
389 | ||
2c65602e | 390 | return error; |
114f5a6c RB |
391 | } |
392 | ||
393 | void git_diff_driver_free(git_diff_driver *driver) | |
394 | { | |
5dc98298 RB |
395 | size_t i; |
396 | ||
397 | if (!driver) | |
398 | return; | |
399 | ||
54faddd2 | 400 | for (i = 0; i < git_array_size(driver->fn_patterns); ++i) |
a5a38643 | 401 | regfree(& git_array_get(driver->fn_patterns, i)->re); |
5dc98298 RB |
402 | git_array_clear(driver->fn_patterns); |
403 | ||
404 | regfree(&driver->word_pattern); | |
405 | ||
406 | git__free(driver); | |
114f5a6c RB |
407 | } |
408 | ||
5dc98298 RB |
409 | void git_diff_driver_update_options( |
410 | uint32_t *option_flags, git_diff_driver *driver) | |
114f5a6c | 411 | { |
5dc98298 RB |
412 | if ((*option_flags & FORCE_DIFFABLE) == 0) |
413 | *option_flags |= driver->binary_flags; | |
414 | ||
415 | *option_flags |= driver->other_flags; | |
114f5a6c RB |
416 | } |
417 | ||
418 | int git_diff_driver_content_is_binary( | |
419 | git_diff_driver *driver, const char *content, size_t content_len) | |
420 | { | |
d4cf1675 | 421 | git_buf search = GIT_BUF_INIT; |
114f5a6c RB |
422 | |
423 | GIT_UNUSED(driver); | |
424 | ||
d4cf1675 ET |
425 | git_buf_attach_notowned(&search, content, |
426 | min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL)); | |
427 | ||
114f5a6c RB |
428 | /* TODO: provide encoding / binary detection callbacks that can |
429 | * be UTF-8 aware, etc. For now, instead of trying to be smart, | |
430 | * let's just use the simple NUL-byte detection that core git uses. | |
431 | */ | |
432 | ||
433 | /* previously was: if (git_buf_text_is_binary(&search)) */ | |
434 | if (git_buf_text_contains_nul(&search)) | |
435 | return 1; | |
436 | ||
437 | return 0; | |
438 | } | |
439 | ||
5dc98298 | 440 | static int diff_context_line__simple( |
a5a38643 | 441 | git_diff_driver *driver, git_buf *line) |
5dc98298 | 442 | { |
a5a38643 | 443 | char firstch = line->ptr[0]; |
5dc98298 | 444 | GIT_UNUSED(driver); |
a5a38643 | 445 | return (git__isalpha(firstch) || firstch == '_' || firstch == '$'); |
5dc98298 RB |
446 | } |
447 | ||
448 | static int diff_context_line__pattern_match( | |
a5a38643 | 449 | git_diff_driver *driver, git_buf *line) |
5dc98298 | 450 | { |
b8e86c62 | 451 | size_t i, maxi = git_array_size(driver->fn_patterns); |
a5a38643 | 452 | regmatch_t pmatch[2]; |
5dc98298 | 453 | |
b8e86c62 | 454 | for (i = 0; i < maxi; ++i) { |
a5a38643 RB |
455 | git_diff_driver_pattern *pat = git_array_get(driver->fn_patterns, i); |
456 | ||
457 | if (!regexec(&pat->re, line->ptr, 2, pmatch, 0)) { | |
458 | if (pat->flags & REG_NEGATE) | |
459 | return false; | |
b8e86c62 RB |
460 | |
461 | /* use pmatch data to trim line data */ | |
462 | i = (pmatch[1].rm_so >= 0) ? 1 : 0; | |
463 | git_buf_consume(line, git_buf_cstr(line) + pmatch[i].rm_so); | |
464 | git_buf_truncate(line, pmatch[i].rm_eo - pmatch[i].rm_so); | |
082e82db | 465 | git_buf_rtrim(line); |
b8e86c62 | 466 | |
5dc98298 | 467 | return true; |
a5a38643 | 468 | } |
5dc98298 RB |
469 | } |
470 | ||
471 | return false; | |
472 | } | |
473 | ||
114f5a6c RB |
474 | static long diff_context_find( |
475 | const char *line, | |
476 | long line_len, | |
477 | char *out, | |
478 | long out_size, | |
479 | void *payload) | |
480 | { | |
5dc98298 | 481 | git_diff_find_context_payload *ctxt = payload; |
114f5a6c | 482 | |
5dc98298 | 483 | if (git_buf_set(&ctxt->line, line, (size_t)line_len) < 0) |
114f5a6c | 484 | return -1; |
5dc98298 | 485 | git_buf_rtrim(&ctxt->line); |
114f5a6c | 486 | |
5dc98298 | 487 | if (!ctxt->line.size) |
114f5a6c RB |
488 | return -1; |
489 | ||
a5a38643 | 490 | if (!ctxt->match_line || !ctxt->match_line(ctxt->driver, &ctxt->line)) |
5dc98298 | 491 | return -1; |
114f5a6c | 492 | |
a5f9b5f8 | 493 | if (out_size > (long)ctxt->line.size) |
584f2d30 | 494 | out_size = (long)ctxt->line.size; |
a5f9b5f8 | 495 | memcpy(out, ctxt->line.ptr, (size_t)out_size); |
114f5a6c | 496 | |
a5f9b5f8 | 497 | return out_size; |
5dc98298 | 498 | } |
114f5a6c | 499 | |
5dc98298 RB |
500 | void git_diff_find_context_init( |
501 | git_diff_find_context_fn *findfn_out, | |
502 | git_diff_find_context_payload *payload_out, | |
503 | git_diff_driver *driver) | |
504 | { | |
505 | *findfn_out = driver ? diff_context_find : NULL; | |
506 | ||
507 | memset(payload_out, 0, sizeof(*payload_out)); | |
508 | if (driver) { | |
509 | payload_out->driver = driver; | |
510 | payload_out->match_line = (driver->type == DIFF_DRIVER_PATTERNLIST) ? | |
511 | diff_context_line__pattern_match : diff_context_line__simple; | |
512 | git_buf_init(&payload_out->line, 0); | |
513 | } | |
114f5a6c RB |
514 | } |
515 | ||
5dc98298 | 516 | void git_diff_find_context_clear(git_diff_find_context_payload *payload) |
114f5a6c | 517 | { |
5dc98298 RB |
518 | if (payload) { |
519 | git_buf_free(&payload->line); | |
520 | payload->driver = NULL; | |
521 | } | |
114f5a6c RB |
522 | } |
523 |