]>
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 | */ | |
eae0bfdc PP |
7 | |
8 | #include "diff_file.h" | |
9 | ||
114f5a6c RB |
10 | #include "git2/blob.h" |
11 | #include "git2/submodule.h" | |
12 | #include "diff.h" | |
9be638ec | 13 | #include "diff_generate.h" |
114f5a6c | 14 | #include "odb.h" |
22a2d3d5 | 15 | #include "futils.h" |
114f5a6c RB |
16 | #include "filter.h" |
17 | ||
18 | #define DIFF_MAX_FILESIZE 0x20000000 | |
19 | ||
20 | static bool diff_file_content_binary_by_size(git_diff_file_content *fc) | |
21 | { | |
22 | /* if we have diff opts, check max_size vs file size */ | |
74ded024 | 23 | if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) == 0 && |
5dc98298 | 24 | fc->opts_max_size > 0 && |
74ded024 RB |
25 | fc->file->size > fc->opts_max_size) |
26 | fc->file->flags |= GIT_DIFF_FLAG_BINARY; | |
114f5a6c | 27 | |
74ded024 | 28 | return ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0); |
114f5a6c RB |
29 | } |
30 | ||
31 | static void diff_file_content_binary_by_content(git_diff_file_content *fc) | |
32 | { | |
74ded024 | 33 | if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) != 0) |
114f5a6c RB |
34 | return; |
35 | ||
36 | switch (git_diff_driver_content_is_binary( | |
37 | fc->driver, fc->map.data, fc->map.len)) { | |
74ded024 RB |
38 | case 0: fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY; break; |
39 | case 1: fc->file->flags |= GIT_DIFF_FLAG_BINARY; break; | |
114f5a6c RB |
40 | default: break; |
41 | } | |
42 | } | |
43 | ||
5dc98298 RB |
44 | static int diff_file_content_init_common( |
45 | git_diff_file_content *fc, const git_diff_options *opts) | |
114f5a6c | 46 | { |
5dc98298 RB |
47 | fc->opts_flags = opts ? opts->flags : GIT_DIFF_NORMAL; |
48 | ||
49 | if (opts && opts->max_size >= 0) | |
50 | fc->opts_max_size = opts->max_size ? | |
51 | opts->max_size : DIFF_MAX_FILESIZE; | |
114f5a6c | 52 | |
22a2d3d5 UG |
53 | if (fc->src == GIT_ITERATOR_EMPTY) |
54 | fc->src = GIT_ITERATOR_TREE; | |
74ded024 RB |
55 | |
56 | if (!fc->driver && | |
eae0bfdc PP |
57 | git_diff_driver_lookup(&fc->driver, fc->repo, |
58 | NULL, fc->file->path) < 0) | |
74ded024 | 59 | return -1; |
114f5a6c | 60 | |
5dc98298 RB |
61 | /* give driver a chance to modify options */ |
62 | git_diff_driver_update_options(&fc->opts_flags, fc->driver); | |
63 | ||
114f5a6c | 64 | /* make sure file is conceivable mmap-able */ |
22a2d3d5 | 65 | if ((size_t)fc->file->size != fc->file->size) |
74ded024 | 66 | fc->file->flags |= GIT_DIFF_FLAG_BINARY; |
5dc98298 RB |
67 | /* check if user is forcing text diff the file */ |
68 | else if (fc->opts_flags & GIT_DIFF_FORCE_TEXT) { | |
74ded024 RB |
69 | fc->file->flags &= ~GIT_DIFF_FLAG_BINARY; |
70 | fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY; | |
5dc98298 RB |
71 | } |
72 | /* check if user is forcing binary diff the file */ | |
73 | else if (fc->opts_flags & GIT_DIFF_FORCE_BINARY) { | |
74ded024 RB |
74 | fc->file->flags &= ~GIT_DIFF_FLAG_NOT_BINARY; |
75 | fc->file->flags |= GIT_DIFF_FLAG_BINARY; | |
5dc98298 | 76 | } |
114f5a6c RB |
77 | |
78 | diff_file_content_binary_by_size(fc); | |
79 | ||
74ded024 RB |
80 | if ((fc->flags & GIT_DIFF_FLAG__NO_DATA) != 0) { |
81 | fc->flags |= GIT_DIFF_FLAG__LOADED; | |
114f5a6c RB |
82 | fc->map.len = 0; |
83 | fc->map.data = ""; | |
84 | } | |
85 | ||
74ded024 | 86 | if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0) |
114f5a6c RB |
87 | diff_file_content_binary_by_content(fc); |
88 | ||
89 | return 0; | |
90 | } | |
91 | ||
360f42f4 | 92 | int git_diff_file_content__init_from_diff( |
114f5a6c | 93 | git_diff_file_content *fc, |
3ff1d123 | 94 | git_diff *diff, |
8147b1af | 95 | git_diff_delta *delta, |
114f5a6c RB |
96 | bool use_old) |
97 | { | |
114f5a6c RB |
98 | bool has_data = true; |
99 | ||
100 | memset(fc, 0, sizeof(*fc)); | |
101 | fc->repo = diff->repo; | |
74ded024 | 102 | fc->file = use_old ? &delta->old_file : &delta->new_file; |
114f5a6c | 103 | fc->src = use_old ? diff->old_src : diff->new_src; |
114f5a6c | 104 | |
eae0bfdc PP |
105 | if (git_diff_driver_lookup(&fc->driver, fc->repo, |
106 | &diff->attrsession, fc->file->path) < 0) | |
114f5a6c RB |
107 | return -1; |
108 | ||
109 | switch (delta->status) { | |
110 | case GIT_DELTA_ADDED: | |
111 | has_data = !use_old; break; | |
112 | case GIT_DELTA_DELETED: | |
113 | has_data = use_old; break; | |
114 | case GIT_DELTA_UNTRACKED: | |
115 | has_data = !use_old && | |
10672e3e | 116 | (diff->opts.flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) != 0; |
114f5a6c | 117 | break; |
61bef72d | 118 | case GIT_DELTA_UNREADABLE: |
114f5a6c RB |
119 | case GIT_DELTA_MODIFIED: |
120 | case GIT_DELTA_COPIED: | |
121 | case GIT_DELTA_RENAMED: | |
122 | break; | |
123 | default: | |
124 | has_data = false; | |
125 | break; | |
126 | } | |
127 | ||
128 | if (!has_data) | |
74ded024 | 129 | fc->flags |= GIT_DIFF_FLAG__NO_DATA; |
114f5a6c | 130 | |
5dc98298 | 131 | return diff_file_content_init_common(fc, &diff->opts); |
114f5a6c RB |
132 | } |
133 | ||
6789b7a7 | 134 | int git_diff_file_content__init_from_src( |
114f5a6c RB |
135 | git_diff_file_content *fc, |
136 | git_repository *repo, | |
137 | const git_diff_options *opts, | |
6789b7a7 | 138 | const git_diff_file_content_src *src, |
74ded024 | 139 | git_diff_file *as_file) |
114f5a6c RB |
140 | { |
141 | memset(fc, 0, sizeof(*fc)); | |
142 | fc->repo = repo; | |
74ded024 | 143 | fc->file = as_file; |
114f5a6c | 144 | |
6789b7a7 | 145 | if (!src->blob && !src->buf) { |
74ded024 | 146 | fc->flags |= GIT_DIFF_FLAG__NO_DATA; |
114f5a6c | 147 | } else { |
74ded024 | 148 | fc->flags |= GIT_DIFF_FLAG__LOADED; |
9950bb4e | 149 | fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; |
74ded024 | 150 | fc->file->mode = GIT_FILEMODE_BLOB; |
114f5a6c | 151 | |
6789b7a7 | 152 | if (src->blob) { |
eae0bfdc | 153 | git_blob_dup((git_blob **)&fc->blob, (git_blob *) src->blob); |
6789b7a7 RB |
154 | fc->file->size = git_blob_rawsize(src->blob); |
155 | git_oid_cpy(&fc->file->id, git_blob_id(src->blob)); | |
d68cb736 | 156 | fc->file->id_abbrev = GIT_OID_HEXSZ; |
114f5a6c | 157 | |
6789b7a7 RB |
158 | fc->map.len = (size_t)fc->file->size; |
159 | fc->map.data = (char *)git_blob_rawcontent(src->blob); | |
eae0bfdc PP |
160 | |
161 | fc->flags |= GIT_DIFF_FLAG__FREE_BLOB; | |
6789b7a7 | 162 | } else { |
22a2d3d5 UG |
163 | int error; |
164 | if ((error = git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB)) < 0) | |
165 | return error; | |
6789b7a7 | 166 | fc->file->size = src->buflen; |
d68cb736 | 167 | fc->file->id_abbrev = GIT_OID_HEXSZ; |
114f5a6c | 168 | |
6789b7a7 RB |
169 | fc->map.len = src->buflen; |
170 | fc->map.data = (char *)src->buf; | |
171 | } | |
114f5a6c RB |
172 | } |
173 | ||
5dc98298 | 174 | return diff_file_content_init_common(fc, opts); |
114f5a6c RB |
175 | } |
176 | ||
177 | static int diff_file_content_commit_to_str( | |
178 | git_diff_file_content *fc, bool check_status) | |
179 | { | |
180 | char oid[GIT_OID_HEXSZ+1]; | |
e579e0f7 | 181 | git_str content = GIT_STR_INIT; |
114f5a6c RB |
182 | const char *status = ""; |
183 | ||
184 | if (check_status) { | |
185 | int error = 0; | |
186 | git_submodule *sm = NULL; | |
187 | unsigned int sm_status = 0; | |
188 | const git_oid *sm_head; | |
189 | ||
a15c7802 | 190 | if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) { |
114f5a6c | 191 | /* GIT_EEXISTS means a "submodule" that has not been git added */ |
a15c7802 | 192 | if (error == GIT_EEXISTS) { |
ac3d33df | 193 | git_error_clear(); |
114f5a6c | 194 | error = 0; |
a15c7802 RB |
195 | } |
196 | return error; | |
197 | } | |
198 | ||
c2418f46 | 199 | if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) { |
a15c7802 | 200 | git_submodule_free(sm); |
114f5a6c RB |
201 | return error; |
202 | } | |
203 | ||
204 | /* update OID if we didn't have it previously */ | |
9950bb4e | 205 | if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 && |
114f5a6c RB |
206 | ((sm_head = git_submodule_wd_id(sm)) != NULL || |
207 | (sm_head = git_submodule_head_id(sm)) != NULL)) | |
208 | { | |
9950bb4e CMN |
209 | git_oid_cpy(&fc->file->id, sm_head); |
210 | fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; | |
114f5a6c RB |
211 | } |
212 | ||
213 | if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status)) | |
214 | status = "-dirty"; | |
a15c7802 RB |
215 | |
216 | git_submodule_free(sm); | |
114f5a6c RB |
217 | } |
218 | ||
9950bb4e | 219 | git_oid_tostr(oid, sizeof(oid), &fc->file->id); |
e579e0f7 | 220 | if (git_str_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) |
114f5a6c RB |
221 | return -1; |
222 | ||
e579e0f7 MB |
223 | fc->map.len = git_str_len(&content); |
224 | fc->map.data = git_str_detach(&content); | |
74ded024 | 225 | fc->flags |= GIT_DIFF_FLAG__FREE_DATA; |
114f5a6c RB |
226 | |
227 | return 0; | |
228 | } | |
229 | ||
8147b1af ET |
230 | static int diff_file_content_load_blob( |
231 | git_diff_file_content *fc, | |
232 | git_diff_options *opts) | |
114f5a6c RB |
233 | { |
234 | int error = 0; | |
235 | git_odb_object *odb_obj = NULL; | |
236 | ||
22a2d3d5 | 237 | if (git_oid_is_zero(&fc->file->id)) |
114f5a6c RB |
238 | return 0; |
239 | ||
74ded024 | 240 | if (fc->file->mode == GIT_FILEMODE_COMMIT) |
114f5a6c RB |
241 | return diff_file_content_commit_to_str(fc, false); |
242 | ||
243 | /* if we don't know size, try to peek at object header first */ | |
74ded024 | 244 | if (!fc->file->size) { |
effdbeb3 RB |
245 | if ((error = git_diff_file__resolve_zero_size( |
246 | fc->file, &odb_obj, fc->repo)) < 0) | |
114f5a6c | 247 | return error; |
114f5a6c RB |
248 | } |
249 | ||
8147b1af ET |
250 | if ((opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && |
251 | diff_file_content_binary_by_size(fc)) | |
114f5a6c RB |
252 | return 0; |
253 | ||
254 | if (odb_obj != NULL) { | |
255 | error = git_object__from_odb_object( | |
ac3d33df | 256 | (git_object **)&fc->blob, fc->repo, odb_obj, GIT_OBJECT_BLOB); |
114f5a6c RB |
257 | git_odb_object_free(odb_obj); |
258 | } else { | |
259 | error = git_blob_lookup( | |
9950bb4e | 260 | (git_blob **)&fc->blob, fc->repo, &fc->file->id); |
114f5a6c RB |
261 | } |
262 | ||
263 | if (!error) { | |
74ded024 | 264 | fc->flags |= GIT_DIFF_FLAG__FREE_BLOB; |
114f5a6c RB |
265 | fc->map.data = (void *)git_blob_rawcontent(fc->blob); |
266 | fc->map.len = (size_t)git_blob_rawsize(fc->blob); | |
267 | } | |
268 | ||
269 | return error; | |
270 | } | |
271 | ||
6b0fc6ab | 272 | static int diff_file_content_load_workdir_symlink_fake( |
e579e0f7 | 273 | git_diff_file_content *fc, git_str *path) |
6b0fc6ab | 274 | { |
e579e0f7 | 275 | git_str target = GIT_STR_INIT; |
6b0fc6ab ET |
276 | int error; |
277 | ||
278 | if ((error = git_futils_readbuffer(&target, path->ptr)) < 0) | |
279 | return error; | |
280 | ||
e579e0f7 MB |
281 | fc->map.len = git_str_len(&target); |
282 | fc->map.data = git_str_detach(&target); | |
6b0fc6ab ET |
283 | fc->flags |= GIT_DIFF_FLAG__FREE_DATA; |
284 | ||
e579e0f7 | 285 | git_str_dispose(&target); |
6b0fc6ab ET |
286 | return error; |
287 | } | |
288 | ||
114f5a6c | 289 | static int diff_file_content_load_workdir_symlink( |
e579e0f7 | 290 | git_diff_file_content *fc, git_str *path) |
114f5a6c RB |
291 | { |
292 | ssize_t alloc_len, read_len; | |
6b0fc6ab ET |
293 | int symlink_supported, error; |
294 | ||
22a2d3d5 UG |
295 | if ((error = git_repository__configmap_lookup( |
296 | &symlink_supported, fc->repo, GIT_CONFIGMAP_SYMLINKS)) < 0) | |
6b0fc6ab ET |
297 | return -1; |
298 | ||
299 | if (!symlink_supported) | |
300 | return diff_file_content_load_workdir_symlink_fake(fc, path); | |
114f5a6c RB |
301 | |
302 | /* link path on disk could be UTF-16, so prepare a buffer that is | |
303 | * big enough to handle some UTF-8 data expansion | |
304 | */ | |
74ded024 | 305 | alloc_len = (ssize_t)(fc->file->size * 2) + 1; |
114f5a6c RB |
306 | |
307 | fc->map.data = git__calloc(alloc_len, sizeof(char)); | |
ac3d33df | 308 | GIT_ERROR_CHECK_ALLOC(fc->map.data); |
114f5a6c | 309 | |
74ded024 | 310 | fc->flags |= GIT_DIFF_FLAG__FREE_DATA; |
114f5a6c | 311 | |
e579e0f7 | 312 | read_len = p_readlink(git_str_cstr(path), fc->map.data, alloc_len); |
114f5a6c | 313 | if (read_len < 0) { |
ac3d33df | 314 | git_error_set(GIT_ERROR_OS, "failed to read symlink '%s'", fc->file->path); |
114f5a6c RB |
315 | return -1; |
316 | } | |
317 | ||
318 | fc->map.len = read_len; | |
319 | return 0; | |
320 | } | |
321 | ||
322 | static int diff_file_content_load_workdir_file( | |
8147b1af | 323 | git_diff_file_content *fc, |
e579e0f7 | 324 | git_str *path, |
8147b1af | 325 | git_diff_options *diff_opts) |
114f5a6c RB |
326 | { |
327 | int error = 0; | |
85d54812 | 328 | git_filter_list *fl = NULL; |
e579e0f7 MB |
329 | git_file fd = git_futils_open_ro(git_str_cstr(path)); |
330 | git_str raw = GIT_STR_INIT; | |
331 | git_object_size_t new_file_size = 0; | |
114f5a6c RB |
332 | |
333 | if (fd < 0) | |
334 | return fd; | |
335 | ||
e579e0f7 | 336 | error = git_futils_filesize(&new_file_size, fd); |
22a2d3d5 | 337 | |
e579e0f7 | 338 | if (error < 0) |
114f5a6c RB |
339 | goto cleanup; |
340 | ||
e579e0f7 MB |
341 | if (!(fc->file->flags & GIT_DIFF_FLAG_VALID_SIZE)) { |
342 | fc->file->size = new_file_size; | |
343 | fc->file->flags |= GIT_DIFF_FLAG_VALID_SIZE; | |
344 | } else if (fc->file->size != new_file_size) { | |
345 | git_error_set(GIT_ERROR_FILESYSTEM, "file changed before we could read it"); | |
346 | error = -1; | |
347 | goto cleanup; | |
348 | } | |
349 | ||
8147b1af ET |
350 | if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && |
351 | diff_file_content_binary_by_size(fc)) | |
114f5a6c RB |
352 | goto cleanup; |
353 | ||
85d54812 | 354 | if ((error = git_filter_list_load( |
5269008c | 355 | &fl, fc->repo, NULL, fc->file->path, |
795eaccd | 356 | GIT_FILTER_TO_ODB, GIT_FILTER_ALLOW_UNSAFE)) < 0) |
114f5a6c | 357 | goto cleanup; |
114f5a6c | 358 | |
85d54812 RB |
359 | /* if there are no filters, try to mmap the file */ |
360 | if (fl == NULL) { | |
114f5a6c | 361 | if (!(error = git_futils_mmap_ro( |
85d54812 | 362 | &fc->map, fd, 0, (size_t)fc->file->size))) { |
74ded024 | 363 | fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA; |
114f5a6c | 364 | goto cleanup; |
114f5a6c RB |
365 | } |
366 | ||
85d54812 | 367 | /* if mmap failed, fall through to try readbuffer below */ |
ac3d33df | 368 | git_error_clear(); |
114f5a6c RB |
369 | } |
370 | ||
2a7d224f | 371 | if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) { |
e579e0f7 | 372 | git_str out = GIT_STR_INIT; |
2a7d224f | 373 | |
c25aa7cd | 374 | error = git_filter_list__convert_buf(&out, fl, &raw); |
85d54812 | 375 | |
2a7d224f RB |
376 | if (!error) { |
377 | fc->map.len = out.size; | |
378 | fc->map.data = out.ptr; | |
379 | fc->flags |= GIT_DIFF_FLAG__FREE_DATA; | |
380 | } | |
381 | } | |
85d54812 | 382 | |
114f5a6c | 383 | cleanup: |
85d54812 | 384 | git_filter_list_free(fl); |
114f5a6c RB |
385 | p_close(fd); |
386 | ||
387 | return error; | |
388 | } | |
389 | ||
8147b1af ET |
390 | static int diff_file_content_load_workdir( |
391 | git_diff_file_content *fc, | |
392 | git_diff_options *diff_opts) | |
114f5a6c RB |
393 | { |
394 | int error = 0; | |
e579e0f7 | 395 | git_str path = GIT_STR_INIT; |
114f5a6c | 396 | |
74ded024 | 397 | if (fc->file->mode == GIT_FILEMODE_COMMIT) |
114f5a6c RB |
398 | return diff_file_content_commit_to_str(fc, true); |
399 | ||
74ded024 | 400 | if (fc->file->mode == GIT_FILEMODE_TREE) |
114f5a6c RB |
401 | return 0; |
402 | ||
c25aa7cd | 403 | if (git_repository_workdir_path(&path, fc->repo, fc->file->path) < 0) |
114f5a6c RB |
404 | return -1; |
405 | ||
74ded024 | 406 | if (S_ISLNK(fc->file->mode)) |
114f5a6c RB |
407 | error = diff_file_content_load_workdir_symlink(fc, &path); |
408 | else | |
8147b1af | 409 | error = diff_file_content_load_workdir_file(fc, &path, diff_opts); |
114f5a6c RB |
410 | |
411 | /* once data is loaded, update OID if we didn't have it previously */ | |
9950bb4e | 412 | if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) { |
114f5a6c | 413 | error = git_odb_hash( |
ac3d33df | 414 | &fc->file->id, fc->map.data, fc->map.len, GIT_OBJECT_BLOB); |
9950bb4e | 415 | fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; |
114f5a6c RB |
416 | } |
417 | ||
e579e0f7 | 418 | git_str_dispose(&path); |
114f5a6c RB |
419 | return error; |
420 | } | |
421 | ||
8147b1af ET |
422 | int git_diff_file_content__load( |
423 | git_diff_file_content *fc, | |
424 | git_diff_options *diff_opts) | |
114f5a6c RB |
425 | { |
426 | int error = 0; | |
427 | ||
74ded024 | 428 | if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0) |
114f5a6c RB |
429 | return 0; |
430 | ||
8147b1af ET |
431 | if ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0 && |
432 | (diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0) | |
114f5a6c RB |
433 | return 0; |
434 | ||
22a2d3d5 | 435 | if (fc->src == GIT_ITERATOR_WORKDIR) |
8147b1af | 436 | error = diff_file_content_load_workdir(fc, diff_opts); |
114f5a6c | 437 | else |
8147b1af | 438 | error = diff_file_content_load_blob(fc, diff_opts); |
114f5a6c RB |
439 | if (error) |
440 | return error; | |
441 | ||
74ded024 | 442 | fc->flags |= GIT_DIFF_FLAG__LOADED; |
114f5a6c RB |
443 | |
444 | diff_file_content_binary_by_content(fc); | |
445 | ||
446 | return 0; | |
447 | } | |
448 | ||
360f42f4 | 449 | void git_diff_file_content__unload(git_diff_file_content *fc) |
114f5a6c | 450 | { |
39a1a662 RB |
451 | if ((fc->flags & GIT_DIFF_FLAG__LOADED) == 0) |
452 | return; | |
453 | ||
74ded024 | 454 | if (fc->flags & GIT_DIFF_FLAG__FREE_DATA) { |
114f5a6c RB |
455 | git__free(fc->map.data); |
456 | fc->map.data = ""; | |
457 | fc->map.len = 0; | |
74ded024 | 458 | fc->flags &= ~GIT_DIFF_FLAG__FREE_DATA; |
114f5a6c | 459 | } |
74ded024 | 460 | else if (fc->flags & GIT_DIFF_FLAG__UNMAP_DATA) { |
114f5a6c RB |
461 | git_futils_mmap_free(&fc->map); |
462 | fc->map.data = ""; | |
463 | fc->map.len = 0; | |
74ded024 | 464 | fc->flags &= ~GIT_DIFF_FLAG__UNMAP_DATA; |
114f5a6c RB |
465 | } |
466 | ||
74ded024 | 467 | if (fc->flags & GIT_DIFF_FLAG__FREE_BLOB) { |
114f5a6c RB |
468 | git_blob_free((git_blob *)fc->blob); |
469 | fc->blob = NULL; | |
74ded024 | 470 | fc->flags &= ~GIT_DIFF_FLAG__FREE_BLOB; |
114f5a6c RB |
471 | } |
472 | ||
74ded024 | 473 | fc->flags &= ~GIT_DIFF_FLAG__LOADED; |
114f5a6c RB |
474 | } |
475 | ||
360f42f4 | 476 | void git_diff_file_content__clear(git_diff_file_content *fc) |
114f5a6c | 477 | { |
360f42f4 | 478 | git_diff_file_content__unload(fc); |
114f5a6c RB |
479 | |
480 | /* for now, nothing else to do */ | |
481 | } |