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 module libgit2_d.tree;
8 
9 
10 private static import libgit2_d.buffer;
11 private static import libgit2_d.oid;
12 private static import libgit2_d.types;
13 
14 /**
15  * @file git2/tree.h
16  * @brief Git tree parsing, loading routines
17  * @defgroup git_tree Git tree parsing, loading routines
18  * @ingroup Git
19  * @{
20  */
21 extern (C):
22 nothrow @nogc:
23 public:
24 
25 /**
26  * Lookup a tree object from the repository.
27  *
28  * @param out_ Pointer to the looked up tree
29  * @param repo The repo to use when locating the tree.
30  * @param id Identity of the tree to locate.
31  * @return 0 or an error code
32  */
33 //GIT_EXTERN
34 int git_tree_lookup(libgit2_d.types.git_tree** out_, libgit2_d.types.git_repository* repo, const (libgit2_d.oid.git_oid)* id);
35 
36 /**
37  * Lookup a tree object from the repository,
38  * given a prefix of its identifier (short id).
39  *
40  * @see git_object_lookup_prefix
41  *
42  * @param out_ pointer to the looked up tree
43  * @param repo the repo to use when locating the tree.
44  * @param id identity of the tree to locate.
45  * @param len the length of the short identifier
46  * @return 0 or an error code
47  */
48 //GIT_EXTERN
49 int git_tree_lookup_prefix(libgit2_d.types.git_tree** out_, libgit2_d.types.git_repository* repo, const (libgit2_d.oid.git_oid)* id, size_t len);
50 
51 /**
52  * Close an open tree
53  *
54  * You can no longer use the git_tree pointer after this call.
55  *
56  * IMPORTANT: You MUST call this method when you stop using a tree to
57  * release memory. Failure to do so will cause a memory leak.
58  *
59  * @param tree The tree to close
60  */
61 //GIT_EXTERN
62 void git_tree_free(libgit2_d.types.git_tree* tree);
63 
64 /**
65  * Get the id of a tree.
66  *
67  * @param tree a previously loaded tree.
68  * @return object identity for the tree.
69  */
70 //GIT_EXTERN
71 const (libgit2_d.oid.git_oid)* git_tree_id(const (libgit2_d.types.git_tree)* tree);
72 
73 /**
74  * Get the repository that contains the tree.
75  *
76  * @param tree A previously loaded tree.
77  * @return Repository that contains this tree.
78  */
79 //GIT_EXTERN
80 libgit2_d.types.git_repository* git_tree_owner(const (libgit2_d.types.git_tree)* tree);
81 
82 /**
83  * Get the number of entries listed in a tree
84  *
85  * @param tree a previously loaded tree.
86  * @return the number of entries in the tree
87  */
88 //GIT_EXTERN
89 size_t git_tree_entrycount(const (libgit2_d.types.git_tree)* tree);
90 
91 /**
92  * Lookup a tree entry by its filename
93  *
94  * This returns a git_tree_entry that is owned by the git_tree.  You don't
95  * have to free it, but you must not use it after the git_tree is released.
96  *
97  * @param tree a previously loaded tree.
98  * @param filename the filename of the desired entry
99  * @return the tree entry; null if not found
100  */
101 //GIT_EXTERN
102 const (libgit2_d.types.git_tree_entry)* git_tree_entry_byname(const (libgit2_d.types.git_tree)* tree, const (char)* filename);
103 
104 /**
105  * Lookup a tree entry by its position in the tree
106  *
107  * This returns a git_tree_entry that is owned by the git_tree.  You don't
108  * have to free it, but you must not use it after the git_tree is released.
109  *
110  * @param tree a previously loaded tree.
111  * @param idx the position in the entry list
112  * @return the tree entry; null if not found
113  */
114 //GIT_EXTERN
115 const (libgit2_d.types.git_tree_entry)* git_tree_entry_byindex(const (libgit2_d.types.git_tree)* tree, size_t idx);
116 
117 /**
118  * Lookup a tree entry by SHA value.
119  *
120  * This returns a git_tree_entry that is owned by the git_tree.  You don't
121  * have to free it, but you must not use it after the git_tree is released.
122  *
123  * Warning: this must examine every entry in the tree, so it is not fast.
124  *
125  * @param tree a previously loaded tree.
126  * @param id the sha being looked for
127  * @return the tree entry; null if not found
128  */
129 //GIT_EXTERN
130 const (libgit2_d.types.git_tree_entry)* git_tree_entry_byid(const (libgit2_d.types.git_tree)* tree, const (libgit2_d.oid.git_oid)* id);
131 
132 /**
133  * Retrieve a tree entry contained in a tree or in any of its subtrees,
134  * given its relative path.
135  *
136  * Unlike the other lookup functions, the returned tree entry is owned by
137  * the user and must be freed explicitly with `git_tree_entry_free()`.
138  *
139  * @param out_ Pointer where to store the tree entry
140  * @param root Previously loaded tree which is the root of the relative path
141  * @param path Path to the contained entry
142  * @return 0 on success; git_error_code.GIT_ENOTFOUND if the path does not exist
143  */
144 //GIT_EXTERN
145 int git_tree_entry_bypath(libgit2_d.types.git_tree_entry** out_, const (libgit2_d.types.git_tree)* root, const (char)* path);
146 
147 /**
148  * Duplicate a tree entry
149  *
150  * Create a copy of a tree entry. The returned copy is owned by the user,
151  * and must be freed explicitly with `git_tree_entry_free()`.
152  *
153  * @param dest pointer where to store the copy
154  * @param source tree entry to duplicate
155  * @return 0 or an error code
156  */
157 //GIT_EXTERN
158 int git_tree_entry_dup(libgit2_d.types.git_tree_entry** dest, const (libgit2_d.types.git_tree_entry)* source);
159 
160 /**
161  * Free a user-owned tree entry
162  *
163  * IMPORTANT: This function is only needed for tree entries owned by the
164  * user, such as the ones returned by `git_tree_entry_dup()` or
165  * `git_tree_entry_bypath()`.
166  *
167  * @param entry The entry to free
168  */
169 //GIT_EXTERN
170 void git_tree_entry_free(libgit2_d.types.git_tree_entry* entry);
171 
172 /**
173  * Get the filename of a tree entry
174  *
175  * @param entry a tree entry
176  * @return the name of the file
177  */
178 //GIT_EXTERN
179 const (char)* git_tree_entry_name(const (libgit2_d.types.git_tree_entry)* entry);
180 
181 /**
182  * Get the id of the object pointed by the entry
183  *
184  * @param entry a tree entry
185  * @return the oid of the object
186  */
187 //GIT_EXTERN
188 const (libgit2_d.oid.git_oid)* git_tree_entry_id(const (libgit2_d.types.git_tree_entry)* entry);
189 
190 /**
191  * Get the type of the object pointed by the entry
192  *
193  * @param entry a tree entry
194  * @return the type of the pointed object
195  */
196 //GIT_EXTERN
197 libgit2_d.types.git_object_t git_tree_entry_type(const (libgit2_d.types.git_tree_entry)* entry);
198 
199 /**
200  * Get the UNIX file attributes of a tree entry
201  *
202  * @param entry a tree entry
203  * @return filemode as an integer
204  */
205 //GIT_EXTERN
206 libgit2_d.types.git_filemode_t git_tree_entry_filemode(const (libgit2_d.types.git_tree_entry)* entry);
207 
208 /**
209  * Get the raw UNIX file attributes of a tree entry
210  *
211  * This function does not perform any normalization and is only useful
212  * if you need to be able to recreate the original tree object.
213  *
214  * @param entry a tree entry
215  * @return filemode as an integer
216  */
217 
218 //GIT_EXTERN
219 libgit2_d.types.git_filemode_t git_tree_entry_filemode_raw(const (libgit2_d.types.git_tree_entry)* entry);
220 
221 /**
222  * Compare two tree entries
223  *
224  * @param e1 first tree entry
225  * @param e2 second tree entry
226  * @return <0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2
227  */
228 //GIT_EXTERN
229 int git_tree_entry_cmp(const (libgit2_d.types.git_tree_entry)* e1, const (libgit2_d.types.git_tree_entry)* e2);
230 
231 /**
232  * Convert a tree entry to the git_object it points to.
233  *
234  * You must call `git_object_free()` on the object when you are done with it.
235  *
236  * @param object_out pointer to the converted object
237  * @param repo repository where to lookup the pointed object
238  * @param entry a tree entry
239  * @return 0 or an error code
240  */
241 //GIT_EXTERN
242 int git_tree_entry_to_object(libgit2_d.types.git_object** object_out, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_tree_entry)* entry);
243 
244 /**
245  * Create a new tree builder.
246  *
247  * The tree builder can be used to create or modify trees in memory and
248  * write them as tree objects to the database.
249  *
250  * If the `source` parameter is not null, the tree builder will be
251  * initialized with the entries of the given tree.
252  *
253  * If the `source` parameter is null, the tree builder will start with no
254  * entries and will have to be filled manually.
255  *
256  * @param out_ Pointer where to store the tree builder
257  * @param repo Repository in which to store the object
258  * @param source Source tree to initialize the builder (optional)
259  * @return 0 on success; error code otherwise
260  */
261 //GIT_EXTERN
262 int git_treebuilder_new(libgit2_d.types.git_treebuilder** out_, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_tree)* source);
263 
264 /**
265  * Clear all the entires in the builder
266  *
267  * @param bld Builder to clear
268  * @return 0 on success; error code otherwise
269  */
270 //GIT_EXTERN
271 int git_treebuilder_clear(libgit2_d.types.git_treebuilder* bld);
272 
273 /**
274  * Get the number of entries listed in a treebuilder
275  *
276  * @param bld a previously loaded treebuilder.
277  * @return the number of entries in the treebuilder
278  */
279 //GIT_EXTERN
280 size_t git_treebuilder_entrycount(libgit2_d.types.git_treebuilder* bld);
281 
282 /**
283  * Free a tree builder
284  *
285  * This will clear all the entries and free to builder.
286  * Failing to free the builder after you're done using it
287  * will result in a memory leak
288  *
289  * @param bld Builder to free
290  */
291 //GIT_EXTERN
292 void git_treebuilder_free(libgit2_d.types.git_treebuilder* bld);
293 
294 /**
295  * Get an entry from the builder from its filename
296  *
297  * The returned entry is owned by the builder and should
298  * not be freed manually.
299  *
300  * @param bld Tree builder
301  * @param filename Name of the entry
302  * @return pointer to the entry; null if not found
303  */
304 //GIT_EXTERN
305 const (libgit2_d.types.git_tree_entry)* git_treebuilder_get(libgit2_d.types.git_treebuilder* bld, const (char)* filename);
306 
307 /**
308  * Add or update an entry to the builder
309  *
310  * Insert a new entry for `filename` in the builder with the
311  * given attributes.
312  *
313  * If an entry named `filename` already exists, its attributes
314  * will be updated with the given ones.
315  *
316  * The optional pointer `out` can be used to retrieve a pointer to the
317  * newly created/updated entry.  Pass null if you do not need it. The
318  * pointer may not be valid past the next operation in this
319  * builder. Duplicate the entry if you want to keep it.
320  *
321  * By default the entry that you are inserting will be checked for
322  * validity; that it exists in the object database and is of the
323  * correct type.  If you do not want this behavior, set the
324  * `git_libgit2_opt_t.GIT_OPT_ENABLE_STRICT_OBJECT_CREATION` library option to false.
325  *
326  * @param out_ Pointer to store the entry (optional)
327  * @param bld Tree builder
328  * @param filename Filename of the entry
329  * @param id SHA1 oid of the entry
330  * @param filemode Folder attributes of the entry. This parameter must
331  *			be valued with one of the following entries: 0040000,
332  *0100644, 0100755, 0120000 or 0160000.
333  * @return 0 or an error code
334  */
335 //GIT_EXTERN
336 int git_treebuilder_insert(const (libgit2_d.types.git_tree_entry)** out_, libgit2_d.types.git_treebuilder* bld, const (char)* filename, const (libgit2_d.oid.git_oid)* id, libgit2_d.types.git_filemode_t filemode);
337 
338 /**
339  * Remove an entry from the builder by its filename
340  *
341  * @param bld Tree builder
342  * @param filename Filename of the entry to remove
343  */
344 //GIT_EXTERN
345 int git_treebuilder_remove(libgit2_d.types.git_treebuilder* bld, const (char)* filename);
346 
347 /**
348  * Callback for git_treebuilder_filter
349  *
350  * The return value is treated as a boolean, with zero indicating that the
351  * entry should be left alone and any non-zero value meaning that the
352  * entry should be removed from the treebuilder list (i.e. filtered out).
353  */
354 alias git_treebuilder_filter_cb = int function(const (libgit2_d.types.git_tree_entry)* entry, void* payload);
355 
356 /**
357  * Selectively remove entries in the tree
358  *
359  * The `filter` callback will be called for each entry in the tree with a
360  * pointer to the entry and the provided `payload`; if the callback returns
361  * non-zero, the entry will be filtered (removed from the builder).
362  *
363  * @param bld Tree builder
364  * @param filter Callback to filter entries
365  * @param payload Extra data to pass to filter callback
366  * @return 0 on success, non-zero callback return value, or error code
367  */
368 //GIT_EXTERN
369 int git_treebuilder_filter(libgit2_d.types.git_treebuilder* bld, .git_treebuilder_filter_cb filter, void* payload);
370 
371 /**
372  * Write the contents of the tree builder as a tree object
373  *
374  * The tree builder will be written to the given `repo`, and its
375  * identifying SHA1 hash will be stored in the `id` pointer.
376  *
377  * @param id Pointer to store the OID of the newly written tree
378  * @param bld Tree builder to write
379  * @return 0 or an error code
380  */
381 //GIT_EXTERN
382 int git_treebuilder_write(libgit2_d.oid.git_oid* id, libgit2_d.types.git_treebuilder* bld);
383 
384 /**
385  * Write the contents of the tree builder as a tree object
386  * using a shared git_buf.
387  *
388  * @see git_treebuilder_write
389  *
390  * @param oid Pointer to store the OID of the newly written tree
391  * @param bld Tree builder to write
392  * @param tree Shared buffer for writing the tree. Will be grown as necessary.
393  * @return 0 or an error code
394  */
395 //GIT_EXTERN
396 int git_treebuilder_write_with_buffer(libgit2_d.oid.git_oid* oid, libgit2_d.types.git_treebuilder* bld, libgit2_d.buffer.git_buf* tree);
397 
398 /**
399  * Callback for the tree traversal method
400  */
401 alias git_treewalk_cb = int function(const (char)* root, const (libgit2_d.types.git_tree_entry)* entry, void* payload);
402 
403 /**
404  * Tree traversal modes
405  */
406 enum git_treewalk_mode
407 {
408 	/**
409 	 * Pre-order
410 	 */
411 	GIT_TREEWALK_PRE = 0,
412 
413 	/**
414 	 * Post-order
415 	 */
416 	GIT_TREEWALK_POST = 1,
417 }
418 
419 /**
420  * Traverse the entries in a tree and its subtrees in post or pre order.
421  *
422  * The entries will be traversed in the specified order, children subtrees
423  * will be automatically loaded as required, and the `callback` will be
424  * called once per entry with the current (relative) root for the entry and
425  * the entry data itself.
426  *
427  * If the callback returns a positive value, the passed entry will be
428  * skipped on the traversal (in pre mode). A negative value stops the walk.
429  *
430  * @param tree The tree to walk
431  * @param mode Traversal mode (pre or post-order)
432  * @param callback Function to call on each tree entry
433  * @param payload Opaque pointer to be passed on each callback
434  * @return 0 or an error code
435  */
436 //GIT_EXTERN
437 int git_tree_walk(const (libgit2_d.types.git_tree)* tree, .git_treewalk_mode mode, .git_treewalk_cb callback, void* payload);
438 
439 /**
440  * Create an in-memory copy of a tree. The copy must be explicitly
441  * free'd or it will leak.
442  *
443  * @param out_ Pointer to store the copy of the tree
444  * @param source Original tree to copy
445  */
446 //GIT_EXTERN
447 int git_tree_dup(libgit2_d.types.git_tree** out_, libgit2_d.types.git_tree* source);
448 
449 /**
450  * The kind of update to perform
451  */
452 enum git_tree_update_t
453 {
454 	/**
455 	 * Update or insert an entry at the specified path
456 	 */
457 	GIT_TREE_UPDATE_UPSERT,
458 
459 	/**
460 	 * Remove an entry from the specified path
461 	 */
462 	GIT_TREE_UPDATE_REMOVE,
463 }
464 
465 /**
466  * An action to perform during the update of a tree
467  */
468 struct git_tree_update
469 {
470 	/**
471 	 * Update action. If it's an removal, only the path is looked at
472 	 */
473 	.git_tree_update_t action;
474 
475 	/**
476 	 * The entry's id
477 	 */
478 	libgit2_d.oid.git_oid id;
479 
480 	/**
481 	 * The filemode/kind of object
482 	 */
483 	libgit2_d.types.git_filemode_t filemode;
484 
485 	/**
486 	 * The full path from the root tree
487 	 */
488 	const (char)* path;
489 }
490 
491 /**
492  * Create a tree based on another one with the specified modifications
493  *
494  * Given the `baseline` perform the changes described in the list of
495  * `updates` and create a new tree.
496  *
497  * This function is optimized for common file/directory addition, removal and
498  * replacement in trees. It is much more efficient than reading the tree into a
499  * `git_index` and modifying that, but in exchange it is not as flexible.
500  *
501  * Deleting and adding the same entry is undefined behaviour, changing
502  * a tree to a blob or viceversa is not supported.
503  *
504  * @param out_ id of the new tree
505  * @param repo the repository in which to create the tree, must be the
506  * same as for `baseline`
507  * @param baseline the tree to base these changes on
508  * @param nupdates the number of elements in the update list
509  * @param updates the list of updates to perform
510  */
511 //GIT_EXTERN
512 int git_tree_create_updated(libgit2_d.oid.git_oid* out_, libgit2_d.types.git_repository* repo, libgit2_d.types.git_tree* baseline, size_t nupdates, const (.git_tree_update)* updates);
513 
514 /** @} */