Raw
1 #ifndef COMMIT_GRAPH_H
2 #define COMMIT_GRAPH_H
3
4 #include "odb.h"
5 #include "oidset.h"
6
7 #define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH"
8 #define GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE "GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE"
9 #define GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS "GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS"
10
11 /*
12 * This environment variable controls whether commits looked up via the
13 * commit graph will be double checked to exist in the object database.
14 */
15 #define GIT_COMMIT_GRAPH_PARANOIA "GIT_COMMIT_GRAPH_PARANOIA"
16
17 /*
18 * This method is only used to enhance coverage of the commit-graph
19 * feature in the test suite with the GIT_TEST_COMMIT_GRAPH and
20 * GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS environment variables. Do not
21 * call this method outside of a builtin, and only if you know what
22 * you are doing!
23 */
24 void git_test_write_commit_graph_or_die(struct odb_source *source);
25
26 struct commit;
27 struct bloom_filter_settings;
28 struct repository;
29 struct object_database;
30 struct string_list;
31
32 char *get_commit_graph_filename(struct odb_source *source);
33 char *get_commit_graph_chain_filename(struct odb_source *source);
34 int open_commit_graph(const char *graph_file, int *fd, struct stat *st);
35 int open_commit_graph_chain(const char *chain_file, int *fd, struct stat *st,
36 const struct git_hash_algo *hash_algo);
37
38 /*
39 * Given a commit struct, try to fill the commit struct info, including:
40 * 1. tree object
41 * 2. date
42 * 3. parents.
43 *
44 * Returns 1 if and only if the commit was found in the packed graph.
45 *
46 * See parse_commit_buffer() for the fallback after this call.
47 */
48 int parse_commit_in_graph(struct repository *r, struct commit *item);
49
50 /*
51 * Fills `*pos` with the graph position of `c`, and returns the graph `c` is
52 * found in, or NULL otherwise. Initializes the commit-graphs belonging to
53 * `r` if it hasn't been already.
54 *
55 * Note: this is a low-level helper that does not alter any slab data
56 * associated with `c`. Useful in circumstances where the slab data is
57 * already being modified (e.g., writing the commit-graph itself).
58 *
59 * In most cases, callers should use `parse_commit_in_graph()` instead.
60 */
61 struct commit_graph *repo_find_commit_pos_in_graph(struct repository *r,
62 struct commit *c,
63 uint32_t *pos);
64
65 /*
66 * Look up the given commit ID in the commit-graph. This will only return a
67 * commit if the ID exists both in the graph and in the object database such
68 * that we don't return commits whose object has been pruned. Otherwise, this
69 * function returns `NULL`.
70 */
71 struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id);
72
73 /*
74 * It is possible that we loaded commit contents from the commit buffer,
75 * but we also want to ensure the commit-graph content is correctly
76 * checked and filled. Fill the graph_pos and generation members of
77 * the given commit.
78 */
79 void load_commit_graph_info(struct repository *r, struct commit *item);
80
81 struct tree *get_commit_tree_in_graph(struct repository *r,
82 const struct commit *c);
83
84 struct commit_graph {
85 const unsigned char *data;
86 size_t data_len;
87
88 const struct git_hash_algo *hash_algo;
89 unsigned char num_chunks;
90 uint32_t num_commits;
91 struct object_id oid;
92 char *filename;
93 struct odb_source *odb_source;
94
95 uint32_t num_commits_in_base;
96 unsigned int read_generation_data;
97 struct commit_graph *base_graph;
98
99 const uint32_t *chunk_oid_fanout;
100 const unsigned char *chunk_oid_lookup;
101 const unsigned char *chunk_commit_data;
102 const unsigned char *chunk_generation_data;
103 const unsigned char *chunk_generation_data_overflow;
104 size_t chunk_generation_data_overflow_size;
105 const unsigned char *chunk_extra_edges;
106 size_t chunk_extra_edges_size;
107 const unsigned char *chunk_base_graphs;
108 size_t chunk_base_graphs_size;
109 const unsigned char *chunk_bloom_indexes;
110 const unsigned char *chunk_bloom_data;
111 size_t chunk_bloom_data_size;
112
113 struct topo_level_slab *topo_levels;
114 struct bloom_filter_settings *bloom_filter_settings;
115 };
116
117 struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source,
118 int fd, struct stat *st);
119 struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb,
120 int fd, struct stat *st,
121 int *incomplete_chain);
122 struct commit_graph *read_commit_graph_one(struct odb_source *source);
123
124 struct repo_settings;
125
126 /*
127 * Callers should initialize the repo_settings with prepare_repo_settings()
128 * prior to calling parse_commit_graph().
129 */
130 struct commit_graph *parse_commit_graph(struct repository *r,
131 void *graph_map, size_t graph_size);
132
133 /*
134 * Return 1 if and only if the repository has a commit-graph
135 * file and generation numbers are computed in that file.
136 */
137 int generation_numbers_enabled(struct repository *r);
138
139 struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r);
140
141 enum commit_graph_write_flags {
142 COMMIT_GRAPH_WRITE_APPEND = (1 << 0),
143 COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1),
144 COMMIT_GRAPH_WRITE_SPLIT = (1 << 2),
145 COMMIT_GRAPH_WRITE_BLOOM_FILTERS = (1 << 3),
146 COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS = (1 << 4),
147 };
148
149 enum commit_graph_split_flags {
150 COMMIT_GRAPH_SPLIT_UNSPECIFIED = 0,
151 COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED = 1,
152 COMMIT_GRAPH_SPLIT_REPLACE = 2
153 };
154
155 struct commit_graph_opts {
156 int size_multiple;
157 int max_commits;
158 timestamp_t expire_time;
159 enum commit_graph_split_flags split_flags;
160 int max_new_filters;
161 };
162
163 /*
164 * The write_commit_graph* methods return zero on success
165 * and a negative value on failure. Note that if the repository
166 * is not compatible with the commit-graph feature, then the
167 * methods will return 0 without writing a commit-graph.
168 */
169 int write_commit_graph_reachable(struct odb_source *source,
170 enum commit_graph_write_flags flags,
171 const struct commit_graph_opts *opts);
172 int write_commit_graph(struct odb_source *source,
173 const struct string_list *pack_indexes,
174 struct oidset *commits,
175 enum commit_graph_write_flags flags,
176 const struct commit_graph_opts *opts);
177
178 #define COMMIT_GRAPH_VERIFY_SHALLOW (1 << 0)
179
180 int verify_commit_graph(struct commit_graph *g, int flags);
181
182 void close_commit_graph(struct object_database *);
183 void free_commit_graph(struct commit_graph *);
184
185 /*
186 * Disable further use of the commit graph in this process when parsing a
187 * "struct commit".
188 */
189 void disable_commit_graph(struct repository *r);
190
191 struct commit_graph_data {
192 uint32_t graph_pos;
193 timestamp_t generation;
194 };
195
196 /*
197 * Commits should be parsed before accessing generation, graph positions.
198 */
199 timestamp_t commit_graph_generation(const struct commit *);
200 uint32_t commit_graph_position(const struct commit *);
201
202 /*
203 * After this method, all commits reachable from those in the given
204 * list will have non-zero, non-infinite generation numbers.
205 */
206 void ensure_generations_valid(struct repository *r,
207 struct commit **commits, size_t nr);
208
209 #endif