summaryrefslogtreecommitdiff
path: root/src/refs.c
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2011-02-18 18:09:19 +0200
committerVicent Marti <tanoku@gmail.com>2011-03-03 20:23:49 +0200
commit32054c24a26ab386fb56c7333fa723459e7e8dff (patch)
tree5cf4c8240ed7f43a807fe962dc9f8d859401a9d4 /src/refs.c
parent2de3b35cd4cc92a35f45cf2e7e27fc35f866e370 (diff)
downloadlibgit2-32054c24a26ab386fb56c7333fa723459e7e8dff.tar.gz
Brush up the refs API
Changed some more API details and updated documentation. Sketched API for addition/removal of entries. Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src/refs.c')
-rw-r--r--src/refs.c94
1 files changed, 30 insertions, 64 deletions
diff --git a/src/refs.c b/src/refs.c
index 0cae6ee13..8fa157cb2 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -30,6 +30,8 @@
#define MAX_NESTING_LEVEL 5
+static int reference_write(git_reference *ref);
+
static const int default_table_size = 32;
static uint32_t reftable_hash(const void *key, int hash_id)
@@ -43,17 +45,6 @@ static uint32_t reftable_hash(const void *key, int hash_id)
return git__hash(key, strlen((const char *)key), hash_seeds[hash_id]);
}
-static int check_refname(const char *name)
-{
- /*
- * TODO: To be implemented
- * Check if the given name is a valid name
- * for a reference
- */
-
- return name ? GIT_SUCCESS : GIT_ERROR;
-}
-
static void reference_free(git_reference *reference)
{
if (reference == NULL)
@@ -68,7 +59,7 @@ static void reference_free(git_reference *reference)
free(reference);
}
-static int reference__create(git_reference **ref_out, git_repository *repo, const char *name, git_rtype type) {
+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;
git_reference *reference = NULL;
@@ -111,7 +102,7 @@ int git_reference_create_symbolic(git_reference **ref_out, git_repository *repo,
int error = GIT_SUCCESS;
git_reference *ref = NULL;
- error = reference__create(&ref, repo, name, GIT_REF_SYMBOLIC);
+ error = reference_create(&ref, repo, name, GIT_REF_SYMBOLIC);
if (error < GIT_SUCCESS)
goto cleanup;
@@ -120,14 +111,11 @@ int git_reference_create_symbolic(git_reference **ref_out, git_repository *repo,
if (error < GIT_SUCCESS)
goto cleanup;
+ /* set the target; this will write the reference on disk */
error = git_reference_set_target(ref, normalized);
if (error < GIT_SUCCESS)
goto cleanup;
- error = git_reference_write(ref);
- if (error < GIT_SUCCESS)
- goto cleanup;
-
*ref_out = ref;
return error;
@@ -142,18 +130,15 @@ int git_reference_create_oid(git_reference **ref_out, git_repository *repo, cons
int error = GIT_SUCCESS;
git_reference *ref = NULL;
- error = reference__create(&ref, repo, name, GIT_REF_OID);
+ error = reference_create(&ref, repo, name, GIT_REF_OID);
if (error < GIT_SUCCESS)
goto cleanup;
+ /* set the oid; this will write the reference on disk */
error = git_reference_set_oid(ref, id);
if (error < GIT_SUCCESS)
goto cleanup;
- error = git_reference_write(ref);
- if (error < GIT_SUCCESS)
- goto cleanup;
-
*ref_out = ref;
return error;
@@ -168,7 +153,6 @@ 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;
- int error;
refname_start = (const char *)file_content->data;
@@ -182,9 +166,9 @@ static int parse_sym_ref(git_reference *ref, gitfo_buf *file_content)
refname_start += header_len;
- error = git_reference_set_target(ref, refname_start);
- if (error < GIT_SUCCESS)
- return error;
+ ref->target.ref = git__strdup(refname_start);
+ if (ref->target.ref == NULL)
+ return GIT_ENOMEM;
/* remove newline at the end of file */
eol = strchr(ref->target.ref, '\n');
@@ -202,8 +186,6 @@ static int parse_oid_ref(git_reference *ref, gitfo_buf *file_content)
{
char *buffer;
git_oid id;
- int error;
-
buffer = (char *)file_content->data;
/* File format: 40 chars (OID) + newline */
@@ -213,9 +195,7 @@ static int parse_oid_ref(git_reference *ref, gitfo_buf *file_content)
if (git_oid_mkstr(&id, buffer) < GIT_SUCCESS)
return GIT_EREFCORRUPTED;
- error = git_reference_set_oid(ref, &id);
- if (error < GIT_SUCCESS)
- return error;
+ git_oid_cpy(&ref->target.oid, &id);
buffer = buffer + GIT_OID_HEXSZ;
if (*buffer == '\r')
@@ -265,21 +245,19 @@ static int lookup_loose_ref(
goto cleanup;
if (git__prefixcmp((const char *)(ref_file.data), GIT_SYMREF) == 0) {
- error = reference__create(&ref, repo, name, GIT_REF_SYMBOLIC);
+ error = reference_create(&ref, repo, name, GIT_REF_SYMBOLIC);
if (error < GIT_SUCCESS)
goto cleanup;
error = parse_sym_ref(ref, &ref_file);
} else {
- error = reference__create(&ref, repo, name, GIT_REF_OID);
+ error = reference_create(&ref, repo, name, GIT_REF_OID);
if (error < GIT_SUCCESS)
goto cleanup;
error = parse_oid_ref(ref, &ref_file);
}
- ref->modified = 0;
-
if (error < GIT_SUCCESS)
goto cleanup;
@@ -397,16 +375,13 @@ 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(&ref, repo, refname, GIT_REF_OID);
if (error < GIT_SUCCESS)
goto cleanup;
- error = git_reference_set_oid(ref, &id);
- if (error < GIT_SUCCESS)
- goto cleanup;
+ git_oid_cpy(&ref->target.oid, &id);
ref->packed = 1;
- ref->modified = 0;
*ref_out = ref;
*buffer_out = refname_end + 1;
@@ -496,9 +471,7 @@ int git_reference_set_oid(git_reference *ref, const git_oid *id)
git_oid_cpy(&ref->target.oid, id);
- ref->modified = 1;
-
- return GIT_SUCCESS;
+ return reference_write(ref);
}
int git_reference_set_target(git_reference *ref, const char *target)
@@ -511,9 +484,7 @@ int git_reference_set_target(git_reference *ref, const char *target)
if (ref->target.ref == NULL)
return GIT_ENOMEM;
- ref->modified = 1;
-
- return GIT_SUCCESS;
+ return reference_write(ref);
}
const git_oid *git_reference_oid(git_reference *ref)
@@ -528,6 +499,8 @@ const git_oid *git_reference_oid(git_reference *ref)
const char *git_reference_target(git_reference *ref)
{
+ assert(ref);
+
if (ref->type != GIT_REF_SYMBOLIC)
return NULL;
@@ -576,19 +549,14 @@ int git_reference_resolve(git_reference **resolved_ref, git_reference *ref)
return GIT_ETOONESTEDSYMREF;
}
-int git_reference_write(git_reference *ref)
+static int reference_write(git_reference *ref)
{
git_filebuf file;
- git_reference *looked_up_reference;
char ref_path[GIT_PATH_MAX];
int error, contents_size;
char *ref_contents = NULL;
- if (ref->type == GIT_REF_INVALID || ref->type == GIT_REF_ANY)
- return GIT_EINVALIDREFSTATE;
-
- if (!ref->modified)
- return GIT_SUCCESS;
+ assert(ref->type == GIT_REF_OID || ref->type == GIT_REF_SYMBOLIC);
git__joinpath(ref_path, ref->owner->path_repository, ref->name);
@@ -619,27 +587,25 @@ int git_reference_write(git_reference *ref)
strcat(ref_contents, ref->target.ref);
}
+ /* 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;
- looked_up_reference = git_hashtable_lookup(ref->owner->references.cache, ref->name);
-
- if (looked_up_reference == NULL) {
- error = git_hashtable_insert(ref->owner->references.cache, ref->name, ref);
- if (error < GIT_SUCCESS)
- goto cleanup;
- }
+ error = git_hashtable_insert(ref->owner->references.cache, ref->name, ref);
+ if (error < GIT_SUCCESS)
+ goto unlock;
- goto cleanup;
+ free(ref_contents);
+ return GIT_SUCCESS;
unlock:
- git_filelock_unlock(&lock);
-
-cleanup:
+ git_filebuf_cleanup(&lock);
free(ref_contents);
return error;
}