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