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 #ifndef INCLUDE_git_pack_h__
8 #define INCLUDE_git_pack_h__
9 
10 #include "common.h"
11 #include "oid.h"
12 #include "indexer.h"
13 
14 /**
15  * @file git2/pack.h
16  * @brief Git pack management routines
17  *
18  * Packing objects
19  * ---------------
20  *
21  * Creation of packfiles requires two steps:
22  *
23  * - First, insert all the objects you want to put into the packfile
24  *   using `git_packbuilder_insert` and `git_packbuilder_insert_tree`.
25  *   It's important to add the objects in recency order ("in the order
26  *   that they are 'reachable' from head").
27  *
28  *   "ANY order will give you a working pack, ... [but it is] the thing
29  *   that gives packs good locality. It keeps the objects close to the
30  *   head (whether they are old or new, but they are _reachable_ from the
31  *   head) at the head of the pack. So packs actually have absolutely
32  *   _wonderful_ IO patterns." - Linus Torvalds
33  *   git.git/Documentation/technical/pack-heuristics.txt
34  *
35  * - Second, use `git_packbuilder_write` or `git_packbuilder_foreach` to
36  *   write the resulting packfile.
37  *
38  *   libgit2 will take care of the delta ordering and generation.
39  *   `git_packbuilder_set_threads` can be used to adjust the number of
40  *   threads used for the process.
41  *
42  * See tests/pack/packbuilder.c for an example.
43  *
44  * @ingroup Git
45  * @{
46  */
47 GIT_BEGIN_DECL
48 
49 /**
50  * Stages that are reported by the packbuilder progress callback.
51  */
52 typedef enum {
53 	GIT_PACKBUILDER_ADDING_OBJECTS = 0,
54 	GIT_PACKBUILDER_DELTAFICATION = 1,
55 } git_packbuilder_stage_t;
56 
57 /**
58  * Initialize a new packbuilder
59  *
60  * @param out The new packbuilder object
61  * @param repo The repository
62  *
63  * @return 0 or an error code
64  */
65 GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo);
66 
67 /**
68  * Set number of threads to spawn
69  *
70  * By default, libgit2 won't spawn any threads at all;
71  * when set to 0, libgit2 will autodetect the number of
72  * CPUs.
73  *
74  * @param pb The packbuilder
75  * @param n Number of threads to spawn
76  * @return number of actual threads to be used
77  */
78 GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n);
79 
80 /**
81  * Insert a single object
82  *
83  * For an optimal pack it's mandatory to insert objects in recency order,
84  * commits followed by trees and blobs.
85  *
86  * @param pb The packbuilder
87  * @param id The oid of the commit
88  * @param name The name; might be NULL
89  *
90  * @return 0 or an error code
91  */
92 GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name);
93 
94 /**
95  * Insert a root tree object
96  *
97  * This will add the tree as well as all referenced trees and blobs.
98  *
99  * @param pb The packbuilder
100  * @param id The oid of the root tree
101  *
102  * @return 0 or an error code
103  */
104 GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id);
105 
106 /**
107  * Insert a commit object
108  *
109  * This will add a commit as well as the completed referenced tree.
110  *
111  * @param pb The packbuilder
112  * @param id The oid of the commit
113  *
114  * @return 0 or an error code
115  */
116 GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id);
117 
118 /**
119  * Insert objects as given by the walk
120  *
121  * Those commits and all objects they reference will be inserted into
122  * the packbuilder.
123  *
124  * @param pb the packbuilder
125  * @param walk the revwalk to use to fill the packbuilder
126  *
127  * @return 0 or an error code
128  */
129 GIT_EXTERN(int) git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk);
130 
131 /**
132  * Recursively insert an object and its referenced objects
133  *
134  * Insert the object as well as any object it references.
135  *
136  * @param pb the packbuilder
137  * @param id the id of the root object to insert
138  * @param name optional name for the object
139  * @return 0 or an error code
140  */
141 GIT_EXTERN(int) git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const char *name);
142 
143 /**
144  * Write the contents of the packfile to an in-memory buffer
145  *
146  * The contents of the buffer will become a valid packfile, even though there
147  * will be no attached index
148  *
149  * @param buf Buffer where to write the packfile
150  * @param pb The packbuilder
151  */
152 GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
153 
154 /**
155  * Write the new pack and corresponding index file to path.
156  *
157  * @param pb The packbuilder
158  * @param path Path to the directory where the packfile and index should be stored, or NULL for default location
159  * @param mode permissions to use creating a packfile or 0 for defaults
160  * @param progress_cb function to call with progress information from the indexer (optional)
161  * @param progress_cb_payload payload for the progress callback (optional)
162  *
163  * @return 0 or an error code
164  */
165 GIT_EXTERN(int) git_packbuilder_write(
166 	git_packbuilder *pb,
167 	const char *path,
168 	unsigned int mode,
169 	git_indexer_progress_cb progress_cb,
170 	void *progress_cb_payload);
171 
172 /**
173 * Get the packfile's hash
174 *
175 * A packfile's name is derived from the sorted hashing of all object
176 * names. This is only correct after the packfile has been written.
177 *
178 * @param pb The packbuilder object
179 */
180 GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
181 
182 /**
183  * Callback used to iterate over packed objects
184  *
185  * @see git_packbuilder_foreach
186  *
187  * @param buf A pointer to the object's data
188  * @param size The size of the underlying object
189  * @param payload Payload passed to git_packbuilder_foreach
190  * @return non-zero to terminate the iteration
191  */
192 typedef int GIT_CALLBACK(git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
193 
194 /**
195  * Create the new pack and pass each object to the callback
196  *
197  * @param pb the packbuilder
198  * @param cb the callback to call with each packed object's buffer
199  * @param payload the callback's data
200  * @return 0 or an error code
201  */
202 GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload);
203 
204 /**
205  * Get the total number of objects the packbuilder will write out
206  *
207  * @param pb the packbuilder
208  * @return the number of objects in the packfile
209  */
210 GIT_EXTERN(size_t) git_packbuilder_object_count(git_packbuilder *pb);
211 
212 /**
213  * Get the number of objects the packbuilder has already written out
214  *
215  * @param pb the packbuilder
216  * @return the number of objects which have already been written
217  */
218 GIT_EXTERN(size_t) git_packbuilder_written(git_packbuilder *pb);
219 
220 /** Packbuilder progress notification function */
221 typedef int GIT_CALLBACK(git_packbuilder_progress)(
222 	int stage,
223 	uint32_t current,
224 	uint32_t total,
225 	void *payload);
226 
227 /**
228  * Set the callbacks for a packbuilder
229  *
230  * @param pb The packbuilder object
231  * @param progress_cb Function to call with progress information during
232  * pack building. Be aware that this is called inline with pack building
233  * operations, so performance may be affected.
234  * @param progress_cb_payload Payload for progress callback.
235  * @return 0 or an error code
236  */
237 GIT_EXTERN(int) git_packbuilder_set_callbacks(
238 	git_packbuilder *pb,
239 	git_packbuilder_progress progress_cb,
240 	void *progress_cb_payload);
241 
242 /**
243  * Free the packbuilder and all associated data
244  *
245  * @param pb The packbuilder
246  */
247 GIT_EXTERN(void) git_packbuilder_free(git_packbuilder *pb);
248 
249 /** @} */
250 GIT_END_DECL
251 #endif
252