Add support for git index files
[libgit2.git] / src / tree.c
blob47b0273228dd08a6ce617f8f3ab2092a2d4dca57
1 /*
2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
26 #include "common.h"
27 #include "commit.h"
28 #include "revwalk.h"
29 #include "tree.h"
31 void git_tree__free(git_tree *tree)
33 free(tree);
36 const git_oid *git_tree_id(git_tree *tree)
38 return &tree->object.id;
41 git_tree *git_tree_lookup(git_revpool *pool, const git_oid *id)
43 git_tree *tree = NULL;
45 if (pool == NULL)
46 return NULL;
48 tree = (git_tree *)git_revpool_table_lookup(pool->objects, id);
49 if (tree != NULL)
50 return tree;
52 tree = git__malloc(sizeof(git_tree));
54 if (tree == NULL)
55 return NULL;
57 memset(tree, 0x0, sizeof(git_tree));
59 /* Initialize parent object */
60 git_oid_cpy(&tree->object.id, id);
61 tree->object.pool = pool;
62 tree->object.type = GIT_OBJ_TREE;
64 git_revpool_table_insert(pool->objects, (git_revpool_object *)tree);
66 return tree;
70 git_tree *git_tree_parse(git_revpool *pool, const git_oid *id)
72 git_tree *tree = NULL;
74 if ((tree = git_tree_lookup(pool, id)) == NULL)
75 return NULL;
77 if (git_tree__parse(tree) < 0)
78 goto error_cleanup;
80 return tree;
82 error_cleanup:
83 /* FIXME: do not free; the tree is owned by the revpool */
84 free(tree);
85 return NULL;
88 int git_tree__parse(git_tree *tree)
90 static const char tree_header[] = {'t', 'r', 'e', 'e', ' '};
92 int error = 0;
93 git_obj odb_object;
94 char *buffer, *buffer_end;
96 error = git_odb_read(&odb_object, tree->object.pool->db, &tree->object.id);
97 if (error < 0)
98 return error;
100 buffer = odb_object.data;
101 buffer_end = odb_object.data + odb_object.len;
103 if (memcmp(buffer, tree_header, 5) != 0)
104 return GIT_EOBJCORRUPTED;
106 buffer += 5;
108 tree->byte_size = strtol(buffer, &buffer, 10);
110 if (*buffer++ != 0)
111 return GIT_EOBJCORRUPTED;
113 while (buffer < buffer_end) {
114 git_tree_entry *entry;
116 entry = git__malloc(sizeof(git_tree_entry));
117 entry->next = tree->entries;
119 entry->attr = strtol(buffer, &buffer, 10);
121 if (*buffer++ != ' ') {
122 error = GIT_EOBJCORRUPTED;
123 break;
126 entry->filename = git__strdup(buffer);
128 if (entry->filename == NULL) {
129 error = GIT_EOBJCORRUPTED;
130 break;
132 buffer += strlen(entry->filename);
134 git_oid_mkraw(&entry->oid, (const unsigned char *)buffer);
135 buffer += GIT_OID_RAWSZ;
137 tree->entries = entry;
140 return error;