summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/repository.c40
-rw-r--r--src/tree.c33
-rw-r--r--src/tree.h1
3 files changed, 54 insertions, 20 deletions
diff --git a/src/repository.c b/src/repository.c
index 7e56a4b66..97a7e15e2 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -379,31 +379,48 @@ git_odb *git_repository_database(git_repository *repo)
return repo->db;
}
-int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type)
+static int create_object(git_object **object_out, git_otype type)
{
git_object *object = NULL;
- assert(object_out && repo);
+ assert(object_out);
*object_out = NULL;
switch (type) {
case GIT_OBJ_COMMIT:
case GIT_OBJ_TAG:
- case GIT_OBJ_TREE:
case GIT_OBJ_BLOB:
+ object = git__malloc(git_object__size(type));
+ if (object == NULL)
+ return GIT_ENOMEM;
+ memset(object, 0x0, git_object__size(type));
+ break;
+
+ case GIT_OBJ_TREE:
+ object = (git_object *)git_tree__new();
+ if (object == NULL)
+ return GIT_ENOMEM;
break;
default:
return GIT_EINVALIDTYPE;
}
- object = git__malloc(git_object__size(type));
+ *object_out = object;
+ return GIT_SUCCESS;
+}
- if (object == NULL)
- return GIT_ENOMEM;
+int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type)
+{
+ git_object *object = NULL;
+ int error;
+
+ assert(object_out && repo);
+
+ if ((error = create_object(&object, type)) < GIT_SUCCESS)
+ return error;
- memset(object, 0x0, git_object__size(type));
object->repo = repo;
object->in_memory = 1;
object->modified = 1;
@@ -439,12 +456,8 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
type = obj_file.type;
- object = git__malloc(git_object__size(type));
-
- if (object == NULL)
- return GIT_ENOMEM;
-
- memset(object, 0x0, git_object__size(type));
+ if ((error = create_object(&object, type)) < GIT_SUCCESS)
+ return error;
/* Initialize parent object */
git_oid_cpy(&object->id, id);
@@ -453,7 +466,6 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
object->source.open = 1;
switch (type) {
-
case GIT_OBJ_COMMIT:
error = git_commit__parse((git_commit *)object);
break;
diff --git a/src/tree.c b/src/tree.c
index 4655dc760..d160a79a4 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -30,6 +30,8 @@
#include "git2/repository.h"
#include "git2/object.h"
+#define DEFAULT_TREE_SIZE 16
+
int entry_search_cmp(const void *key, const void *array_member)
{
const char *filename = (const char *)key;
@@ -46,7 +48,7 @@ int entry_sort_cmp(const void *a, const void *b)
return strcmp(entry_a->filename, entry_b->filename);
}
-static void free_tree_entries(git_tree *tree)
+static void clear_entries(git_tree *tree)
{
unsigned int i;
@@ -61,14 +63,35 @@ static void free_tree_entries(git_tree *tree)
free(e);
}
- git_vector_free(&tree->entries);
+ git_vector_clear(&tree->entries);
}
+git_tree *git_tree__new(void)
+{
+ git_tree *tree;
+
+ tree = git__malloc(sizeof(struct git_tree));
+ if (tree == NULL)
+ return NULL;
+
+ memset(tree, 0x0, sizeof(struct git_tree));
+
+ if (git_vector_init(&tree->entries,
+ DEFAULT_TREE_SIZE,
+ entry_sort_cmp,
+ entry_search_cmp) < GIT_SUCCESS) {
+ free(tree);
+ return NULL;
+ }
+
+ return tree;
+}
void git_tree__free(git_tree *tree)
{
- free_tree_entries(tree);
+ clear_entries(tree);
+ git_vector_free(&tree->entries);
free(tree);
}
@@ -243,9 +266,7 @@ static int tree_parse_buffer(git_tree *tree, char *buffer, char *buffer_end)
expected_size = (tree->object.source.raw.len / avg_entry_size) + 1;
- free_tree_entries(tree);
- if (git_vector_init(&tree->entries, expected_size, entry_sort_cmp, entry_search_cmp) < GIT_SUCCESS)
- return GIT_ENOMEM;
+ clear_entries(tree);
while (buffer < buffer_end) {
git_tree_entry *entry;
diff --git a/src/tree.h b/src/tree.h
index 5f532f887..78500c471 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -19,6 +19,7 @@ struct git_tree {
};
void git_tree__free(git_tree *tree);
+git_tree *git_tree__new(void);
int git_tree__parse(git_tree *tree);
int git_tree__writeback(git_tree *tree, git_odb_source *src);