]> git.proxmox.com Git - libgit2.git/blob - src/index.c
remote: create FETCH_HEAD with a refspecless remote
[libgit2.git] / src / index.c
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 <stddef.h>
9
10 #include "common.h"
11 #include "repository.h"
12 #include "index.h"
13 #include "tree.h"
14 #include "tree-cache.h"
15 #include "hash.h"
16 #include "iterator.h"
17 #include "pathspec.h"
18 #include "ignore.h"
19 #include "blob.h"
20
21 #include "git2/odb.h"
22 #include "git2/oid.h"
23 #include "git2/blob.h"
24 #include "git2/config.h"
25 #include "git2/sys/index.h"
26
27 #define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
28 #define short_entry_size(len) entry_size(struct entry_short, len)
29 #define long_entry_size(len) entry_size(struct entry_long, len)
30
31 #define minimal_entry_size (offsetof(struct entry_short, path))
32
33 static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
34 static const size_t INDEX_HEADER_SIZE = 12;
35
36 static const unsigned int INDEX_VERSION_NUMBER = 2;
37 static const unsigned int INDEX_VERSION_NUMBER_EXT = 3;
38
39 static const unsigned int INDEX_HEADER_SIG = 0x44495243;
40 static const char INDEX_EXT_TREECACHE_SIG[] = {'T', 'R', 'E', 'E'};
41 static const char INDEX_EXT_UNMERGED_SIG[] = {'R', 'E', 'U', 'C'};
42 static const char INDEX_EXT_CONFLICT_NAME_SIG[] = {'N', 'A', 'M', 'E'};
43
44 #define INDEX_OWNER(idx) ((git_repository *)(GIT_REFCOUNT_OWNER(idx)))
45
46 struct index_header {
47 uint32_t signature;
48 uint32_t version;
49 uint32_t entry_count;
50 };
51
52 struct index_extension {
53 char signature[4];
54 uint32_t extension_size;
55 };
56
57 struct entry_time {
58 uint32_t seconds;
59 uint32_t nanoseconds;
60 };
61
62 struct entry_short {
63 struct entry_time ctime;
64 struct entry_time mtime;
65 uint32_t dev;
66 uint32_t ino;
67 uint32_t mode;
68 uint32_t uid;
69 uint32_t gid;
70 uint32_t file_size;
71 git_oid oid;
72 uint16_t flags;
73 char path[1]; /* arbitrary length */
74 };
75
76 struct entry_long {
77 struct entry_time ctime;
78 struct entry_time mtime;
79 uint32_t dev;
80 uint32_t ino;
81 uint32_t mode;
82 uint32_t uid;
83 uint32_t gid;
84 uint32_t file_size;
85 git_oid oid;
86 uint16_t flags;
87 uint16_t flags_extended;
88 char path[1]; /* arbitrary length */
89 };
90
91 struct entry_srch_key {
92 const char *path;
93 int stage;
94 };
95
96 /* local declarations */
97 static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size);
98 static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size);
99 static int read_header(struct index_header *dest, const void *buffer);
100
101 static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
102 static bool is_index_extended(git_index *index);
103 static int write_index(git_index *index, git_filebuf *file);
104
105 static void index_entry_free(git_index_entry *entry);
106 static void index_entry_reuc_free(git_index_reuc_entry *reuc);
107
108 static int index_srch(const void *key, const void *array_member)
109 {
110 const struct entry_srch_key *srch_key = key;
111 const git_index_entry *entry = array_member;
112 int ret;
113
114 ret = strcmp(srch_key->path, entry->path);
115
116 if (ret == 0 && srch_key->stage != GIT_INDEX_STAGE_ANY)
117 ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
118
119 return ret;
120 }
121
122 static int index_isrch(const void *key, const void *array_member)
123 {
124 const struct entry_srch_key *srch_key = key;
125 const git_index_entry *entry = array_member;
126 int ret;
127
128 ret = strcasecmp(srch_key->path, entry->path);
129
130 if (ret == 0 && srch_key->stage != GIT_INDEX_STAGE_ANY)
131 ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
132
133 return ret;
134 }
135
136 static int index_cmp_path(const void *a, const void *b)
137 {
138 return strcmp((const char *)a, (const char *)b);
139 }
140
141 static int index_icmp_path(const void *a, const void *b)
142 {
143 return strcasecmp((const char *)a, (const char *)b);
144 }
145
146 static int index_srch_path(const void *path, const void *array_member)
147 {
148 const git_index_entry *entry = array_member;
149
150 return strcmp((const char *)path, entry->path);
151 }
152
153 static int index_isrch_path(const void *path, const void *array_member)
154 {
155 const git_index_entry *entry = array_member;
156
157 return strcasecmp((const char *)path, entry->path);
158 }
159
160 static int index_cmp(const void *a, const void *b)
161 {
162 int diff;
163 const git_index_entry *entry_a = a;
164 const git_index_entry *entry_b = b;
165
166 diff = strcmp(entry_a->path, entry_b->path);
167
168 if (diff == 0)
169 diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
170
171 return diff;
172 }
173
174 static int index_icmp(const void *a, const void *b)
175 {
176 int diff;
177 const git_index_entry *entry_a = a;
178 const git_index_entry *entry_b = b;
179
180 diff = strcasecmp(entry_a->path, entry_b->path);
181
182 if (diff == 0)
183 diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
184
185 return diff;
186 }
187
188 static int conflict_name_cmp(const void *a, const void *b)
189 {
190 const git_index_name_entry *name_a = a;
191 const git_index_name_entry *name_b = b;
192
193 if (name_a->ancestor && !name_b->ancestor)
194 return 1;
195
196 if (!name_a->ancestor && name_b->ancestor)
197 return -1;
198
199 if (name_a->ancestor)
200 return strcmp(name_a->ancestor, name_b->ancestor);
201
202 if (!name_a->ours || !name_b->ours)
203 return 0;
204
205 return strcmp(name_a->ours, name_b->ours);
206 }
207
208 /**
209 * TODO: enable this when resolving case insensitive conflicts
210 */
211 #if 0
212 static int conflict_name_icmp(const void *a, const void *b)
213 {
214 const git_index_name_entry *name_a = a;
215 const git_index_name_entry *name_b = b;
216
217 if (name_a->ancestor && !name_b->ancestor)
218 return 1;
219
220 if (!name_a->ancestor && name_b->ancestor)
221 return -1;
222
223 if (name_a->ancestor)
224 return strcasecmp(name_a->ancestor, name_b->ancestor);
225
226 if (!name_a->ours || !name_b->ours)
227 return 0;
228
229 return strcasecmp(name_a->ours, name_b->ours);
230 }
231 #endif
232
233 static int reuc_srch(const void *key, const void *array_member)
234 {
235 const git_index_reuc_entry *reuc = array_member;
236
237 return strcmp(key, reuc->path);
238 }
239
240 static int reuc_isrch(const void *key, const void *array_member)
241 {
242 const git_index_reuc_entry *reuc = array_member;
243
244 return strcasecmp(key, reuc->path);
245 }
246
247 static int reuc_cmp(const void *a, const void *b)
248 {
249 const git_index_reuc_entry *info_a = a;
250 const git_index_reuc_entry *info_b = b;
251
252 return strcmp(info_a->path, info_b->path);
253 }
254
255 static int reuc_icmp(const void *a, const void *b)
256 {
257 const git_index_reuc_entry *info_a = a;
258 const git_index_reuc_entry *info_b = b;
259
260 return strcasecmp(info_a->path, info_b->path);
261 }
262
263 static void index_entry_reuc_free(git_index_reuc_entry *reuc)
264 {
265 if (!reuc)
266 return;
267 git__free(reuc->path);
268 git__free(reuc);
269 }
270
271 static void index_entry_free(git_index_entry *entry)
272 {
273 if (!entry)
274 return;
275 git__free(entry->path);
276 git__free(entry);
277 }
278
279 static unsigned int index_create_mode(unsigned int mode)
280 {
281 if (S_ISLNK(mode))
282 return S_IFLNK;
283
284 if (S_ISDIR(mode) || (mode & S_IFMT) == (S_IFLNK | S_IFDIR))
285 return (S_IFLNK | S_IFDIR);
286
287 return S_IFREG | GIT_PERMS_CANONICAL(mode);
288 }
289
290 static unsigned int index_merge_mode(
291 git_index *index, git_index_entry *existing, unsigned int mode)
292 {
293 if (index->no_symlinks && S_ISREG(mode) &&
294 existing && S_ISLNK(existing->mode))
295 return existing->mode;
296
297 if (index->distrust_filemode && S_ISREG(mode))
298 return (existing && S_ISREG(existing->mode)) ?
299 existing->mode : index_create_mode(0666);
300
301 return index_create_mode(mode);
302 }
303
304 void git_index__set_ignore_case(git_index *index, bool ignore_case)
305 {
306 index->ignore_case = ignore_case;
307
308 index->entries_cmp_path = ignore_case ? index_icmp_path : index_cmp_path;
309 index->entries_search = ignore_case ? index_isrch : index_srch;
310 index->entries_search_path = ignore_case ? index_isrch_path : index_srch_path;
311
312 git_vector_set_cmp(&index->entries, ignore_case ? index_icmp : index_cmp);
313 git_vector_sort(&index->entries);
314
315 index->reuc_search = ignore_case ? reuc_isrch : reuc_srch;
316
317 git_vector_set_cmp(&index->reuc, ignore_case ? reuc_icmp : reuc_cmp);
318 git_vector_sort(&index->reuc);
319 }
320
321 int git_index_open(git_index **index_out, const char *index_path)
322 {
323 git_index *index;
324
325 assert(index_out);
326
327 index = git__calloc(1, sizeof(git_index));
328 GITERR_CHECK_ALLOC(index);
329
330 if (index_path != NULL) {
331 index->index_file_path = git__strdup(index_path);
332 GITERR_CHECK_ALLOC(index->index_file_path);
333
334 /* Check if index file is stored on disk already */
335 if (git_path_exists(index->index_file_path) == true)
336 index->on_disk = 1;
337 }
338
339 if (git_vector_init(&index->entries, 32, index_cmp) < 0 ||
340 git_vector_init(&index->names, 32, conflict_name_cmp) < 0 ||
341 git_vector_init(&index->reuc, 32, reuc_cmp) < 0)
342 return -1;
343
344 index->entries_cmp_path = index_cmp_path;
345 index->entries_search = index_srch;
346 index->entries_search_path = index_srch_path;
347 index->reuc_search = reuc_srch;
348
349 *index_out = index;
350 GIT_REFCOUNT_INC(index);
351
352 return (index_path != NULL) ? git_index_read(index) : 0;
353 }
354
355 int git_index_new(git_index **out)
356 {
357 return git_index_open(out, NULL);
358 }
359
360 static void index_free(git_index *index)
361 {
362 git_index_clear(index);
363 git_vector_free(&index->entries);
364 git_vector_free(&index->names);
365 git_vector_free(&index->reuc);
366
367 git__free(index->index_file_path);
368
369 git__memzero(index, sizeof(*index));
370 git__free(index);
371 }
372
373 void git_index_free(git_index *index)
374 {
375 if (index == NULL)
376 return;
377
378 GIT_REFCOUNT_DEC(index, index_free);
379 }
380
381 static void index_entries_free(git_vector *entries)
382 {
383 size_t i;
384
385 for (i = 0; i < entries->length; ++i)
386 index_entry_free(git__swap(entries->contents[i], NULL));
387
388 git_vector_clear(entries);
389 }
390
391 void git_index_clear(git_index *index)
392 {
393 assert(index);
394
395 index_entries_free(&index->entries);
396 git_index_reuc_clear(index);
397 git_index_name_clear(index);
398
399 git_futils_filestamp_set(&index->stamp, NULL);
400
401 git_tree_cache_free(index->tree);
402 index->tree = NULL;
403 }
404
405 static int create_index_error(int error, const char *msg)
406 {
407 giterr_set(GITERR_INDEX, msg);
408 return error;
409 }
410
411 int git_index_set_caps(git_index *index, unsigned int caps)
412 {
413 unsigned int old_ignore_case;
414
415 assert(index);
416
417 old_ignore_case = index->ignore_case;
418
419 if (caps == GIT_INDEXCAP_FROM_OWNER) {
420 git_repository *repo = INDEX_OWNER(index);
421 int val;
422
423 if (!repo)
424 return create_index_error(
425 -1, "Cannot access repository to set index caps");
426
427 if (!git_repository__cvar(&val, repo, GIT_CVAR_IGNORECASE))
428 index->ignore_case = (val != 0);
429 if (!git_repository__cvar(&val, repo, GIT_CVAR_FILEMODE))
430 index->distrust_filemode = (val == 0);
431 if (!git_repository__cvar(&val, repo, GIT_CVAR_SYMLINKS))
432 index->no_symlinks = (val == 0);
433 }
434 else {
435 index->ignore_case = ((caps & GIT_INDEXCAP_IGNORE_CASE) != 0);
436 index->distrust_filemode = ((caps & GIT_INDEXCAP_NO_FILEMODE) != 0);
437 index->no_symlinks = ((caps & GIT_INDEXCAP_NO_SYMLINKS) != 0);
438 }
439
440 if (old_ignore_case != index->ignore_case) {
441 git_index__set_ignore_case(index, (bool)index->ignore_case);
442 }
443
444 return 0;
445 }
446
447 unsigned int git_index_caps(const git_index *index)
448 {
449 return ((index->ignore_case ? GIT_INDEXCAP_IGNORE_CASE : 0) |
450 (index->distrust_filemode ? GIT_INDEXCAP_NO_FILEMODE : 0) |
451 (index->no_symlinks ? GIT_INDEXCAP_NO_SYMLINKS : 0));
452 }
453
454 int git_index_read(git_index *index)
455 {
456 int error = 0, updated;
457 git_buf buffer = GIT_BUF_INIT;
458 git_futils_filestamp stamp = {0};
459
460 if (!index->index_file_path)
461 return create_index_error(-1,
462 "Failed to read index: The index is in-memory only");
463
464 index->on_disk = git_path_exists(index->index_file_path);
465
466 if (!index->on_disk) {
467 git_index_clear(index);
468 return 0;
469 }
470
471 updated = git_futils_filestamp_check(&stamp, index->index_file_path);
472 if (updated <= 0)
473 return updated;
474
475 error = git_futils_readbuffer(&buffer, index->index_file_path);
476 if (error < 0)
477 return error;
478
479 git_index_clear(index);
480 error = parse_index(index, buffer.ptr, buffer.size);
481
482 if (!error)
483 git_futils_filestamp_set(&index->stamp, &stamp);
484
485 git_buf_free(&buffer);
486 return error;
487 }
488
489 int git_index_write(git_index *index)
490 {
491 git_filebuf file = GIT_FILEBUF_INIT;
492 int error;
493
494 if (!index->index_file_path)
495 return create_index_error(-1,
496 "Failed to read index: The index is in-memory only");
497
498 git_vector_sort(&index->entries);
499 git_vector_sort(&index->reuc);
500
501 if ((error = git_filebuf_open(
502 &file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS)) < 0) {
503 if (error == GIT_ELOCKED)
504 giterr_set(GITERR_INDEX, "The index is locked. This might be due to a concurrrent or crashed process");
505
506 return error;
507 }
508
509 if ((error = write_index(index, &file)) < 0) {
510 git_filebuf_cleanup(&file);
511 return error;
512 }
513
514 if ((error = git_filebuf_commit(&file, GIT_INDEX_FILE_MODE)) < 0)
515 return error;
516
517 error = git_futils_filestamp_check(&index->stamp, index->index_file_path);
518 if (error < 0)
519 return error;
520
521 index->on_disk = 1;
522 return 0;
523 }
524
525 const char * git_index_path(git_index *index)
526 {
527 assert(index);
528 return index->index_file_path;
529 }
530
531 int git_index_write_tree(git_oid *oid, git_index *index)
532 {
533 git_repository *repo;
534
535 assert(oid && index);
536
537 repo = INDEX_OWNER(index);
538
539 if (repo == NULL)
540 return create_index_error(-1, "Failed to write tree. "
541 "The index file is not backed up by an existing repository");
542
543 return git_tree__write_index(oid, index, repo);
544 }
545
546 int git_index_write_tree_to(git_oid *oid, git_index *index, git_repository *repo)
547 {
548 assert(oid && index && repo);
549 return git_tree__write_index(oid, index, repo);
550 }
551
552 size_t git_index_entrycount(const git_index *index)
553 {
554 assert(index);
555 return index->entries.length;
556 }
557
558 const git_index_entry *git_index_get_byindex(
559 git_index *index, size_t n)
560 {
561 assert(index);
562 git_vector_sort(&index->entries);
563 return git_vector_get(&index->entries, n);
564 }
565
566 const git_index_entry *git_index_get_bypath(
567 git_index *index, const char *path, int stage)
568 {
569 size_t pos;
570
571 assert(index);
572
573 git_vector_sort(&index->entries);
574
575 if (git_index__find(&pos, index, path, stage) < 0) {
576 giterr_set(GITERR_INDEX, "Index does not contain %s", path);
577 return NULL;
578 }
579
580 return git_index_get_byindex(index, pos);
581 }
582
583 void git_index_entry__init_from_stat(
584 git_index_entry *entry, struct stat *st, bool trust_mode)
585 {
586 entry->ctime.seconds = (git_time_t)st->st_ctime;
587 entry->mtime.seconds = (git_time_t)st->st_mtime;
588 /* entry->mtime.nanoseconds = st->st_mtimensec; */
589 /* entry->ctime.nanoseconds = st->st_ctimensec; */
590 entry->dev = st->st_rdev;
591 entry->ino = st->st_ino;
592 entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
593 index_create_mode(0666) : index_create_mode(st->st_mode);
594 entry->uid = st->st_uid;
595 entry->gid = st->st_gid;
596 entry->file_size = st->st_size;
597 }
598
599 int git_index_entry__cmp(const void *a, const void *b)
600 {
601 const git_index_entry *entry_a = a;
602 const git_index_entry *entry_b = b;
603
604 return strcmp(entry_a->path, entry_b->path);
605 }
606
607 int git_index_entry__cmp_icase(const void *a, const void *b)
608 {
609 const git_index_entry *entry_a = a;
610 const git_index_entry *entry_b = b;
611
612 return strcasecmp(entry_a->path, entry_b->path);
613 }
614
615 static int index_entry_init(
616 git_index_entry **entry_out, git_index *index, const char *rel_path)
617 {
618 int error = 0;
619 git_index_entry *entry = NULL;
620 struct stat st;
621 git_oid oid;
622
623 if (INDEX_OWNER(index) == NULL)
624 return create_index_error(-1,
625 "Could not initialize index entry. "
626 "Index is not backed up by an existing repository.");
627
628 /* write the blob to disk and get the oid and stat info */
629 error = git_blob__create_from_paths(
630 &oid, &st, INDEX_OWNER(index), NULL, rel_path, 0, true);
631 if (error < 0)
632 return error;
633
634 entry = git__calloc(1, sizeof(git_index_entry));
635 GITERR_CHECK_ALLOC(entry);
636
637 git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
638
639 entry->oid = oid;
640 entry->path = git__strdup(rel_path);
641 GITERR_CHECK_ALLOC(entry->path);
642
643 *entry_out = entry;
644 return 0;
645 }
646
647 static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
648 const char *path,
649 int ancestor_mode, const git_oid *ancestor_oid,
650 int our_mode, const git_oid *our_oid,
651 int their_mode, const git_oid *their_oid)
652 {
653 git_index_reuc_entry *reuc = NULL;
654
655 assert(reuc_out && path);
656
657 *reuc_out = NULL;
658
659 reuc = git__calloc(1, sizeof(git_index_reuc_entry));
660 GITERR_CHECK_ALLOC(reuc);
661
662 reuc->path = git__strdup(path);
663 if (reuc->path == NULL)
664 return -1;
665
666 if ((reuc->mode[0] = ancestor_mode) > 0)
667 git_oid_cpy(&reuc->oid[0], ancestor_oid);
668
669 if ((reuc->mode[1] = our_mode) > 0)
670 git_oid_cpy(&reuc->oid[1], our_oid);
671
672 if ((reuc->mode[2] = their_mode) > 0)
673 git_oid_cpy(&reuc->oid[2], their_oid);
674
675 *reuc_out = reuc;
676 return 0;
677 }
678
679 static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
680 {
681 git_index_entry *entry;
682
683 entry = git__malloc(sizeof(git_index_entry));
684 if (!entry)
685 return NULL;
686
687 memcpy(entry, source_entry, sizeof(git_index_entry));
688
689 /* duplicate the path string so we own it */
690 entry->path = git__strdup(entry->path);
691 if (!entry->path)
692 return NULL;
693
694 return entry;
695 }
696
697 static int index_insert(git_index *index, git_index_entry *entry, int replace)
698 {
699 size_t path_length, position;
700 git_index_entry **existing = NULL;
701
702 assert(index && entry && entry->path != NULL);
703
704 /* make sure that the path length flag is correct */
705 path_length = strlen(entry->path);
706
707 entry->flags &= ~GIT_IDXENTRY_NAMEMASK;
708
709 if (path_length < GIT_IDXENTRY_NAMEMASK)
710 entry->flags |= path_length & GIT_IDXENTRY_NAMEMASK;
711 else
712 entry->flags |= GIT_IDXENTRY_NAMEMASK;
713
714 /* look if an entry with this path already exists */
715 if (!git_index__find(
716 &position, index, entry->path, GIT_IDXENTRY_STAGE(entry))) {
717 existing = (git_index_entry **)&index->entries.contents[position];
718
719 /* update filemode to existing values if stat is not trusted */
720 entry->mode = index_merge_mode(index, *existing, entry->mode);
721 }
722
723 /* if replacing is not requested or no existing entry exists, just
724 * insert entry at the end; the index is no longer sorted
725 */
726 if (!replace || !existing)
727 return git_vector_insert(&index->entries, entry);
728
729 /* exists, replace it (preserving name from existing entry) */
730 git__free(entry->path);
731 entry->path = (*existing)->path;
732 git__free(*existing);
733 *existing = entry;
734
735 return 0;
736 }
737
738 static int index_conflict_to_reuc(git_index *index, const char *path)
739 {
740 const git_index_entry *conflict_entries[3];
741 int ancestor_mode, our_mode, their_mode;
742 git_oid const *ancestor_oid, *our_oid, *their_oid;
743 int ret;
744
745 if ((ret = git_index_conflict_get(&conflict_entries[0],
746 &conflict_entries[1], &conflict_entries[2], index, path)) < 0)
747 return ret;
748
749 ancestor_mode = conflict_entries[0] == NULL ? 0 : conflict_entries[0]->mode;
750 our_mode = conflict_entries[1] == NULL ? 0 : conflict_entries[1]->mode;
751 their_mode = conflict_entries[2] == NULL ? 0 : conflict_entries[2]->mode;
752
753 ancestor_oid = conflict_entries[0] == NULL ? NULL : &conflict_entries[0]->oid;
754 our_oid = conflict_entries[1] == NULL ? NULL : &conflict_entries[1]->oid;
755 their_oid = conflict_entries[2] == NULL ? NULL : &conflict_entries[2]->oid;
756
757 if ((ret = git_index_reuc_add(index, path, ancestor_mode, ancestor_oid,
758 our_mode, our_oid, their_mode, their_oid)) >= 0)
759 ret = git_index_conflict_remove(index, path);
760
761 return ret;
762 }
763
764 int git_index_add_bypath(git_index *index, const char *path)
765 {
766 git_index_entry *entry = NULL;
767 int ret;
768
769 assert(index && path);
770
771 if ((ret = index_entry_init(&entry, index, path)) < 0 ||
772 (ret = index_insert(index, entry, 1)) < 0)
773 goto on_error;
774
775 /* Adding implies conflict was resolved, move conflict entries to REUC */
776 if ((ret = index_conflict_to_reuc(index, path)) < 0 && ret != GIT_ENOTFOUND)
777 goto on_error;
778
779 git_tree_cache_invalidate_path(index->tree, entry->path);
780 return 0;
781
782 on_error:
783 index_entry_free(entry);
784 return ret;
785 }
786
787 int git_index_remove_bypath(git_index *index, const char *path)
788 {
789 int ret;
790
791 assert(index && path);
792
793 if (((ret = git_index_remove(index, path, 0)) < 0 &&
794 ret != GIT_ENOTFOUND) ||
795 ((ret = index_conflict_to_reuc(index, path)) < 0 &&
796 ret != GIT_ENOTFOUND))
797 return ret;
798
799 return 0;
800 }
801
802 int git_index_add(git_index *index, const git_index_entry *source_entry)
803 {
804 git_index_entry *entry = NULL;
805 int ret;
806
807 entry = index_entry_dup(source_entry);
808 if (entry == NULL)
809 return -1;
810
811 if ((ret = index_insert(index, entry, 1)) < 0) {
812 index_entry_free(entry);
813 return ret;
814 }
815
816 git_tree_cache_invalidate_path(index->tree, entry->path);
817 return 0;
818 }
819
820 int git_index_remove(git_index *index, const char *path, int stage)
821 {
822 size_t position;
823 int error;
824 git_index_entry *entry;
825
826 git_vector_sort(&index->entries);
827
828 if (git_index__find(&position, index, path, stage) < 0) {
829 giterr_set(GITERR_INDEX, "Index does not contain %s at stage %d",
830 path, stage);
831 return GIT_ENOTFOUND;
832 }
833
834 entry = git_vector_get(&index->entries, position);
835 if (entry != NULL)
836 git_tree_cache_invalidate_path(index->tree, entry->path);
837
838 error = git_vector_remove(&index->entries, position);
839
840 if (!error)
841 index_entry_free(entry);
842
843 return error;
844 }
845
846 int git_index_remove_directory(git_index *index, const char *dir, int stage)
847 {
848 git_buf pfx = GIT_BUF_INIT;
849 int error = 0;
850 size_t pos;
851 git_index_entry *entry;
852
853 if (git_buf_sets(&pfx, dir) < 0 || git_path_to_dir(&pfx) < 0)
854 return -1;
855
856 git_vector_sort(&index->entries);
857
858 pos = git_index__prefix_position(index, pfx.ptr);
859
860 while (1) {
861 entry = git_vector_get(&index->entries, pos);
862 if (!entry || git__prefixcmp(entry->path, pfx.ptr) != 0)
863 break;
864
865 if (GIT_IDXENTRY_STAGE(entry) != stage) {
866 ++pos;
867 continue;
868 }
869
870 git_tree_cache_invalidate_path(index->tree, entry->path);
871
872 if ((error = git_vector_remove(&index->entries, pos)) < 0)
873 break;
874 index_entry_free(entry);
875
876 /* removed entry at 'pos' so we don't need to increment it */
877 }
878
879 git_buf_free(&pfx);
880
881 return error;
882 }
883
884 int git_index__find(
885 size_t *at_pos, git_index *index, const char *path, int stage)
886 {
887 struct entry_srch_key srch_key;
888
889 assert(path);
890
891 srch_key.path = path;
892 srch_key.stage = stage;
893
894 return git_vector_bsearch2(
895 at_pos, &index->entries, index->entries_search, &srch_key);
896 }
897
898 int git_index_find(size_t *at_pos, git_index *index, const char *path)
899 {
900 size_t pos;
901
902 assert(index && path);
903
904 if (git_vector_bsearch2(&pos, &index->entries, index->entries_search_path, path) < 0) {
905 giterr_set(GITERR_INDEX, "Index does not contain %s", path);
906 return GIT_ENOTFOUND;
907 }
908
909 /* Since our binary search only looked at path, we may be in the
910 * middle of a list of stages.
911 */
912 while (pos > 0) {
913 const git_index_entry *prev = git_vector_get(&index->entries, pos-1);
914
915 if (index->entries_cmp_path(prev->path, path) != 0)
916 break;
917
918 --pos;
919 }
920
921 if (at_pos)
922 *at_pos = pos;
923
924 return 0;
925 }
926
927 size_t git_index__prefix_position(git_index *index, const char *path)
928 {
929 struct entry_srch_key srch_key;
930 size_t pos;
931
932 srch_key.path = path;
933 srch_key.stage = 0;
934
935 git_vector_sort(&index->entries);
936 git_vector_bsearch2(
937 &pos, &index->entries, index->entries_search, &srch_key);
938
939 return pos;
940 }
941
942 int git_index_conflict_add(git_index *index,
943 const git_index_entry *ancestor_entry,
944 const git_index_entry *our_entry,
945 const git_index_entry *their_entry)
946 {
947 git_index_entry *entries[3] = { 0 };
948 unsigned short i;
949 int ret = 0;
950
951 assert (index);
952
953 if ((ancestor_entry != NULL && (entries[0] = index_entry_dup(ancestor_entry)) == NULL) ||
954 (our_entry != NULL && (entries[1] = index_entry_dup(our_entry)) == NULL) ||
955 (their_entry != NULL && (entries[2] = index_entry_dup(their_entry)) == NULL))
956 return -1;
957
958 for (i = 0; i < 3; i++) {
959 if (entries[i] == NULL)
960 continue;
961
962 /* Make sure stage is correct */
963 entries[i]->flags = (entries[i]->flags & ~GIT_IDXENTRY_STAGEMASK) |
964 ((i+1) << GIT_IDXENTRY_STAGESHIFT);
965
966 if ((ret = index_insert(index, entries[i], 1)) < 0)
967 goto on_error;
968 }
969
970 return 0;
971
972 on_error:
973 for (i = 0; i < 3; i++) {
974 if (entries[i] != NULL)
975 index_entry_free(entries[i]);
976 }
977
978 return ret;
979 }
980
981 static int index_conflict__get_byindex(
982 const git_index_entry **ancestor_out,
983 const git_index_entry **our_out,
984 const git_index_entry **their_out,
985 git_index *index,
986 size_t n)
987 {
988 const git_index_entry *conflict_entry;
989 const char *path = NULL;
990 size_t count;
991 int stage, len = 0;
992
993 assert(ancestor_out && our_out && their_out && index);
994
995 *ancestor_out = NULL;
996 *our_out = NULL;
997 *their_out = NULL;
998
999 for (count = git_index_entrycount(index); n < count; ++n) {
1000 conflict_entry = git_vector_get(&index->entries, n);
1001
1002 if (path && index->entries_cmp_path(conflict_entry->path, path) != 0)
1003 break;
1004
1005 stage = GIT_IDXENTRY_STAGE(conflict_entry);
1006 path = conflict_entry->path;
1007
1008 switch (stage) {
1009 case 3:
1010 *their_out = conflict_entry;
1011 len++;
1012 break;
1013 case 2:
1014 *our_out = conflict_entry;
1015 len++;
1016 break;
1017 case 1:
1018 *ancestor_out = conflict_entry;
1019 len++;
1020 break;
1021 default:
1022 break;
1023 };
1024 }
1025
1026 return len;
1027 }
1028
1029 int git_index_conflict_get(
1030 const git_index_entry **ancestor_out,
1031 const git_index_entry **our_out,
1032 const git_index_entry **their_out,
1033 git_index *index,
1034 const char *path)
1035 {
1036 size_t pos;
1037 int len = 0;
1038
1039 assert(ancestor_out && our_out && their_out && index && path);
1040
1041 *ancestor_out = NULL;
1042 *our_out = NULL;
1043 *their_out = NULL;
1044
1045 if (git_index_find(&pos, index, path) < 0)
1046 return GIT_ENOTFOUND;
1047
1048 if ((len = index_conflict__get_byindex(
1049 ancestor_out, our_out, their_out, index, pos)) < 0)
1050 return len;
1051 else if (len == 0)
1052 return GIT_ENOTFOUND;
1053
1054 return 0;
1055 }
1056
1057 int git_index_conflict_remove(git_index *index, const char *path)
1058 {
1059 size_t pos, posmax;
1060 git_index_entry *conflict_entry;
1061 int error = 0;
1062
1063 assert(index && path);
1064
1065 if (git_index_find(&pos, index, path) < 0)
1066 return GIT_ENOTFOUND;
1067
1068 posmax = git_index_entrycount(index);
1069
1070 while (pos < posmax) {
1071 conflict_entry = git_vector_get(&index->entries, pos);
1072
1073 if (index->entries_cmp_path(conflict_entry->path, path) != 0)
1074 break;
1075
1076 if (GIT_IDXENTRY_STAGE(conflict_entry) == 0) {
1077 pos++;
1078 continue;
1079 }
1080
1081 if ((error = git_vector_remove(&index->entries, pos)) < 0)
1082 return error;
1083
1084 index_entry_free(conflict_entry);
1085 posmax--;
1086 }
1087
1088 return 0;
1089 }
1090
1091 static int index_conflicts_match(const git_vector *v, size_t idx)
1092 {
1093 git_index_entry *entry = git_vector_get(v, idx);
1094
1095 if (GIT_IDXENTRY_STAGE(entry) > 0) {
1096 index_entry_free(entry);
1097 return 1;
1098 }
1099
1100 return 0;
1101 }
1102
1103 void git_index_conflict_cleanup(git_index *index)
1104 {
1105 assert(index);
1106 git_vector_remove_matching(&index->entries, index_conflicts_match);
1107 }
1108
1109 int git_index_has_conflicts(const git_index *index)
1110 {
1111 size_t i;
1112 git_index_entry *entry;
1113
1114 assert(index);
1115
1116 git_vector_foreach(&index->entries, i, entry) {
1117 if (GIT_IDXENTRY_STAGE(entry) > 0)
1118 return 1;
1119 }
1120
1121 return 0;
1122 }
1123
1124 int git_index_conflict_iterator_new(
1125 git_index_conflict_iterator **iterator_out,
1126 git_index *index)
1127 {
1128 git_index_conflict_iterator *it = NULL;
1129
1130 assert(iterator_out && index);
1131
1132 it = git__calloc(1, sizeof(git_index_conflict_iterator));
1133 GITERR_CHECK_ALLOC(it);
1134
1135 it->index = index;
1136
1137 *iterator_out = it;
1138 return 0;
1139 }
1140
1141 int git_index_conflict_next(
1142 const git_index_entry **ancestor_out,
1143 const git_index_entry **our_out,
1144 const git_index_entry **their_out,
1145 git_index_conflict_iterator *iterator)
1146 {
1147 const git_index_entry *entry;
1148 int len;
1149
1150 assert(ancestor_out && our_out && their_out && iterator);
1151
1152 *ancestor_out = NULL;
1153 *our_out = NULL;
1154 *their_out = NULL;
1155
1156 while (iterator->cur < iterator->index->entries.length) {
1157 entry = git_index_get_byindex(iterator->index, iterator->cur);
1158
1159 if (git_index_entry_stage(entry) > 0) {
1160 if ((len = index_conflict__get_byindex(
1161 ancestor_out,
1162 our_out,
1163 their_out,
1164 iterator->index,
1165 iterator->cur)) < 0)
1166 return len;
1167
1168 iterator->cur += len;
1169 return 0;
1170 }
1171
1172 iterator->cur++;
1173 }
1174
1175 return GIT_ITEROVER;
1176 }
1177
1178 void git_index_conflict_iterator_free(git_index_conflict_iterator *iterator)
1179 {
1180 if (iterator == NULL)
1181 return;
1182
1183 git__free(iterator);
1184 }
1185
1186 unsigned int git_index_name_entrycount(git_index *index)
1187 {
1188 assert(index);
1189 return (unsigned int)index->names.length;
1190 }
1191
1192 const git_index_name_entry *git_index_name_get_byindex(
1193 git_index *index, size_t n)
1194 {
1195 assert(index);
1196
1197 git_vector_sort(&index->names);
1198 return git_vector_get(&index->names, n);
1199 }
1200
1201 int git_index_name_add(git_index *index,
1202 const char *ancestor, const char *ours, const char *theirs)
1203 {
1204 git_index_name_entry *conflict_name;
1205
1206 assert ((ancestor && ours) || (ancestor && theirs) || (ours && theirs));
1207
1208 conflict_name = git__calloc(1, sizeof(git_index_name_entry));
1209 GITERR_CHECK_ALLOC(conflict_name);
1210
1211 if (ancestor) {
1212 conflict_name->ancestor = git__strdup(ancestor);
1213 GITERR_CHECK_ALLOC(conflict_name->ancestor);
1214 }
1215
1216 if (ours) {
1217 conflict_name->ours = git__strdup(ours);
1218 GITERR_CHECK_ALLOC(conflict_name->ours);
1219 }
1220
1221 if (theirs) {
1222 conflict_name->theirs = git__strdup(theirs);
1223 GITERR_CHECK_ALLOC(conflict_name->theirs);
1224 }
1225
1226 return git_vector_insert(&index->names, conflict_name);
1227 }
1228
1229 void git_index_name_clear(git_index *index)
1230 {
1231 size_t i;
1232 git_index_name_entry *conflict_name;
1233
1234 assert(index);
1235
1236 git_vector_foreach(&index->names, i, conflict_name) {
1237 if (conflict_name->ancestor)
1238 git__free(conflict_name->ancestor);
1239
1240 if (conflict_name->ours)
1241 git__free(conflict_name->ours);
1242
1243 if (conflict_name->theirs)
1244 git__free(conflict_name->theirs);
1245
1246 git__free(conflict_name);
1247 }
1248
1249 git_vector_clear(&index->names);
1250 }
1251
1252 unsigned int git_index_reuc_entrycount(git_index *index)
1253 {
1254 assert(index);
1255 return (unsigned int)index->reuc.length;
1256 }
1257
1258 static int index_reuc_insert(
1259 git_index *index,
1260 git_index_reuc_entry *reuc,
1261 int replace)
1262 {
1263 git_index_reuc_entry **existing = NULL;
1264 size_t position;
1265
1266 assert(index && reuc && reuc->path != NULL);
1267
1268 if (!git_index_reuc_find(&position, index, reuc->path))
1269 existing = (git_index_reuc_entry **)&index->reuc.contents[position];
1270
1271 if (!replace || !existing)
1272 return git_vector_insert(&index->reuc, reuc);
1273
1274 /* exists, replace it */
1275 git__free((*existing)->path);
1276 git__free(*existing);
1277 *existing = reuc;
1278
1279 return 0;
1280 }
1281
1282 int git_index_reuc_add(git_index *index, const char *path,
1283 int ancestor_mode, const git_oid *ancestor_oid,
1284 int our_mode, const git_oid *our_oid,
1285 int their_mode, const git_oid *their_oid)
1286 {
1287 git_index_reuc_entry *reuc = NULL;
1288 int error = 0;
1289
1290 assert(index && path);
1291
1292 if ((error = index_entry_reuc_init(&reuc, path, ancestor_mode, ancestor_oid, our_mode, our_oid, their_mode, their_oid)) < 0 ||
1293 (error = index_reuc_insert(index, reuc, 1)) < 0)
1294 {
1295 index_entry_reuc_free(reuc);
1296 return error;
1297 }
1298
1299 return error;
1300 }
1301
1302 int git_index_reuc_find(size_t *at_pos, git_index *index, const char *path)
1303 {
1304 return git_vector_bsearch2(at_pos, &index->reuc, index->reuc_search, path);
1305 }
1306
1307 const git_index_reuc_entry *git_index_reuc_get_bypath(
1308 git_index *index, const char *path)
1309 {
1310 size_t pos;
1311 assert(index && path);
1312
1313 if (!index->reuc.length)
1314 return NULL;
1315
1316 git_vector_sort(&index->reuc);
1317
1318 if (git_index_reuc_find(&pos, index, path) < 0)
1319 return NULL;
1320
1321 return git_vector_get(&index->reuc, pos);
1322 }
1323
1324 const git_index_reuc_entry *git_index_reuc_get_byindex(
1325 git_index *index, size_t n)
1326 {
1327 assert(index);
1328
1329 git_vector_sort(&index->reuc);
1330 return git_vector_get(&index->reuc, n);
1331 }
1332
1333 int git_index_reuc_remove(git_index *index, size_t position)
1334 {
1335 int error;
1336 git_index_reuc_entry *reuc;
1337
1338 git_vector_sort(&index->reuc);
1339
1340 reuc = git_vector_get(&index->reuc, position);
1341 error = git_vector_remove(&index->reuc, position);
1342
1343 if (!error)
1344 index_entry_reuc_free(reuc);
1345
1346 return error;
1347 }
1348
1349 void git_index_reuc_clear(git_index *index)
1350 {
1351 size_t i;
1352
1353 assert(index);
1354
1355 for (i = 0; i < index->reuc.length; ++i)
1356 index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL));
1357
1358 git_vector_clear(&index->reuc);
1359 }
1360
1361 static int index_error_invalid(const char *message)
1362 {
1363 giterr_set(GITERR_INDEX, "Invalid data in index - %s", message);
1364 return -1;
1365 }
1366
1367 static int read_reuc(git_index *index, const char *buffer, size_t size)
1368 {
1369 const char *endptr;
1370 size_t len;
1371 int i;
1372
1373 /* If called multiple times, the vector might already be initialized */
1374 if (index->reuc._alloc_size == 0 &&
1375 git_vector_init(&index->reuc, 16, reuc_cmp) < 0)
1376 return -1;
1377
1378 while (size) {
1379 git_index_reuc_entry *lost;
1380
1381 len = p_strnlen(buffer, size) + 1;
1382 if (size <= len)
1383 return index_error_invalid("reading reuc entries");
1384
1385 lost = git__calloc(1, sizeof(git_index_reuc_entry));
1386 GITERR_CHECK_ALLOC(lost);
1387
1388 /* read NUL-terminated pathname for entry */
1389 lost->path = git__strdup(buffer);
1390 GITERR_CHECK_ALLOC(lost->path);
1391
1392 size -= len;
1393 buffer += len;
1394
1395 /* read 3 ASCII octal numbers for stage entries */
1396 for (i = 0; i < 3; i++) {
1397 int tmp;
1398
1399 if (git__strtol32(&tmp, buffer, &endptr, 8) < 0 ||
1400 !endptr || endptr == buffer || *endptr ||
1401 (unsigned)tmp > UINT_MAX) {
1402 index_entry_reuc_free(lost);
1403 return index_error_invalid("reading reuc entry stage");
1404 }
1405
1406 lost->mode[i] = tmp;
1407
1408 len = (endptr + 1) - buffer;
1409 if (size <= len) {
1410 index_entry_reuc_free(lost);
1411 return index_error_invalid("reading reuc entry stage");
1412 }
1413
1414 size -= len;
1415 buffer += len;
1416 }
1417
1418 /* read up to 3 OIDs for stage entries */
1419 for (i = 0; i < 3; i++) {
1420 if (!lost->mode[i])
1421 continue;
1422 if (size < 20) {
1423 index_entry_reuc_free(lost);
1424 return index_error_invalid("reading reuc entry oid");
1425 }
1426
1427 git_oid_fromraw(&lost->oid[i], (const unsigned char *) buffer);
1428 size -= 20;
1429 buffer += 20;
1430 }
1431
1432 /* entry was read successfully - insert into reuc vector */
1433 if (git_vector_insert(&index->reuc, lost) < 0)
1434 return -1;
1435 }
1436
1437 /* entries are guaranteed to be sorted on-disk */
1438 index->reuc.sorted = 1;
1439
1440 return 0;
1441 }
1442
1443
1444 static int read_conflict_names(git_index *index, const char *buffer, size_t size)
1445 {
1446 size_t len;
1447
1448 /* This gets called multiple times, the vector might already be initialized */
1449 if (index->names._alloc_size == 0 &&
1450 git_vector_init(&index->names, 16, conflict_name_cmp) < 0)
1451 return -1;
1452
1453 #define read_conflict_name(ptr) \
1454 len = p_strnlen(buffer, size) + 1; \
1455 if (size < len) \
1456 return index_error_invalid("reading conflict name entries"); \
1457 \
1458 if (len == 1) \
1459 ptr = NULL; \
1460 else { \
1461 ptr = git__malloc(len); \
1462 GITERR_CHECK_ALLOC(ptr); \
1463 memcpy(ptr, buffer, len); \
1464 } \
1465 \
1466 buffer += len; \
1467 size -= len;
1468
1469 while (size) {
1470 git_index_name_entry *conflict_name = git__calloc(1, sizeof(git_index_name_entry));
1471 GITERR_CHECK_ALLOC(conflict_name);
1472
1473 read_conflict_name(conflict_name->ancestor);
1474 read_conflict_name(conflict_name->ours);
1475 read_conflict_name(conflict_name->theirs);
1476
1477 if (git_vector_insert(&index->names, conflict_name) < 0)
1478 return -1;
1479 }
1480
1481 #undef read_conflict_name
1482
1483 /* entries are guaranteed to be sorted on-disk */
1484 index->names.sorted = 1;
1485
1486 return 0;
1487 }
1488
1489 static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size)
1490 {
1491 size_t path_length, entry_size;
1492 uint16_t flags_raw;
1493 const char *path_ptr;
1494 const struct entry_short *source = buffer;
1495
1496 if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
1497 return 0;
1498
1499 memset(dest, 0x0, sizeof(git_index_entry));
1500
1501 dest->ctime.seconds = (git_time_t)ntohl(source->ctime.seconds);
1502 dest->ctime.nanoseconds = ntohl(source->ctime.nanoseconds);
1503 dest->mtime.seconds = (git_time_t)ntohl(source->mtime.seconds);
1504 dest->mtime.nanoseconds = ntohl(source->mtime.nanoseconds);
1505 dest->dev = ntohl(source->dev);
1506 dest->ino = ntohl(source->ino);
1507 dest->mode = ntohl(source->mode);
1508 dest->uid = ntohl(source->uid);
1509 dest->gid = ntohl(source->gid);
1510 dest->file_size = ntohl(source->file_size);
1511 git_oid_cpy(&dest->oid, &source->oid);
1512 dest->flags = ntohs(source->flags);
1513
1514 if (dest->flags & GIT_IDXENTRY_EXTENDED) {
1515 const struct entry_long *source_l = (const struct entry_long *)source;
1516 path_ptr = source_l->path;
1517
1518 flags_raw = ntohs(source_l->flags_extended);
1519 memcpy(&dest->flags_extended, &flags_raw, 2);
1520 } else
1521 path_ptr = source->path;
1522
1523 path_length = dest->flags & GIT_IDXENTRY_NAMEMASK;
1524
1525 /* if this is a very long string, we must find its
1526 * real length without overflowing */
1527 if (path_length == 0xFFF) {
1528 const char *path_end;
1529
1530 path_end = memchr(path_ptr, '\0', buffer_size);
1531 if (path_end == NULL)
1532 return 0;
1533
1534 path_length = path_end - path_ptr;
1535 }
1536
1537 if (dest->flags & GIT_IDXENTRY_EXTENDED)
1538 entry_size = long_entry_size(path_length);
1539 else
1540 entry_size = short_entry_size(path_length);
1541
1542 if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
1543 return 0;
1544
1545 dest->path = git__strdup(path_ptr);
1546 assert(dest->path);
1547
1548 return entry_size;
1549 }
1550
1551 static int read_header(struct index_header *dest, const void *buffer)
1552 {
1553 const struct index_header *source = buffer;
1554
1555 dest->signature = ntohl(source->signature);
1556 if (dest->signature != INDEX_HEADER_SIG)
1557 return index_error_invalid("incorrect header signature");
1558
1559 dest->version = ntohl(source->version);
1560 if (dest->version != INDEX_VERSION_NUMBER_EXT &&
1561 dest->version != INDEX_VERSION_NUMBER)
1562 return index_error_invalid("incorrect header version");
1563
1564 dest->entry_count = ntohl(source->entry_count);
1565 return 0;
1566 }
1567
1568 static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size)
1569 {
1570 const struct index_extension *source;
1571 struct index_extension dest;
1572 size_t total_size;
1573
1574 source = (const struct index_extension *)(buffer);
1575
1576 memcpy(dest.signature, source->signature, 4);
1577 dest.extension_size = ntohl(source->extension_size);
1578
1579 total_size = dest.extension_size + sizeof(struct index_extension);
1580
1581 if (dest.extension_size > total_size ||
1582 buffer_size < total_size ||
1583 buffer_size - total_size < INDEX_FOOTER_SIZE)
1584 return 0;
1585
1586 /* optional extension */
1587 if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
1588 /* tree cache */
1589 if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
1590 if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size) < 0)
1591 return 0;
1592 } else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
1593 if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
1594 return 0;
1595 } else if (memcmp(dest.signature, INDEX_EXT_CONFLICT_NAME_SIG, 4) == 0) {
1596 if (read_conflict_names(index, buffer + 8, dest.extension_size) < 0)
1597 return 0;
1598 }
1599 /* else, unsupported extension. We cannot parse this, but we can skip
1600 * it by returning `total_size */
1601 } else {
1602 /* we cannot handle non-ignorable extensions;
1603 * in fact they aren't even defined in the standard */
1604 return 0;
1605 }
1606
1607 return total_size;
1608 }
1609
1610 static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
1611 {
1612 unsigned int i;
1613 struct index_header header = { 0 };
1614 git_oid checksum_calculated, checksum_expected;
1615
1616 #define seek_forward(_increase) { \
1617 if (_increase >= buffer_size) \
1618 return index_error_invalid("ran out of data while parsing"); \
1619 buffer += _increase; \
1620 buffer_size -= _increase;\
1621 }
1622
1623 if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE)
1624 return index_error_invalid("insufficient buffer space");
1625
1626 /* Precalculate the SHA1 of the files's contents -- we'll match it to
1627 * the provided SHA1 in the footer */
1628 git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE);
1629
1630 /* Parse header */
1631 if (read_header(&header, buffer) < 0)
1632 return -1;
1633
1634 seek_forward(INDEX_HEADER_SIZE);
1635
1636 git_vector_clear(&index->entries);
1637
1638 /* Parse all the entries */
1639 for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
1640 size_t entry_size;
1641 git_index_entry *entry;
1642
1643 entry = git__malloc(sizeof(git_index_entry));
1644 GITERR_CHECK_ALLOC(entry);
1645
1646 entry_size = read_entry(entry, buffer, buffer_size);
1647
1648 /* 0 bytes read means an object corruption */
1649 if (entry_size == 0)
1650 return index_error_invalid("invalid entry");
1651
1652 if (git_vector_insert(&index->entries, entry) < 0)
1653 return -1;
1654
1655 seek_forward(entry_size);
1656 }
1657
1658 if (i != header.entry_count)
1659 return index_error_invalid("header entries changed while parsing");
1660
1661 /* There's still space for some extensions! */
1662 while (buffer_size > INDEX_FOOTER_SIZE) {
1663 size_t extension_size;
1664
1665 extension_size = read_extension(index, buffer, buffer_size);
1666
1667 /* see if we have read any bytes from the extension */
1668 if (extension_size == 0)
1669 return index_error_invalid("extension is truncated");
1670
1671 seek_forward(extension_size);
1672 }
1673
1674 if (buffer_size != INDEX_FOOTER_SIZE)
1675 return index_error_invalid("buffer size does not match index footer size");
1676
1677 /* 160-bit SHA-1 over the content of the index file before this checksum. */
1678 git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer);
1679
1680 if (git_oid__cmp(&checksum_calculated, &checksum_expected) != 0)
1681 return index_error_invalid("calculated checksum does not match expected");
1682
1683 #undef seek_forward
1684
1685 /* Entries are stored case-sensitively on disk. */
1686 index->entries.sorted = !index->ignore_case;
1687 git_vector_sort(&index->entries);
1688
1689 return 0;
1690 }
1691
1692 static bool is_index_extended(git_index *index)
1693 {
1694 size_t i, extended;
1695 git_index_entry *entry;
1696
1697 extended = 0;
1698
1699 git_vector_foreach(&index->entries, i, entry) {
1700 entry->flags &= ~GIT_IDXENTRY_EXTENDED;
1701 if (entry->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS) {
1702 extended++;
1703 entry->flags |= GIT_IDXENTRY_EXTENDED;
1704 }
1705 }
1706
1707 return (extended > 0);
1708 }
1709
1710 static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
1711 {
1712 void *mem = NULL;
1713 struct entry_short *ondisk;
1714 size_t path_len, disk_size;
1715 char *path;
1716
1717 path_len = strlen(entry->path);
1718
1719 if (entry->flags & GIT_IDXENTRY_EXTENDED)
1720 disk_size = long_entry_size(path_len);
1721 else
1722 disk_size = short_entry_size(path_len);
1723
1724 if (git_filebuf_reserve(file, &mem, disk_size) < 0)
1725 return -1;
1726
1727 ondisk = (struct entry_short *)mem;
1728
1729 memset(ondisk, 0x0, disk_size);
1730
1731 /**
1732 * Yes, we have to truncate.
1733 *
1734 * The on-disk format for Index entries clearly defines
1735 * the time and size fields to be 4 bytes each -- so even if
1736 * we store these values with 8 bytes on-memory, they must
1737 * be truncated to 4 bytes before writing to disk.
1738 *
1739 * In 2038 I will be either too dead or too rich to care about this
1740 */
1741 ondisk->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
1742 ondisk->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
1743 ondisk->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
1744 ondisk->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
1745 ondisk->dev = htonl(entry->dev);
1746 ondisk->ino = htonl(entry->ino);
1747 ondisk->mode = htonl(entry->mode);
1748 ondisk->uid = htonl(entry->uid);
1749 ondisk->gid = htonl(entry->gid);
1750 ondisk->file_size = htonl((uint32_t)entry->file_size);
1751
1752 git_oid_cpy(&ondisk->oid, &entry->oid);
1753
1754 ondisk->flags = htons(entry->flags);
1755
1756 if (entry->flags & GIT_IDXENTRY_EXTENDED) {
1757 struct entry_long *ondisk_ext;
1758 ondisk_ext = (struct entry_long *)ondisk;
1759 ondisk_ext->flags_extended = htons(entry->flags_extended);
1760 path = ondisk_ext->path;
1761 }
1762 else
1763 path = ondisk->path;
1764
1765 memcpy(path, entry->path, path_len);
1766
1767 return 0;
1768 }
1769
1770 static int write_entries(git_index *index, git_filebuf *file)
1771 {
1772 int error = 0;
1773 size_t i;
1774 git_vector case_sorted;
1775 git_index_entry *entry;
1776 git_vector *out = &index->entries;
1777
1778 /* If index->entries is sorted case-insensitively, then we need
1779 * to re-sort it case-sensitively before writing */
1780 if (index->ignore_case) {
1781 git_vector_dup(&case_sorted, &index->entries, index_cmp);
1782 git_vector_sort(&case_sorted);
1783 out = &case_sorted;
1784 }
1785
1786 git_vector_foreach(out, i, entry)
1787 if ((error = write_disk_entry(file, entry)) < 0)
1788 break;
1789
1790 if (index->ignore_case)
1791 git_vector_free(&case_sorted);
1792
1793 return error;
1794 }
1795
1796 static int write_extension(git_filebuf *file, struct index_extension *header, git_buf *data)
1797 {
1798 struct index_extension ondisk;
1799 int error = 0;
1800
1801 memset(&ondisk, 0x0, sizeof(struct index_extension));
1802 memcpy(&ondisk, header, 4);
1803 ondisk.extension_size = htonl(header->extension_size);
1804
1805 if ((error = git_filebuf_write(file, &ondisk, sizeof(struct index_extension))) == 0)
1806 error = git_filebuf_write(file, data->ptr, data->size);
1807
1808 return error;
1809 }
1810
1811 static int create_name_extension_data(git_buf *name_buf, git_index_name_entry *conflict_name)
1812 {
1813 int error = 0;
1814
1815 if (conflict_name->ancestor == NULL)
1816 error = git_buf_put(name_buf, "\0", 1);
1817 else
1818 error = git_buf_put(name_buf, conflict_name->ancestor, strlen(conflict_name->ancestor) + 1);
1819
1820 if (error != 0)
1821 goto on_error;
1822
1823 if (conflict_name->ours == NULL)
1824 error = git_buf_put(name_buf, "\0", 1);
1825 else
1826 error = git_buf_put(name_buf, conflict_name->ours, strlen(conflict_name->ours) + 1);
1827
1828 if (error != 0)
1829 goto on_error;
1830
1831 if (conflict_name->theirs == NULL)
1832 error = git_buf_put(name_buf, "\0", 1);
1833 else
1834 error = git_buf_put(name_buf, conflict_name->theirs, strlen(conflict_name->theirs) + 1);
1835
1836 on_error:
1837 return error;
1838 }
1839
1840 static int write_name_extension(git_index *index, git_filebuf *file)
1841 {
1842 git_buf name_buf = GIT_BUF_INIT;
1843 git_vector *out = &index->names;
1844 git_index_name_entry *conflict_name;
1845 struct index_extension extension;
1846 size_t i;
1847 int error = 0;
1848
1849 git_vector_foreach(out, i, conflict_name) {
1850 if ((error = create_name_extension_data(&name_buf, conflict_name)) < 0)
1851 goto done;
1852 }
1853
1854 memset(&extension, 0x0, sizeof(struct index_extension));
1855 memcpy(&extension.signature, INDEX_EXT_CONFLICT_NAME_SIG, 4);
1856 extension.extension_size = (uint32_t)name_buf.size;
1857
1858 error = write_extension(file, &extension, &name_buf);
1859
1860 git_buf_free(&name_buf);
1861
1862 done:
1863 return error;
1864 }
1865
1866 static int create_reuc_extension_data(git_buf *reuc_buf, git_index_reuc_entry *reuc)
1867 {
1868 int i;
1869 int error = 0;
1870
1871 if ((error = git_buf_put(reuc_buf, reuc->path, strlen(reuc->path) + 1)) < 0)
1872 return error;
1873
1874 for (i = 0; i < 3; i++) {
1875 if ((error = git_buf_printf(reuc_buf, "%o", reuc->mode[i])) < 0 ||
1876 (error = git_buf_put(reuc_buf, "\0", 1)) < 0)
1877 return error;
1878 }
1879
1880 for (i = 0; i < 3; i++) {
1881 if (reuc->mode[i] && (error = git_buf_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0)
1882 return error;
1883 }
1884
1885 return 0;
1886 }
1887
1888 static int write_reuc_extension(git_index *index, git_filebuf *file)
1889 {
1890 git_buf reuc_buf = GIT_BUF_INIT;
1891 git_vector *out = &index->reuc;
1892 git_index_reuc_entry *reuc;
1893 struct index_extension extension;
1894 size_t i;
1895 int error = 0;
1896
1897 git_vector_foreach(out, i, reuc) {
1898 if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
1899 goto done;
1900 }
1901
1902 memset(&extension, 0x0, sizeof(struct index_extension));
1903 memcpy(&extension.signature, INDEX_EXT_UNMERGED_SIG, 4);
1904 extension.extension_size = (uint32_t)reuc_buf.size;
1905
1906 error = write_extension(file, &extension, &reuc_buf);
1907
1908 git_buf_free(&reuc_buf);
1909
1910 done:
1911 return error;
1912 }
1913
1914 static int write_index(git_index *index, git_filebuf *file)
1915 {
1916 git_oid hash_final;
1917 struct index_header header;
1918 bool is_extended;
1919
1920 assert(index && file);
1921
1922 is_extended = is_index_extended(index);
1923
1924 header.signature = htonl(INDEX_HEADER_SIG);
1925 header.version = htonl(is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER);
1926 header.entry_count = htonl((uint32_t)index->entries.length);
1927
1928 if (git_filebuf_write(file, &header, sizeof(struct index_header)) < 0)
1929 return -1;
1930
1931 if (write_entries(index, file) < 0)
1932 return -1;
1933
1934 /* TODO: write tree cache extension */
1935
1936 /* write the rename conflict extension */
1937 if (index->names.length > 0 && write_name_extension(index, file) < 0)
1938 return -1;
1939
1940 /* write the reuc extension */
1941 if (index->reuc.length > 0 && write_reuc_extension(index, file) < 0)
1942 return -1;
1943
1944 /* get out the hash for all the contents we've appended to the file */
1945 git_filebuf_hash(&hash_final, file);
1946
1947 /* write it at the end of the file */
1948 return git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ);
1949 }
1950
1951 int git_index_entry_stage(const git_index_entry *entry)
1952 {
1953 return GIT_IDXENTRY_STAGE(entry);
1954 }
1955
1956 typedef struct read_tree_data {
1957 git_vector *old_entries;
1958 git_vector *new_entries;
1959 git_vector_cmp entries_search;
1960 } read_tree_data;
1961
1962 static int read_tree_cb(
1963 const char *root, const git_tree_entry *tentry, void *payload)
1964 {
1965 read_tree_data *data = payload;
1966 git_index_entry *entry = NULL, *old_entry;
1967 git_buf path = GIT_BUF_INIT;
1968
1969 if (git_tree_entry__is_tree(tentry))
1970 return 0;
1971
1972 if (git_buf_joinpath(&path, root, tentry->filename) < 0)
1973 return -1;
1974
1975 entry = git__calloc(1, sizeof(git_index_entry));
1976 GITERR_CHECK_ALLOC(entry);
1977
1978 entry->mode = tentry->attr;
1979 entry->oid = tentry->oid;
1980
1981 /* look for corresponding old entry and copy data to new entry */
1982 if (data->old_entries) {
1983 size_t pos;
1984 struct entry_srch_key skey;
1985
1986 skey.path = path.ptr;
1987 skey.stage = 0;
1988
1989 if (!git_vector_bsearch2(
1990 &pos, data->old_entries, data->entries_search, &skey) &&
1991 (old_entry = git_vector_get(data->old_entries, pos)) != NULL &&
1992 entry->mode == old_entry->mode &&
1993 git_oid_equal(&entry->oid, &old_entry->oid))
1994 {
1995 memcpy(entry, old_entry, sizeof(*entry));
1996 entry->flags_extended = 0;
1997 }
1998 }
1999
2000 if (path.size < GIT_IDXENTRY_NAMEMASK)
2001 entry->flags = path.size & GIT_IDXENTRY_NAMEMASK;
2002 else
2003 entry->flags = GIT_IDXENTRY_NAMEMASK;
2004
2005 entry->path = git_buf_detach(&path);
2006 git_buf_free(&path);
2007
2008 if (git_vector_insert(data->new_entries, entry) < 0) {
2009 index_entry_free(entry);
2010 return -1;
2011 }
2012
2013 return 0;
2014 }
2015
2016 int git_index_read_tree(git_index *index, const git_tree *tree)
2017 {
2018 int error = 0;
2019 git_vector entries = GIT_VECTOR_INIT;
2020 read_tree_data data;
2021
2022 git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
2023
2024 data.old_entries = &index->entries;
2025 data.new_entries = &entries;
2026 data.entries_search = index->entries_search;
2027
2028 git_vector_sort(&index->entries);
2029
2030 error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data);
2031
2032 git_vector_sort(&entries);
2033
2034 git_index_clear(index);
2035
2036 git_vector_swap(&entries, &index->entries);
2037 git_vector_free(&entries);
2038
2039 return error;
2040 }
2041
2042 git_repository *git_index_owner(const git_index *index)
2043 {
2044 return INDEX_OWNER(index);
2045 }
2046
2047 int git_index_add_all(
2048 git_index *index,
2049 const git_strarray *paths,
2050 unsigned int flags,
2051 git_index_matched_path_cb cb,
2052 void *payload)
2053 {
2054 int error;
2055 git_repository *repo;
2056 git_iterator *wditer = NULL;
2057 const git_index_entry *wd = NULL;
2058 git_index_entry *entry;
2059 git_pathspec ps;
2060 const char *match;
2061 size_t existing;
2062 bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0;
2063 int ignorecase;
2064 git_oid blobid;
2065
2066 assert(index);
2067
2068 if (INDEX_OWNER(index) == NULL)
2069 return create_index_error(-1,
2070 "Could not add paths to index. "
2071 "Index is not backed up by an existing repository.");
2072
2073 repo = INDEX_OWNER(index);
2074 if ((error = git_repository__ensure_not_bare(repo, "index add all")) < 0)
2075 return error;
2076
2077 if (git_repository__cvar(&ignorecase, repo, GIT_CVAR_IGNORECASE) < 0)
2078 return -1;
2079
2080 if ((error = git_pathspec__init(&ps, paths)) < 0)
2081 return error;
2082
2083 /* optionally check that pathspec doesn't mention any ignored files */
2084 if ((flags & GIT_INDEX_ADD_CHECK_PATHSPEC) != 0 &&
2085 (flags & GIT_INDEX_ADD_FORCE) == 0 &&
2086 (error = git_ignore__check_pathspec_for_exact_ignores(
2087 repo, &ps.pathspec, no_fnmatch)) < 0)
2088 goto cleanup;
2089
2090 if ((error = git_iterator_for_workdir(
2091 &wditer, repo, 0, ps.prefix, ps.prefix)) < 0)
2092 goto cleanup;
2093
2094 while (!(error = git_iterator_advance(&wd, wditer))) {
2095
2096 /* check if path actually matches */
2097 if (!git_pathspec__match(
2098 &ps.pathspec, wd->path, no_fnmatch, (bool)ignorecase, &match, NULL))
2099 continue;
2100
2101 /* skip ignored items that are not already in the index */
2102 if ((flags & GIT_INDEX_ADD_FORCE) == 0 &&
2103 git_iterator_current_is_ignored(wditer) &&
2104 git_index__find(&existing, index, wd->path, 0) < 0)
2105 continue;
2106
2107 /* issue notification callback if requested */
2108 if (cb && (error = cb(wd->path, match, payload)) != 0) {
2109 if (error > 0) /* return > 0 means skip this one */
2110 continue;
2111 if (error < 0) { /* return < 0 means abort */
2112 giterr_clear();
2113 error = GIT_EUSER;
2114 break;
2115 }
2116 }
2117
2118 /* TODO: Should we check if the file on disk is already an exact
2119 * match to the file in the index and skip this work if it is?
2120 */
2121
2122 /* write the blob to disk and get the oid */
2123 if ((error = git_blob_create_fromworkdir(&blobid, repo, wd->path)) < 0)
2124 break;
2125
2126 /* make the new entry to insert */
2127 if ((entry = index_entry_dup(wd)) == NULL) {
2128 error = -1;
2129 break;
2130 }
2131 entry->oid = blobid;
2132
2133 /* add working directory item to index */
2134 if ((error = index_insert(index, entry, 1)) < 0) {
2135 index_entry_free(entry);
2136 break;
2137 }
2138
2139 git_tree_cache_invalidate_path(index->tree, wd->path);
2140
2141 /* add implies conflict resolved, move conflict entries to REUC */
2142 if ((error = index_conflict_to_reuc(index, wd->path)) < 0) {
2143 if (error != GIT_ENOTFOUND)
2144 break;
2145 giterr_clear();
2146 }
2147 }
2148
2149 if (error == GIT_ITEROVER)
2150 error = 0;
2151
2152 cleanup:
2153 git_iterator_free(wditer);
2154 git_pathspec__clear(&ps);
2155
2156 return error;
2157 }
2158
2159 enum {
2160 INDEX_ACTION_NONE = 0,
2161 INDEX_ACTION_UPDATE = 1,
2162 INDEX_ACTION_REMOVE = 2,
2163 };
2164
2165 static int index_apply_to_all(
2166 git_index *index,
2167 int action,
2168 const git_strarray *paths,
2169 git_index_matched_path_cb cb,
2170 void *payload)
2171 {
2172 int error = 0;
2173 size_t i;
2174 git_pathspec ps;
2175 const char *match;
2176 git_buf path = GIT_BUF_INIT;
2177
2178 assert(index);
2179
2180 if ((error = git_pathspec__init(&ps, paths)) < 0)
2181 return error;
2182
2183 git_vector_sort(&index->entries);
2184
2185 for (i = 0; !error && i < index->entries.length; ++i) {
2186 git_index_entry *entry = git_vector_get(&index->entries, i);
2187
2188 /* check if path actually matches */
2189 if (!git_pathspec__match(
2190 &ps.pathspec, entry->path, false, (bool)index->ignore_case,
2191 &match, NULL))
2192 continue;
2193
2194 /* issue notification callback if requested */
2195 if (cb && (error = cb(entry->path, match, payload)) != 0) {
2196 if (error > 0) { /* return > 0 means skip this one */
2197 error = 0;
2198 continue;
2199 }
2200 if (error < 0) { /* return < 0 means abort */
2201 giterr_clear();
2202 error = GIT_EUSER;
2203 break;
2204 }
2205 }
2206
2207 /* index manipulation may alter entry, so don't depend on it */
2208 if ((error = git_buf_sets(&path, entry->path)) < 0)
2209 break;
2210
2211 switch (action) {
2212 case INDEX_ACTION_NONE:
2213 break;
2214 case INDEX_ACTION_UPDATE:
2215 error = git_index_add_bypath(index, path.ptr);
2216
2217 if (error == GIT_ENOTFOUND) {
2218 giterr_clear();
2219
2220 error = git_index_remove_bypath(index, path.ptr);
2221
2222 if (!error) /* back up foreach if we removed this */
2223 i--;
2224 }
2225 break;
2226 case INDEX_ACTION_REMOVE:
2227 if (!(error = git_index_remove_bypath(index, path.ptr)))
2228 i--; /* back up foreach if we removed this */
2229 break;
2230 default:
2231 giterr_set(GITERR_INVALID, "Unknown index action %d", action);
2232 error = -1;
2233 break;
2234 }
2235 }
2236
2237 git_buf_free(&path);
2238 git_pathspec__clear(&ps);
2239
2240 return error;
2241 }
2242
2243 int git_index_remove_all(
2244 git_index *index,
2245 const git_strarray *pathspec,
2246 git_index_matched_path_cb cb,
2247 void *payload)
2248 {
2249 return index_apply_to_all(
2250 index, INDEX_ACTION_REMOVE, pathspec, cb, payload);
2251 }
2252
2253 int git_index_update_all(
2254 git_index *index,
2255 const git_strarray *pathspec,
2256 git_index_matched_path_cb cb,
2257 void *payload)
2258 {
2259 return index_apply_to_all(
2260 index, INDEX_ACTION_UPDATE, pathspec, cb, payload);
2261 }