Line Flow Count Block(s) Source
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 -
8 - #include "status.h"
9 -
10 - #include "git2.h"
11 - #include "futils.h"
12 - #include "hash.h"
13 - #include "vector.h"
14 - #include "tree.h"
15 - #include "git2/status.h"
16 - #include "repository.h"
17 - #include "ignore.h"
18 - #include "index.h"
19 - #include "wildmatch.h"
20 -
21 - #include "git2/diff.h"
22 - #include "diff.h"
23 - #include "diff_generate.h"
24 -
25 666 2 static unsigned int index_delta2status(const git_diff_delta *head2idx)
26 - {
27 666 2 git_status_t st = GIT_STATUS_CURRENT;
28 -
29 666 2 switch (head2idx->status) {
30 - case GIT_DELTA_ADDED:
31 - case GIT_DELTA_COPIED:
32 253 3 st = GIT_STATUS_INDEX_NEW;
33 253 3 break;
34 - case GIT_DELTA_DELETED:
35 58 4 st = GIT_STATUS_INDEX_DELETED;
36 58 4 break;
37 - case GIT_DELTA_MODIFIED:
38 138 5 st = GIT_STATUS_INDEX_MODIFIED;
39 138 5 break;
40 - case GIT_DELTA_RENAMED:
41 18 6 st = GIT_STATUS_INDEX_RENAMED;
42 -
43 18 6,7 if (!git_oid_equal(&head2idx->old_file.id, &head2idx->new_file.id))
44 5 8 st |= GIT_STATUS_INDEX_MODIFIED;
45 18 9 break;
46 - case GIT_DELTA_TYPECHANGE:
47 ##### 10 st = GIT_STATUS_INDEX_TYPECHANGE;
48 ##### 10 break;
49 - case GIT_DELTA_CONFLICTED:
50 6 11 st = GIT_STATUS_CONFLICTED;
51 6 11 break;
52 - default:
53 193 12 break;
54 - }
55 -
56 666 13 return st;
57 - }
58 -
59 1031 2 static unsigned int workdir_delta2status(
60 - git_diff *diff, git_diff_delta *idx2wd)
61 - {
62 1031 2 git_status_t st = GIT_STATUS_CURRENT;
63 -
64 1031 2 switch (idx2wd->status) {
65 - case GIT_DELTA_ADDED:
66 - case GIT_DELTA_COPIED:
67 - case GIT_DELTA_UNTRACKED:
68 332 3 st = GIT_STATUS_WT_NEW;
69 332 3 break;
70 - case GIT_DELTA_UNREADABLE:
71 1 4 st = GIT_STATUS_WT_UNREADABLE;
72 1 4 break;
73 - case GIT_DELTA_DELETED:
74 86 5 st = GIT_STATUS_WT_DELETED;
75 86 5 break;
76 - case GIT_DELTA_MODIFIED:
77 268 6 st = GIT_STATUS_WT_MODIFIED;
78 268 6 break;
79 - case GIT_DELTA_IGNORED:
80 109 7 st = GIT_STATUS_IGNORED;
81 109 7 break;
82 - case GIT_DELTA_RENAMED:
83 19 8 st = GIT_STATUS_WT_RENAMED;
84 -
85 19 8,9 if (!git_oid_equal(&idx2wd->old_file.id, &idx2wd->new_file.id)) {
86 - /* if OIDs don't match, we might need to calculate them now to
87 - * discern between RENAMED vs RENAMED+MODIFED
88 - */
89 19 10-12 if (git_oid_is_zero(&idx2wd->old_file.id) &&
90 ##### 12,14 diff->old_src == GIT_ITERATOR_WORKDIR &&
91 ##### 13,13 !git_diff__oid_for_file(
92 - &idx2wd->old_file.id, diff, idx2wd->old_file.path,
93 ##### 13 idx2wd->old_file.mode, idx2wd->old_file.size))
94 ##### 15 idx2wd->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
95 -
96 19 16-18 if (git_oid_is_zero(&idx2wd->new_file.id) &&
97 19 18,20 diff->new_src == GIT_ITERATOR_WORKDIR &&
98 19 19,19 !git_diff__oid_for_file(
99 - &idx2wd->new_file.id, diff, idx2wd->new_file.path,
100 19 19 idx2wd->new_file.mode, idx2wd->new_file.size))
101 19 21 idx2wd->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
102 -
103 19 22,23 if (!git_oid_equal(&idx2wd->old_file.id, &idx2wd->new_file.id))
104 6 24 st |= GIT_STATUS_WT_MODIFIED;
105 - }
106 19 25 break;
107 - case GIT_DELTA_TYPECHANGE:
108 ##### 26 st = GIT_STATUS_WT_TYPECHANGE;
109 ##### 26 break;
110 - case GIT_DELTA_CONFLICTED:
111 6 27 st = GIT_STATUS_CONFLICTED;
112 6 27 break;
113 - default:
114 210 28 break;
115 - }
116 -
117 1031 29 return st;
118 - }
119 -
120 1278 2 static bool status_is_included(
121 - git_status_list *status,
122 - git_diff_delta *head2idx,
123 - git_diff_delta *idx2wd)
124 - {
125 1278 2 if (!(status->opts.flags & GIT_STATUS_OPT_EXCLUDE_SUBMODULES))
126 1052 3 return 1;
127 -
128 - /* if excluding submodules and this is a submodule everywhere */
129 226 4 if (head2idx) {
130 126 5,6 if (head2idx->status != GIT_DELTA_ADDED &&
131 54 6 head2idx->old_file.mode != GIT_FILEMODE_COMMIT)
132 54 7 return 1;
133 72 8,9 if (head2idx->status != GIT_DELTA_DELETED &&
134 72 9 head2idx->new_file.mode != GIT_FILEMODE_COMMIT)
135 72 10 return 1;
136 - }
137 100 11 if (idx2wd) {
138 100 12,13 if (idx2wd->status != GIT_DELTA_ADDED &&
139 100 13 idx2wd->old_file.mode != GIT_FILEMODE_COMMIT)
140 100 14 return 1;
141 ##### 15,16 if (idx2wd->status != GIT_DELTA_DELETED &&
142 ##### 16 idx2wd->new_file.mode != GIT_FILEMODE_COMMIT)
143 ##### 17 return 1;
144 - }
145 -
146 - /* only get here if every valid mode is GIT_FILEMODE_COMMIT */
147 ##### 18 return 0;
148 - }
149 -
150 1278 2 static git_status_t status_compute(
151 - git_status_list *status,
152 - git_diff_delta *head2idx,
153 - git_diff_delta *idx2wd)
154 - {
155 1278 2 git_status_t st = GIT_STATUS_CURRENT;
156 -
157 1278 2 if (head2idx)
158 666 3,4 st |= index_delta2status(head2idx);
159 -
160 1278 5 if (idx2wd)
161 1031 6,7 st |= workdir_delta2status(status->idx2wd, idx2wd);
162 -
163 1278 8 return st;
164 - }
165 -
166 1278 2 static int status_collect(
167 - git_diff_delta *head2idx,
168 - git_diff_delta *idx2wd,
169 - void *payload)
170 - {
171 1278 2 git_status_list *status = payload;
172 - git_status_entry *status_entry;
173 -
174 1278 2,3 if (!status_is_included(status, head2idx, idx2wd))
175 ##### 4 return 0;
176 -
177 1278 5 status_entry = git__malloc(sizeof(git_status_entry));
178 1278 6,7 GIT_ERROR_CHECK_ALLOC(status_entry);
179 -
180 1278 8 status_entry->status = status_compute(status, head2idx, idx2wd);
181 1278 9 status_entry->head_to_index = head2idx;
182 1278 9 status_entry->index_to_workdir = idx2wd;
183 -
184 1278 9 return git_vector_insert(&status->paired, status_entry);
185 - }
186 -
187 80 2 GIT_INLINE(int) status_entry_cmp_base(
188 - const void *a,
189 - const void *b,
190 - int (*strcomp)(const char *a, const char *b))
191 - {
192 80 2 const git_status_entry *entry_a = a;
193 80 2 const git_status_entry *entry_b = b;
194 - const git_diff_delta *delta_a, *delta_b;
195 -
196 80 2-4 delta_a = entry_a->index_to_workdir ? entry_a->index_to_workdir :
197 - entry_a->head_to_index;
198 80 5-7 delta_b = entry_b->index_to_workdir ? entry_b->index_to_workdir :
199 - entry_b->head_to_index;
200 -
201 80 8,9 if (!delta_a && delta_b)
202 ##### 10 return -1;
203 80 11,12 if (delta_a && !delta_b)
204 ##### 13 return 1;
205 80 14,15 if (!delta_a && !delta_b)
206 ##### 16 return 0;
207 -
208 80 17 return strcomp(delta_a->new_file.path, delta_b->new_file.path);
209 - }
210 -
211 35 2 static int status_entry_icmp(const void *a, const void *b)
212 - {
213 35 2 return status_entry_cmp_base(a, b, git__strcasecmp);
214 - }
215 -
216 45 2 static int status_entry_cmp(const void *a, const void *b)
217 - {
218 45 2 return status_entry_cmp_base(a, b, git__strcmp);
219 - }
220 -
221 664 2 static git_status_list *git_status_list_alloc(git_index *index)
222 - {
223 664 2 git_status_list *status = NULL;
224 - int (*entrycmp)(const void *a, const void *b);
225 -
226 664 2,3 if (!(status = git__calloc(1, sizeof(git_status_list))))
227 ##### 4 return NULL;
228 -
229 664 5-7 entrycmp = index->ignore_case ? status_entry_icmp : status_entry_cmp;
230 -
231 664 8,9 if (git_vector_init(&status->paired, 0, entrycmp) < 0) {
232 ##### 10 git__free(status);
233 ##### 11 return NULL;
234 - }
235 -
236 664 12 return status;
237 - }
238 -
239 665 2 static int status_validate_options(const git_status_options *opts)
240 - {
241 665 2 if (!opts)
242 112 3 return 0;
243 -
244 553 4-6 GIT_ERROR_CHECK_VERSION(opts, GIT_STATUS_OPTIONS_VERSION, "git_status_options");
245 -
246 553 7 if (opts->show > GIT_STATUS_SHOW_WORKDIR_ONLY) {
247 ##### 8 git_error_set(GIT_ERROR_INVALID, "unknown status 'show' option");
248 ##### 9 return -1;
249 - }
250 -
251 553 10,11 if ((opts->flags & GIT_STATUS_OPT_NO_REFRESH) != 0 &&
252 ##### 11 (opts->flags & GIT_STATUS_OPT_UPDATE_INDEX) != 0) {
253 ##### 12 git_error_set(GIT_ERROR_INVALID, "updating index from status "
254 - "is not allowed when index refresh is disabled");
255 ##### 13 return -1;
256 - }
257 -
258 553 14 return 0;
259 - }
260 -
261 665 2 int git_status_list_new(
262 - git_status_list **out,
263 - git_repository *repo,
264 - const git_status_options *opts)
265 - {
266 665 2 git_index *index = NULL;
267 665 2 git_status_list *status = NULL;
268 665 2 git_diff_options diffopt = GIT_DIFF_OPTIONS_INIT;
269 665 2 git_diff_find_options findopt = GIT_DIFF_FIND_OPTIONS_INIT;
270 665 2 git_tree *head = NULL;
271 665 5 git_status_show_t show =
272 665 2-4 opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
273 665 5 int error = 0;
274 665 5-7 unsigned int flags = opts ? opts->flags : GIT_STATUS_OPT_DEFAULTS;
275 -
276 665 8 *out = NULL;
277 -
278 665 8,9 if (status_validate_options(opts) < 0)
279 ##### 10 return -1;
280 -
281 665 11-14 if ((error = git_repository__ensure_not_bare(repo, "status")) < 0 ||
282 - (error = git_repository_index(&index, repo)) < 0)
283 1 15 return error;
284 -
285 664 16,17 if (opts != NULL && opts->baseline != NULL) {
286 1 18 head = opts->baseline;
287 - } else {
288 - /* if there is no HEAD, that's okay - we'll make an empty iterator */
289 663 19,20 if ((error = git_repository_head_tree(&head, repo)) < 0) {
290 95 21,22 if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH)
291 ##### 23 goto done;
292 95 24 git_error_clear();
293 - }
294 - }
295 -
296 - /* refresh index from disk unless prevented */
297 664 25,27 if ((flags & GIT_STATUS_OPT_NO_REFRESH) == 0 &&
298 664 26 git_index_read_safely(index) < 0)
299 ##### 28 git_error_clear();
300 -
301 664 29 status = git_status_list_alloc(index);
302 664 30,31 GIT_ERROR_CHECK_ALLOC(status);
303 -
304 664 32 if (opts) {
305 552 33 memcpy(&status->opts, opts, sizeof(git_status_options));
306 552 33 memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
307 - }
308 -
309 664 34 diffopt.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
310 664 34 findopt.flags = GIT_DIFF_FIND_FOR_UNTRACKED;
311 -
312 664 34 if ((flags & GIT_STATUS_OPT_INCLUDE_UNTRACKED) != 0)
313 636 35 diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNTRACKED;
314 664 36 if ((flags & GIT_STATUS_OPT_INCLUDE_IGNORED) != 0)
315 565 37 diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_IGNORED;
316 664 38 if ((flags & GIT_STATUS_OPT_INCLUDE_UNMODIFIED) != 0)
317 419 39 diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNMODIFIED;
318 664 40 if ((flags & GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS) != 0)
319 620 41 diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS;
320 664 42 if ((flags & GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH) != 0)
321 423 43 diffopt.flags = diffopt.flags | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
322 664 44 if ((flags & GIT_STATUS_OPT_RECURSE_IGNORED_DIRS) != 0)
323 424 45 diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_IGNORED_DIRS;
324 664 46 if ((flags & GIT_STATUS_OPT_EXCLUDE_SUBMODULES) != 0)
325 69 47 diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
326 664 48 if ((flags & GIT_STATUS_OPT_UPDATE_INDEX) != 0)
327 2 49 diffopt.flags = diffopt.flags | GIT_DIFF_UPDATE_INDEX;
328 664 50 if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE) != 0)
329 3 51 diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE;
330 664 52 if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED) != 0)
331 2 53 diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED;
332 -
333 664 54 if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
334 6 55,55 findopt.flags = findopt.flags |
335 - GIT_DIFF_FIND_AND_BREAK_REWRITES |
336 6 55 GIT_DIFF_FIND_RENAMES_FROM_REWRITES |
337 - GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY;
338 -
339 664 56 if (show != GIT_STATUS_SHOW_WORKDIR_ONLY) {
340 658 57,58 if ((error = git_diff_tree_to_index(
341 - &status->head2idx, repo, head, index, &diffopt)) < 0)
342 ##### 59 goto done;
343 -
344 658 60-62 if ((flags & GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX) != 0 &&
345 12 61 (error = git_diff_find_similar(status->head2idx, &findopt)) < 0)
346 ##### 63 goto done;
347 - }
348 -
349 664 64 if (show != GIT_STATUS_SHOW_INDEX_ONLY) {
350 662 65,66 if ((error = git_diff_index_to_workdir(
351 - &status->idx2wd, repo, index, &diffopt)) < 0) {
352 ##### 67 goto done;
353 - }
354 -
355 662 68-70 if ((flags & GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR) != 0 &&
356 11 69 (error = git_diff_find_similar(status->idx2wd, &findopt)) < 0)
357 ##### 71 goto done;
358 - }
359 -
360 664 72 error = git_diff__paired_foreach(
361 - status->head2idx, status->idx2wd, status_collect, status);
362 664 73 if (error < 0)
363 ##### 74 goto done;
364 -
365 664 75 if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY)
366 1 76 git_vector_set_cmp(&status->paired, status_entry_cmp);
367 664 77 if (flags & GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)
368 2 78 git_vector_set_cmp(&status->paired, status_entry_icmp);
369 -
370 664 79 if ((flags &
371 - (GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
372 - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR |
373 - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY |
374 - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)) != 0)
375 18 80 git_vector_sort(&status->paired);
376 -
377 - done:
378 664 81 if (error < 0) {
379 ##### 82 git_status_list_free(status);
380 ##### 83 status = NULL;
381 - }
382 -
383 664 84 *out = status;
384 -
385 664 84,85 if (opts == NULL || opts->baseline != head)
386 615 86 git_tree_free(head);
387 664 87 git_index_free(index);
388 -
389 664 88 return error;
390 - }
391 -
392 72 2 size_t git_status_list_entrycount(git_status_list *status)
393 - {
394 72 2,3 assert(status);
395 -
396 72 4 return status->paired.length;
397 - }
398 -
399 120 2 const git_status_entry *git_status_byindex(git_status_list *status, size_t i)
400 - {
401 120 2,3 assert(status);
402 -
403 120 4 return git_vector_get(&status->paired, i);
404 - }
405 -
406 664 2 void git_status_list_free(git_status_list *status)
407 - {
408 664 2 if (status == NULL)
409 664 3,9 return;
410 -
411 664 4 git_diff_free(status->head2idx);
412 664 5 git_diff_free(status->idx2wd);
413 -
414 664 6 git_vector_free_deep(&status->paired);
415 -
416 664 7 git__memzero(status, sizeof(*status));
417 664 8 git__free(status);
418 - }
419 -
420 611 2 int git_status_foreach_ext(
421 - git_repository *repo,
422 - const git_status_options *opts,
423 - git_status_cb cb,
424 - void *payload)
425 - {
426 - git_status_list *status;
427 - const git_status_entry *status_entry;
428 - size_t i;
429 611 2 int error = 0;
430 -
431 611 2,3 if ((error = git_status_list_new(&status, repo, opts)) < 0) {
432 1 4 return error;
433 - }
434 -
435 1513 5,12-14 git_vector_foreach(&status->paired, i, status_entry) {
436 965 6,9 const char *path = status_entry->head_to_index ?
437 965 6-8 status_entry->head_to_index->old_file.path :
438 492 8 status_entry->index_to_workdir->old_file.path;
439 -
440 965 9,10 if ((error = cb(path, status_entry->status, payload)) != 0) {
441 62 11 git_error_set_after_callback(error);
442 62 15 break;
443 - }
444 - }
445 -
446 610 16 git_status_list_free(status);
447 -
448 610 17 return error;
449 - }
450 -
451 88 2 int git_status_foreach(git_repository *repo, git_status_cb cb, void *payload)
452 - {
453 88 2 return git_status_foreach_ext(repo, NULL, cb, payload);
454 - }
455 -
456 - struct status_file_info {
457 - char *expected;
458 - unsigned int count;
459 - unsigned int status;
460 - int wildmatch_flags;
461 - int ambiguous;
462 - };
463 -
464 339 2 static int get_one_status(const char *path, unsigned int status, void *data)
465 - {
466 339 2 struct status_file_info *sfi = data;
467 - int (*strcomp)(const char *a, const char *b);
468 -
469 339 2 sfi->count++;
470 339 2 sfi->status = status;
471 -
472 339 2-4 strcomp = (sfi->wildmatch_flags & WM_CASEFOLD) ? git__strcasecmp : git__strcmp;
473 -
474 339 5,7 if (sfi->count > 1 ||
475 339 6,9 (strcomp(sfi->expected, path) != 0 &&
476 1 8 wildmatch(sfi->expected, path, sfi->wildmatch_flags) != 0))
477 - {
478 1 10 sfi->ambiguous = true;
479 1 10 return GIT_EAMBIGUOUS; /* git_error_set will be done by caller */
480 - }
481 -
482 338 11 return 0;
483 - }
484 -
485 414 2 int git_status_file(
486 - unsigned int *status_flags,
487 - git_repository *repo,
488 - const char *path)
489 - {
490 - int error;
491 414 2 git_status_options opts = GIT_STATUS_OPTIONS_INIT;
492 414 2 struct status_file_info sfi = {0};
493 - git_index *index;
494 -
495 414 2-5 assert(status_flags && repo && path);
496 -
497 414 6,7 if ((error = git_repository_index__weakptr(&index, repo)) < 0)
498 ##### 8 return error;
499 -
500 414 9,10 if ((sfi.expected = git__strdup(path)) == NULL)
501 ##### 11 return -1;
502 414 12 if (index->ignore_case)
503 3 13 sfi.wildmatch_flags = WM_CASEFOLD;
504 -
505 414 14 opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
506 414 14 opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
507 - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS |
508 - GIT_STATUS_OPT_INCLUDE_UNTRACKED |
509 - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
510 - GIT_STATUS_OPT_INCLUDE_UNMODIFIED |
511 - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
512 414 14 opts.pathspec.count = 1;
513 414 14 opts.pathspec.strings = &sfi.expected;
514 -
515 414 14 error = git_status_foreach_ext(repo, &opts, get_one_status, &sfi);
516 -
517 414 15,16 if (error < 0 && sfi.ambiguous) {
518 1 17 git_error_set(GIT_ERROR_INVALID,
519 - "ambiguous path '%s' given to git_status_file", sfi.expected);
520 1 18 error = GIT_EAMBIGUOUS;
521 - }
522 -
523 414 19,20 if (!error && !sfi.count) {
524 74 21 git_error_set(GIT_ERROR_INVALID,
525 - "attempt to get status of nonexistent file '%s'", path);
526 74 22 error = GIT_ENOTFOUND;
527 - }
528 -
529 414 23 *status_flags = sfi.status;
530 -
531 414 23 git__free(sfi.expected);
532 -
533 414 24 return error;
534 - }
535 -
536 165 2 int git_status_should_ignore(
537 - int *ignored,
538 - git_repository *repo,
539 - const char *path)
540 - {
541 165 2 return git_ignore_path_is_ignored(ignored, repo, path);
542 - }
543 -
544 1 2 int git_status_options_init(git_status_options *opts, unsigned int version)
545 - {
546 1 2-4 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
547 - opts, version, git_status_options, GIT_STATUS_OPTIONS_INIT);
548 1 5 return 0;
549 - }
550 -
551 - #ifndef GIT_DEPRECATE_HARD
552 ##### 2 int git_status_init_options(git_status_options *opts, unsigned int version)
553 - {
554 ##### 2 return git_status_options_init(opts, version);
555 - }
556 - #endif
557 -
558 3 2 int git_status_list_get_perfdata(
559 - git_diff_perfdata *out, const git_status_list *status)
560 - {
561 3 2,3 assert(out);
562 3 4-6 GIT_ERROR_CHECK_VERSION(out, GIT_DIFF_PERFDATA_VERSION, "git_diff_perfdata");
563 -
564 3 7 out->stat_calls = 0;
565 3 7 out->oid_calculations = 0;
566 -
567 3 7 if (status->head2idx) {
568 3 8 out->stat_calls += status->head2idx->perf.stat_calls;
569 3 8 out->oid_calculations += status->head2idx->perf.oid_calculations;
570 - }
571 3 9 if (status->idx2wd) {
572 3 10 out->stat_calls += status->idx2wd->perf.stat_calls;
573 3 10 out->oid_calculations += status->idx2wd->perf.oid_calculations;
574 - }
575 -
576 3 11 return 0;
577 - }
578 -