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