diff options
| author | Vicent Marti <tanoku@gmail.com> | 2011-02-18 18:09:19 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-03-03 20:23:49 +0200 |
| commit | 32054c24a26ab386fb56c7333fa723459e7e8dff (patch) | |
| tree | 5cf4c8240ed7f43a807fe962dc9f8d859401a9d4 /src/refs.c | |
| parent | 2de3b35cd4cc92a35f45cf2e7e27fc35f866e370 (diff) | |
| download | libgit2-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.c | 94 |
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; } |
