1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_index_h__
#define INCLUDE_index_h__
#include "fileops.h"
#include "filebuf.h"
#include "vector.h"
#include "idxmap.h"
#include "tree-cache.h"
#include "git2/odb.h"
#include "git2/index.h"
#define GIT_INDEX_FILE "index"
#define GIT_INDEX_FILE_MODE 0666
struct git_index {
git_refcount rc;
char *index_file_path;
git_futils_filestamp stamp;
git_oid checksum; /* checksum at the end of the file */
git_vector entries;
git_idxmap *entries_map;
git_mutex lock; /* lock held while entries is being changed */
git_vector deleted; /* deleted entries if readers > 0 */
git_atomic readers; /* number of active iterators */
unsigned int on_disk:1;
unsigned int ignore_case:1;
unsigned int distrust_filemode:1;
unsigned int no_symlinks:1;
git_tree_cache *tree;
git_pool tree_pool;
git_vector names;
git_vector reuc;
git_vector_cmp entries_cmp_path;
git_vector_cmp entries_search;
git_vector_cmp entries_search_path;
git_vector_cmp reuc_search;
};
struct git_index_conflict_iterator {
git_index *index;
size_t cur;
};
extern void git_index_entry__init_from_stat(
git_index_entry *entry, struct stat *st, bool trust_mode);
/* Index entry comparison functions for array sorting */
extern int git_index_entry_cmp(const void *a, const void *b);
extern int git_index_entry_icmp(const void *a, const void *b);
/* Index entry search functions for search using a search spec */
extern int git_index_entry_srch(const void *a, const void *b);
extern int git_index_entry_isrch(const void *a, const void *b);
/* Index time handling functions */
GIT_INLINE(bool) git_index_time_eq(const git_index_time *one, const git_index_time *two)
{
if (one->seconds != two->seconds)
return false;
#ifdef GIT_USE_NSEC
if (one->nanoseconds != two->nanoseconds)
return false;
#endif
return true;
}
/*
* Test if the given index time is newer than the given existing index entry.
* If the timestamps are exactly equivalent, then the given index time is
* considered "racily newer" than the existing index entry.
*/
GIT_INLINE(bool) git_index_entry_newer_than_index(
const git_index_entry *entry, git_index *index)
{
/* If we never read the index, we can't have this race either */
if (!index || index->stamp.mtime.tv_sec == 0)
return false;
/* If the timestamp is the same or newer than the index, it's racy */
#if defined(GIT_USE_NSEC)
if ((int32_t)index->stamp.tv_sec < entry->mtime.seconds)
return true;
else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds)
return false;
else
return (uint32_t)index->stamp.mtime.tv_nsec <= entry->mtime.nanoseconds;
#else
return ((int32_t)index->stamp.mtime.tv_sec) <= entry->mtime.seconds;
#endif
}
/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist
* (but not setting an error message).
*
* `at_pos` is set to the position where it is or would be inserted.
* Pass `path_len` as strlen of path or 0 to call strlen internally.
*/
extern int git_index__find_pos(
size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage);
extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
extern unsigned int git_index__create_mode(unsigned int mode);
GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
{
return &index->stamp;
}
extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum);
/* Copy the current entries vector *and* increment the index refcount.
* Call `git_index__release_snapshot` when done.
*/
extern int git_index_snapshot_new(git_vector *snap, git_index *index);
extern void git_index_snapshot_release(git_vector *snap, git_index *index);
/* Allow searching in a snapshot; entries must already be sorted! */
extern int git_index_snapshot_find(
size_t *at_pos, git_vector *snap, git_vector_cmp entry_srch,
const char *path, size_t path_len, int stage);
/* Replace an index with a new index */
int git_index_read_index(git_index *index, const git_index *new_index);
typedef struct {
git_index *index;
git_filebuf file;
unsigned int should_write:1;
} git_indexwriter;
#define GIT_INDEXWRITER_INIT { NULL, GIT_FILEBUF_INIT }
/* Lock the index for eventual writing. */
extern int git_indexwriter_init(git_indexwriter *writer, git_index *index);
/* Lock the index for eventual writing by a repository operation: a merge,
* revert, cherry-pick or a rebase. Note that the given checkout strategy
* will be updated for the operation's use so that checkout will not write
* the index.
*/
extern int git_indexwriter_init_for_operation(
git_indexwriter *writer,
git_repository *repo,
unsigned int *checkout_strategy);
/* Write the index and unlock it. */
extern int git_indexwriter_commit(git_indexwriter *writer);
/* Cleanup an index writing session, unlocking the file (if it is still
* locked and freeing any data structures.
*/
extern void git_indexwriter_cleanup(git_indexwriter *writer);
#endif
|