summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2011-02-18 21:57:53 +0200
committerVicent Marti <tanoku@gmail.com>2011-03-03 20:23:49 +0200
commit86194b2433b993666bb58e7818f5b1f4133c9a43 (patch)
treec7165ed2c8d7f3bc291f49ef2d815ec29b24ac30 /src
parent32054c24a26ab386fb56c7333fa723459e7e8dff (diff)
downloadlibgit2-86194b2433b993666bb58e7818f5b1f4133c9a43.tar.gz
Split packed from unpacked references
These two reference types are now stored separately to eventually allow the removal/renaming of loose references and rewriting of the refs packfile. Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/common.h1
-rw-r--r--src/filebuf.c3
-rw-r--r--src/filebuf.h3
-rw-r--r--src/git2/types.h5
-rw-r--r--src/refs.c255
-rw-r--r--src/refs.h17
-rw-r--r--src/vector.c17
-rw-r--r--src/vector.h5
8 files changed, 162 insertions, 144 deletions
diff --git a/src/common.h b/src/common.h
index 1aede7367..1ca00471b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -53,6 +53,5 @@ typedef SSIZE_T ssize_t;
#include "bswap.h"
#define GIT_PATH_MAX 4096
-#define GIT_FILELOCK_EXTENSION ".lock\0"
#endif /* INCLUDE_common_h__ */
diff --git a/src/filebuf.c b/src/filebuf.c
index 1359f11d1..a71c57a47 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -28,9 +28,6 @@
#include "filebuf.h"
#include "fileops.h"
-static const char *GIT_FILELOCK_EXTENSION = ".lock\0";
-static const size_t GIT_FILELOCK_EXTLENGTH = 6;
-
static const size_t WRITE_BUFFER_SIZE = (4096 * 2);
static int lock_file(git_filebuf *file, int flags)
diff --git a/src/filebuf.h b/src/filebuf.h
index b2b5eaf4b..9db615fbd 100644
--- a/src/filebuf.h
+++ b/src/filebuf.h
@@ -12,6 +12,9 @@
#define GIT_FILEBUF_APPEND 0x2
#define GIT_FILEBUF_FORCE 0x4
+#define GIT_FILELOCK_EXTENSION ".lock\0"
+#define GIT_FILELOCK_EXTLENGTH 6
+
struct git_filebuf {
char *path_original;
char *path_lock;
diff --git a/src/git2/types.h b/src/git2/types.h
index 7bf4d189e..62467ec45 100644
--- a/src/git2/types.h
+++ b/src/git2/types.h
@@ -140,10 +140,11 @@ typedef struct git_reference git_reference;
/** Basic type of any Git reference. */
typedef enum {
- GIT_REF_ANY = -2, /** Reference can be an object id reference or a symbolic reference */
- GIT_REF_INVALID = -1, /** Invalid reference */
+ GIT_REF_INVALID = 0, /** Invalid reference */
GIT_REF_OID = 1, /** A reference which points at an object id */
GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */
+ GIT_REF_PACKED = 4,
+ GIT_REF_HAS_PEEL = 8,
} git_rtype;
/** @} */
diff --git a/src/refs.c b/src/refs.c
index 8fa157cb2..ff4c3cba7 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -30,7 +30,20 @@
#define MAX_NESTING_LEVEL 5
+typedef struct {
+ git_reference ref;
+ git_oid oid;
+ git_oid peel_target;
+} reference_oid;
+
+typedef struct {
+ git_reference ref;
+ char *target;
+} reference_symbolic;
+
+
static int reference_write(git_reference *ref);
+static int normalize_name(char *buffer_out, const char *name, int is_oid_ref);
static const int default_table_size = 32;
@@ -54,30 +67,34 @@ static void reference_free(git_reference *reference)
free(reference->name);
if (reference->type == GIT_REF_SYMBOLIC)
- free(reference->target.ref);
+ free(((reference_symbolic *)reference)->target);
free(reference);
}
static int reference_create(git_reference **ref_out, git_repository *repo, const char *name, git_rtype type) {
char normalized[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
- int error = GIT_SUCCESS;
+ int error = GIT_SUCCESS, size;
git_reference *reference = NULL;
assert(ref_out && repo && name);
- if (type != GIT_REF_SYMBOLIC && type != GIT_REF_OID)
- return GIT_EMISSINGOBJDATA;
+ if (type == GIT_REF_SYMBOLIC)
+ size = sizeof(reference_symbolic);
+ else if (type == GIT_REF_OID)
+ size = sizeof(reference_oid);
+ else
+ return GIT_EINVALIDREFSTATE;
- reference = git__malloc(sizeof(git_reference));
+ reference = git__malloc(size);
if (reference == NULL)
return GIT_ENOMEM;
- memset(reference, 0x0, sizeof(git_reference));
+ memset(reference, 0x0, size);
reference->owner = repo;
reference->type = type;
- error = git_reference__normalize_name(normalized, name, type);
+ error = normalize_name(normalized, name, (type & GIT_REF_OID));
if (error < GIT_SUCCESS)
goto cleanup;
@@ -107,7 +124,7 @@ int git_reference_create_symbolic(git_reference **ref_out, git_repository *repo,
goto cleanup;
/* The target can aither be the name of an object id reference or the name of another symbolic reference */
- error = git_reference__normalize_name(normalized, target, GIT_REF_ANY);
+ error = normalize_name(normalized, target, 0);
if (error < GIT_SUCCESS)
goto cleanup;
@@ -116,6 +133,10 @@ int git_reference_create_symbolic(git_reference **ref_out, git_repository *repo,
if (error < GIT_SUCCESS)
goto cleanup;
+ error = git_hashtable_insert(repo->references.loose_refs, ref->name, ref);
+ if (error < GIT_SUCCESS)
+ goto cleanup;
+
*ref_out = ref;
return error;
@@ -139,6 +160,10 @@ int git_reference_create_oid(git_reference **ref_out, git_repository *repo, cons
if (error < GIT_SUCCESS)
goto cleanup;
+ error = git_hashtable_insert(repo->references.loose_refs, ref->name, ref);
+ if (error < GIT_SUCCESS)
+ goto cleanup;
+
*ref_out = ref;
return error;
@@ -153,8 +178,10 @@ static int parse_sym_ref(git_reference *ref, gitfo_buf *file_content)
const unsigned int header_len = strlen(GIT_SYMREF);
const char *refname_start;
char *eol;
+ reference_symbolic *ref_sym;
refname_start = (const char *)file_content->data;
+ ref_sym = (reference_symbolic *)ref;
if (file_content->len < (header_len + 1))
return GIT_EREFCORRUPTED;
@@ -166,12 +193,12 @@ static int parse_sym_ref(git_reference *ref, gitfo_buf *file_content)
refname_start += header_len;
- ref->target.ref = git__strdup(refname_start);
- if (ref->target.ref == NULL)
+ ref_sym->target = git__strdup(refname_start);
+ if (ref_sym->target == NULL)
return GIT_ENOMEM;
/* remove newline at the end of file */
- eol = strchr(ref->target.ref, '\n');
+ eol = strchr(ref_sym->target, '\n');
if (eol == NULL)
return GIT_EREFCORRUPTED;
@@ -184,19 +211,19 @@ static int parse_sym_ref(git_reference *ref, gitfo_buf *file_content)
static int parse_oid_ref(git_reference *ref, gitfo_buf *file_content)
{
+ reference_oid *ref_oid;
char *buffer;
- git_oid id;
+
buffer = (char *)file_content->data;
+ ref_oid = (reference_oid *)ref;
/* File format: 40 chars (OID) + newline */
if (file_content->len < GIT_OID_HEXSZ + 1)
return GIT_EREFCORRUPTED;
- if (git_oid_mkstr(&id, buffer) < GIT_SUCCESS)
+ if (git_oid_mkstr(&ref_oid->oid, buffer) < GIT_SUCCESS)
return GIT_EREFCORRUPTED;
- git_oid_cpy(&ref->target.oid, &id);
-
buffer = buffer + GIT_OID_HEXSZ;
if (*buffer == '\r')
buffer++;
@@ -261,7 +288,7 @@ static int lookup_loose_ref(
if (error < GIT_SUCCESS)
goto cleanup;
- error = git_hashtable_insert(repo->references.cache, ref->name, ref);
+ error = git_hashtable_insert(repo->references.loose_refs, ref->name, ref);
if (error < GIT_SUCCESS)
goto cleanup;
@@ -290,12 +317,10 @@ static int read_packed_refs(gitfo_buf *packfile, const char *repo_path)
}
static int parse_packed_line_peel(
- git_reference **ref_out,
- const git_reference *tag_ref,
+ reference_oid *tag_ref,
const char **buffer_out,
const char *buffer_end)
{
- git_oid oid;
const char *buffer = *buffer_out + 1;
assert(buffer[-1] == '^');
@@ -305,14 +330,14 @@ static int parse_packed_line_peel(
return GIT_EPACKEDREFSCORRUPTED;
/* Ensure reference is a tag */
- if (git__prefixcmp(tag_ref->name, GIT_REFS_TAGS_DIR) != 0)
+ if (git__prefixcmp(tag_ref->ref.name, GIT_REFS_TAGS_DIR) != 0)
return GIT_EPACKEDREFSCORRUPTED;
if (buffer + GIT_OID_HEXSZ >= buffer_end)
return GIT_EPACKEDREFSCORRUPTED;
/* Is this a valid object id? */
- if (git_oid_mkstr(&oid, buffer) < GIT_SUCCESS)
+ if (git_oid_mkstr(&tag_ref->peel_target, buffer) < GIT_SUCCESS)
return GIT_EPACKEDREFSCORRUPTED;
buffer = buffer + GIT_OID_HEXSZ;
@@ -323,24 +348,18 @@ static int parse_packed_line_peel(
return GIT_EPACKEDREFSCORRUPTED;
*buffer_out = buffer + 1;
+ tag_ref->ref.type |= GIT_REF_HAS_PEEL;
- /*
- * TODO: do we need the packed line?
- * Right now we don't, so we don't create a new
- * reference.
- */
-
- *ref_out = NULL;
return GIT_SUCCESS;
}
static int parse_packed_line(
- git_reference **ref_out,
+ reference_oid **ref_out,
git_repository *repo,
const char **buffer_out,
const char *buffer_end)
{
- git_reference *ref;
+ reference_oid *ref;
const char *buffer = *buffer_out;
const char *refname_begin, *refname_end;
@@ -375,13 +394,12 @@ static int parse_packed_line(
if (refname[refname_len - 1] == '\r')
refname[refname_len - 1] = 0;
- error = reference_create(&ref, repo, refname, GIT_REF_OID);
+ error = reference_create((git_reference **)&ref, repo, refname, GIT_REF_OID);
if (error < GIT_SUCCESS)
goto cleanup;
- git_oid_cpy(&ref->target.oid, &id);
-
- ref->packed = 1;
+ git_oid_cpy(&ref->oid, &id);
+ ref->ref.type |= GIT_REF_PACKED;
*ref_out = ref;
*buffer_out = refname_end + 1;
@@ -389,11 +407,11 @@ static int parse_packed_line(
return GIT_SUCCESS;
cleanup:
- reference_free(ref);
+ reference_free((git_reference *)ref);
return error;
}
-static int parse_packed_refs(git_refcache *ref_cache, git_repository *repo)
+static int load_packed_refs(git_refcache *ref_cache, git_repository *repo)
{
int error = GIT_SUCCESS;
gitfo_buf packfile = GITFO_BUF_INIT;
@@ -425,34 +443,21 @@ static int parse_packed_refs(git_refcache *ref_cache, git_repository *repo)
while (buffer_start < buffer_end) {
- git_reference *ref = NULL;
- git_reference *ref_tag = NULL;
+ reference_oid *ref = NULL;
error = parse_packed_line(&ref, repo, &buffer_start, buffer_end);
if (error < GIT_SUCCESS)
goto cleanup;
if (buffer_start[0] == '^') {
- error = parse_packed_line_peel(&ref_tag, ref, &buffer_start, buffer_end);
+ error = parse_packed_line_peel(ref, &buffer_start, buffer_end);
if (error < GIT_SUCCESS)
goto cleanup;
}
- /*
- * If a loose reference exists with the same name,
- * we assume that the loose reference is more up-to-date.
- * We don't need to cache this ref from the packfile.
- */
- if (read_loose_ref(NULL, ref->name, repo->path_repository) == GIT_SUCCESS) {
- reference_free(ref);
- reference_free(ref_tag);
- continue;
- }
-
- error = git_hashtable_insert(ref_cache->cache, ref->name, ref);
+ error = git_hashtable_insert(ref_cache->packed_refs, ref->ref.name, ref);
if (error < GIT_SUCCESS) {
- reference_free(ref);
- reference_free(ref_tag);
+ reference_free((git_reference *)ref);
goto cleanup;
}
}
@@ -466,22 +471,32 @@ cleanup:
int git_reference_set_oid(git_reference *ref, const git_oid *id)
{
- if (ref->type != GIT_REF_OID)
+ reference_oid *ref_oid;
+
+ if ((ref->type & GIT_REF_OID) == 0)
return GIT_EINVALIDREFSTATE;
- git_oid_cpy(&ref->target.oid, id);
+ ref_oid = (reference_oid *)ref;
+ git_oid_cpy(&ref_oid->oid, id);
+
+ ref->type &= ~GIT_REF_HAS_PEEL;
+ /* TODO: set new peel target */
return reference_write(ref);
}
int git_reference_set_target(git_reference *ref, const char *target)
{
- if (ref->type != GIT_REF_SYMBOLIC)
+ reference_symbolic *ref_sym;
+
+ if ((ref->type & GIT_REF_SYMBOLIC) == 0)
return GIT_EINVALIDREFSTATE;
- free(ref->target.ref);
- ref->target.ref = git__strdup(target);
- if (ref->target.ref == NULL)
+ ref_sym = (reference_symbolic *)ref;
+
+ free(ref_sym->target);
+ ref_sym->target = git__strdup(target);
+ if (ref_sym->target == NULL)
return GIT_ENOMEM;
return reference_write(ref);
@@ -491,26 +506,33 @@ const git_oid *git_reference_oid(git_reference *ref)
{
assert(ref);
- if (ref->type != GIT_REF_OID)
+ if ((ref->type & GIT_REF_OID) == 0)
return NULL;
- return &ref->target.oid;
+ return &((reference_oid *)ref)->oid;
}
const char *git_reference_target(git_reference *ref)
{
assert(ref);
- if (ref->type != GIT_REF_SYMBOLIC)
+ if ((ref->type & GIT_REF_SYMBOLIC) == 0)
return NULL;
- return ref->target.ref;
+ return ((reference_symbolic *)ref)->target;
}
git_rtype git_reference_type(git_reference *ref)
{
assert(ref);
- return ref->type;
+
+ if (ref->type & GIT_REF_OID)
+ return GIT_REF_OID;
+
+ if (ref->type & GIT_REF_SYMBOLIC)
+ return GIT_REF_SYMBOLIC;
+
+ return GIT_REF_INVALID;
}
const char *git_reference_name(git_reference *ref)
@@ -536,13 +558,15 @@ int git_reference_resolve(git_reference **resolved_ref, git_reference *ref)
repo = ref->owner;
for (i = 0; i < MAX_NESTING_LEVEL; ++i) {
+ reference_symbolic *ref_sym;
- if (ref->type == GIT_REF_OID) {
+ if (ref->type & GIT_REF_OID) {
*resolved_ref = ref;
return GIT_SUCCESS;
}
- if ((error = git_repository_lookup_ref(&ref, repo, ref->target.ref)) < GIT_SUCCESS)
+ ref_sym = (reference_symbolic *)ref;
+ if ((error = git_repository_lookup_ref(&ref, repo, ref_sym->target)) < GIT_SUCCESS)
return error;
}
@@ -556,14 +580,13 @@ static int reference_write(git_reference *ref)
int error, contents_size;
char *ref_contents = NULL;
- assert(ref->type == GIT_REF_OID || ref->type == GIT_REF_SYMBOLIC);
-
git__joinpath(ref_path, ref->owner->path_repository, ref->name);
if ((error = git_filebuf_open(&file, ref_path, 0)) < GIT_SUCCESS)
- goto error_cleanup;
+ return error;
- if (ref->type == GIT_REF_OID) {
+ if (ref->type & GIT_REF_OID) {
+ reference_oid *ref_oid = (reference_oid *)ref;
contents_size = GIT_OID_HEXSZ + 1;
ref_contents = git__malloc(contents_size);
@@ -572,11 +595,12 @@ static int reference_write(git_reference *ref)
goto unlock;
}
- git_oid_fmt(ref_contents, &ref->target.oid);
+ git_oid_fmt(ref_contents, &ref_oid->oid);
- } else { /* GIT_REF_SYMBOLIC */
+ } else if (ref->type & GIT_REF_SYMBOLIC) { /* GIT_REF_SYMBOLIC */
+ reference_symbolic *ref_sym = (reference_symbolic *)ref;
- contents_size = strlen(GIT_SYMREF) + strlen(ref->target.ref) + 1;
+ contents_size = strlen(GIT_SYMREF) + strlen(ref_sym->target) + 1;
ref_contents = git__malloc(contents_size);
if (ref_contents == NULL) {
error = GIT_ENOMEM;
@@ -584,28 +608,25 @@ static int reference_write(git_reference *ref)
}
strcpy(ref_contents, GIT_SYMREF);
- strcat(ref_contents, ref->target.ref);
+ strcat(ref_contents, ref_sym->target);
+ } else {
+ error = GIT_EINVALIDREFSTATE;
+ goto unlock;
}
/* TODO: win32 carriage return when writing references in Windows? */
ref_contents[contents_size - 1] = '\n';
if ((error = git_filebuf_write(&file, ref_contents, contents_size)) < GIT_SUCCESS)
- goto error_cleanup;
-
- error = git_filebuf_commit(&file);
- if (error < GIT_SUCCESS)
goto unlock;
- error = git_hashtable_insert(ref->owner->references.cache, ref->name, ref);
- if (error < GIT_SUCCESS)
- goto unlock;
+ error = git_filebuf_commit(&file);
free(ref_contents);
- return GIT_SUCCESS;
+ return error;
unlock:
- git_filebuf_cleanup(&lock);
+ git_filebuf_cleanup(&file);
free(ref_contents);
return error;
}
@@ -619,7 +640,7 @@ int git_repository_lookup_ref(git_reference **ref_out, git_repository *repo, con
*ref_out = NULL;
- error = git_reference__normalize_name(normalized_name, name, GIT_REF_ANY);
+ error = normalize_name(normalized_name, name, 0);
if (error < GIT_SUCCESS)
return error;
@@ -627,7 +648,7 @@ int git_repository_lookup_ref(git_reference **ref_out, git_repository *repo, con
* First, check if the reference is on the local cache;
* references on the cache are assured to be up-to-date
*/
- *ref_out = git_hashtable_lookup(repo->references.cache, normalized_name);
+ *ref_out = git_hashtable_lookup(repo->references.loose_refs, normalized_name);
if (*ref_out != NULL)
return GIT_SUCCESS;
@@ -644,28 +665,17 @@ int git_repository_lookup_ref(git_reference **ref_out, git_repository *repo, con
if (error != GIT_ENOTFOUND)
return error;
- /*
- * Check if we have loaded the packed references.
- * If the packed references have been loaded, they would be
- * stored already on the cache: that means that the ref
- * we are looking for doesn't exist.
- *
- * If they haven't been loaded yet, we load the packfile
- * and check if our reference is inside of it.
- */
if (!repo->references.pack_loaded) {
-
/* load all the packed references */
- error = parse_packed_refs(&repo->references, repo);
+ error = load_packed_refs(&repo->references, repo);
if (error < GIT_SUCCESS)
return error;
-
- /* check the cache again -- hopefully the reference will be there */
- *ref_out = git_hashtable_lookup(repo->references.cache, normalized_name);
- if (*ref_out != NULL)
- return GIT_SUCCESS;
}
+ *ref_out = git_hashtable_lookup(repo->references.packed_refs, normalized_name);
+ if (*ref_out != NULL)
+ return GIT_SUCCESS;
+
/* The reference doesn't exist anywhere */
return GIT_ENOTFOUND;
}
@@ -674,26 +684,36 @@ int git_repository__refcache_init(git_refcache *refs)
{
assert(refs);
- refs->cache = git_hashtable_alloc(
+ refs->loose_refs = git_hashtable_alloc(
+ default_table_size,
+ reftable_hash,
+ (git_hash_keyeq_ptr)strcmp);
+
+ refs->packed_refs = git_hashtable_alloc(
default_table_size,
reftable_hash,
(git_hash_keyeq_ptr)strcmp);
- return refs->cache ? GIT_SUCCESS : GIT_ENOMEM;
+ return (refs->loose_refs && refs->packed_refs) ? GIT_SUCCESS : GIT_ENOMEM;
}
void git_repository__refcache_free(git_refcache *refs)
{
- const char *ref_name;
git_reference *reference;
+ const void *_unused;
assert(refs);
- GIT_HASHTABLE_FOREACH(refs->cache, ref_name, reference,
- reference_free(reference)
+ GIT_HASHTABLE_FOREACH(refs->loose_refs, _unused, reference,
+ reference_free(reference);
+ );
+
+ GIT_HASHTABLE_FOREACH(refs->packed_refs, _unused, reference,
+ reference_free(reference);
);
- git_hashtable_free(refs->cache);
+ git_hashtable_free(refs->loose_refs);
+ git_hashtable_free(refs->packed_refs);
}
static int check_valid_ref_char(char ch)
@@ -717,7 +737,8 @@ static int check_valid_ref_char(char ch)
}
}
-int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype type)
+
+static int normalize_name(char *buffer_out, const char *name, int is_oid_ref)
{
int error = GIT_SUCCESS;
const char *name_end, *buffer_out_start;
@@ -730,9 +751,6 @@ int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype
current = (char *)name;
name_end = name + strlen(name);
- if (type == GIT_REF_INVALID)
- return GIT_EINVALIDTYPE;
-
/* A refname can not be empty */
if (name_end == name)
return GIT_EINVALIDREFNAME;
@@ -770,7 +788,7 @@ int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype
}
/* Object id refname have to contain at least one slash */
- if (type == GIT_REF_OID && !contains_a_slash)
+ if (is_oid_ref && !contains_a_slash)
return GIT_EINVALIDREFNAME;
/* A refname can not end with ".lock" */
@@ -780,10 +798,21 @@ int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype
*buffer_out = '\0';
/* For object id references, name has to start with refs/(heads|tags|remotes) */
- if (type == GIT_REF_OID && !(!git__prefixcmp(buffer_out_start, GIT_REFS_HEADS_DIR) ||
+ if (is_oid_ref && !(!git__prefixcmp(buffer_out_start, GIT_REFS_HEADS_DIR) ||
!git__prefixcmp(buffer_out_start, GIT_REFS_TAGS_DIR) || !git__prefixcmp(buffer_out_start, GIT_REFS_REMOTES_DIR)))
return GIT_EINVALIDREFNAME;
return error;
}
+int git_reference__normalize_name(char *buffer_out, const char *name)
+{
+ return normalize_name(buffer_out, name, 0);
+}
+
+int git_reference__normalize_name_oid(char *buffer_out, const char *name)
+{
+ return normalize_name(buffer_out, name, 1);
+}
+
+
diff --git a/src/refs.h b/src/refs.h
index 33bedc4b7..5fc71fc83 100644
--- a/src/refs.h
+++ b/src/refs.h
@@ -18,25 +18,22 @@
struct git_reference {
git_repository *owner;
- git_rtype type;
char *name;
-
- unsigned packed:1;
-
- union {
- char *ref;
- git_oid oid;
- } target;
+ unsigned int type;
};
typedef struct {
- git_hashtable *cache;
+ git_hashtable *packed_refs;
+ git_hashtable *loose_refs;
+
unsigned pack_loaded:1;
} git_refcache;
void git_repository__refcache_free(git_refcache *refs);
int git_repository__refcache_init(git_refcache *refs);
-int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype type);
+
+int git_reference__normalize_name(char *buffer_out, const char *name);
+int git_reference__normalize_name_oid(char *buffer_out, const char *name);
#endif
diff --git a/src/vector.c b/src/vector.c
index 325f34306..e19497748 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -35,18 +35,13 @@ static int resize_vector(git_vector *v)
void **new_contents;
v->_alloc_size = ((unsigned int)(v->_alloc_size * resize_factor)) + 1;
- if (v->_alloc_size == 0)
+ if (v->_alloc_size < minimum_size)
v->_alloc_size = minimum_size;
- new_contents = git__malloc(v->_alloc_size * sizeof(void *));
- if (new_contents == NULL)
+ v->contents = realloc(v->contents, v->_alloc_size * sizeof(void *));
+ if (v->contents == NULL)
return GIT_ENOMEM;
- memcpy(new_contents, v->contents, v->length * sizeof(void *));
-
- free(v->contents);
- v->contents = new_contents;
-
return GIT_SUCCESS;
}
@@ -93,12 +88,6 @@ int git_vector_insert(git_vector *v, void *element)
return GIT_SUCCESS;
}
-void *git_vector_get(git_vector *v, unsigned int position)
-{
- assert(v);
- return (position < v->length) ? v->contents[position] : NULL;
-}
-
void git_vector_sort(git_vector *v)
{
assert(v);
diff --git a/src/vector.h b/src/vector.h
index 305927a72..dfd604765 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -24,7 +24,10 @@ void git_vector_clear(git_vector *v);
int git_vector_search(git_vector *v, const void *key);
void git_vector_sort(git_vector *v);
-void *git_vector_get(git_vector *v, unsigned int position);
+GIT_INLINE(void *) git_vector_get(git_vector *v, unsigned int position)
+{
+ return (position < v->length) ? v->contents[position] : NULL;
+}
int git_vector_insert(git_vector *v, void *element);
int git_vector_remove(git_vector *v, unsigned int idx);