Git fork
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 oustide of a builtin, and only if you know what
22 * you are doing!
23 */
24void git_test_write_commit_graph_or_die(struct odb_source *source);
25
26struct commit;
27struct bloom_filter_settings;
28struct repository;
29struct object_database;
30struct string_list;
31
32char *get_commit_graph_filename(struct odb_source *source);
33char *get_commit_graph_chain_filename(struct odb_source *source);
34int open_commit_graph(const char *graph_file, int *fd, struct stat *st);
35int 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 */
48int 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 */
61struct 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 */
71struct 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 */
79void load_commit_graph_info(struct repository *r, struct commit *item);
80
81struct tree *get_commit_tree_in_graph(struct repository *r,
82 const struct commit *c);
83
84struct 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
117struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source,
118 int fd, struct stat *st);
119struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb,
120 int fd, struct stat *st,
121 int *incomplete_chain);
122struct commit_graph *read_commit_graph_one(struct odb_source *source);
123
124struct repo_settings;
125
126/*
127 * Callers should initialize the repo_settings with prepare_repo_settings()
128 * prior to calling parse_commit_graph().
129 */
130struct 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 */
137int generation_numbers_enabled(struct repository *r);
138
139/*
140 * Return 1 if and only if the repository has a commit-graph
141 * file and generation data chunk has been written for the file.
142 */
143int corrected_commit_dates_enabled(struct repository *r);
144
145struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r);
146
147enum commit_graph_write_flags {
148 COMMIT_GRAPH_WRITE_APPEND = (1 << 0),
149 COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1),
150 COMMIT_GRAPH_WRITE_SPLIT = (1 << 2),
151 COMMIT_GRAPH_WRITE_BLOOM_FILTERS = (1 << 3),
152 COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS = (1 << 4),
153};
154
155enum commit_graph_split_flags {
156 COMMIT_GRAPH_SPLIT_UNSPECIFIED = 0,
157 COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED = 1,
158 COMMIT_GRAPH_SPLIT_REPLACE = 2
159};
160
161struct commit_graph_opts {
162 int size_multiple;
163 int max_commits;
164 timestamp_t expire_time;
165 enum commit_graph_split_flags split_flags;
166 int max_new_filters;
167};
168
169/*
170 * The write_commit_graph* methods return zero on success
171 * and a negative value on failure. Note that if the repository
172 * is not compatible with the commit-graph feature, then the
173 * methods will return 0 without writing a commit-graph.
174 */
175int write_commit_graph_reachable(struct odb_source *source,
176 enum commit_graph_write_flags flags,
177 const struct commit_graph_opts *opts);
178int write_commit_graph(struct odb_source *source,
179 const struct string_list *pack_indexes,
180 struct oidset *commits,
181 enum commit_graph_write_flags flags,
182 const struct commit_graph_opts *opts);
183
184#define COMMIT_GRAPH_VERIFY_SHALLOW (1 << 0)
185
186int verify_commit_graph(struct commit_graph *g, int flags);
187
188void close_commit_graph(struct object_database *);
189void free_commit_graph(struct commit_graph *);
190
191/*
192 * Disable further use of the commit graph in this process when parsing a
193 * "struct commit".
194 */
195void disable_commit_graph(struct repository *r);
196
197struct commit_graph_data {
198 uint32_t graph_pos;
199 timestamp_t generation;
200};
201
202/*
203 * Commits should be parsed before accessing generation, graph positions.
204 */
205timestamp_t commit_graph_generation(const struct commit *);
206uint32_t commit_graph_position(const struct commit *);
207
208/*
209 * After this method, all commits reachable from those in the given
210 * list will have non-zero, non-infinite generation numbers.
211 */
212void ensure_generations_valid(struct repository *r,
213 struct commit **commits, size_t nr);
214
215#endif