diff options
author | Vicent Martà <vicent@github.com> | 2012-07-13 06:56:24 -0700 |
---|---|---|
committer | Vicent Martà <vicent@github.com> | 2012-07-13 06:56:24 -0700 |
commit | 0848ec24faf3b6e182d01f61d62540c6f6480c39 (patch) | |
tree | 5a34d3a4dc7287b7abcc6a3e046bdab07dd3f701 /src | |
parent | 68c5ef5cc5392dc3b1895fdc03d4135536a9fa57 (diff) | |
parent | b5f90115240e333a60809ef912934bce8afae0c1 (diff) | |
download | libgit2-0848ec24faf3b6e182d01f61d62540c6f6480c39.tar.gz |
Merge pull request #815 from nulltoken/topic/revparse-refac
More revparse <3
Diffstat (limited to 'src')
-rw-r--r-- | src/revparse.c | 111 | ||||
-rw-r--r-- | src/tree.c | 5 |
2 files changed, 34 insertions, 82 deletions
diff --git a/src/revparse.c b/src/revparse.c index 2b03c86b4..777dee685 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -147,23 +147,23 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const if (error < 0 && error != GIT_ENOTFOUND) return error; - error = maybe_sha_or_abbrev(out, repo, spec); - if (!error) - return 0; - - if (error < 0 && error != GIT_ENOTFOUND) - return error; - error = disambiguate_refname(&ref, repo, spec); if (!error) { error = git_object_lookup(out, repo, git_reference_oid(ref), GIT_OBJ_ANY); git_reference_free(ref); - return 0; + return error; } if (error < 0 && error != GIT_ENOTFOUND) return error; + error = maybe_sha_or_abbrev(out, repo, spec); + if (!error) + return 0; + + if (error < 0 && error != GIT_ENOTFOUND) + return error; + giterr_set(GITERR_REFERENCE, "Refspec '%s' not found.", spec); return GIT_ENOTFOUND; } @@ -482,7 +482,7 @@ static int handle_caret_syntax(git_object **out, git_repository *repo, git_objec if (movementlen == 0) { n = 1; } else { - git__strtol32(&n, movement, NULL, 0); + git__strtol32(&n, movement, NULL, 10); } commit = (git_commit*)obj; @@ -513,95 +513,44 @@ static int handle_linear_syntax(git_object **out, git_object *obj, const char *m /* "~" is the same as "~1" */ if (*movement == '\0') { n = 1; - } else if (git__strtol32(&n, movement, NULL, 0) < 0) { + } else if (git__strtol32(&n, movement, NULL, 10) < 0) { return GIT_ERROR; } return git_commit_nth_gen_ancestor((git_commit **)out, (git_commit*)obj, n); } -static int oid_for_tree_path(git_oid *out, git_tree *tree, git_repository *repo, const char *path) -{ - char *str, *tok; - void *alloc; - git_tree *tree2 = tree; - const git_tree_entry *entry = NULL; - git_otype type; - - if (*path == '\0') { - git_oid_cpy(out, git_object_id((git_object *)tree)); - return 0; - } - - alloc = str = git__strdup(path); - - while ((tok = git__strtok(&str, "/\\")) != NULL) { - entry = git_tree_entry_byname(tree2, tok); - if (tree2 != tree) git_tree_free(tree2); - - if (entry == NULL) - break; - - type = git_tree_entry_type(entry); - - switch (type) { - case GIT_OBJ_TREE: - if (*str == '\0') - break; - if (git_tree_lookup(&tree2, repo, &entry->oid) < 0) { - git__free(alloc); - return GIT_ERROR; - } - break; - case GIT_OBJ_BLOB: - if (*str != '\0') { - entry = NULL; - goto out; - } - break; - default: - /* TODO: support submodules? */ - giterr_set(GITERR_INVALID, "Unimplemented"); - git__free(alloc); - return GIT_ERROR; - } - } - -out: - if (!entry) { - giterr_set(GITERR_INVALID, "Invalid tree path '%s'", path); - git__free(alloc); - return GIT_ENOTFOUND; - } - - git_oid_cpy(out, git_tree_entry_id(entry)); - git__free(alloc); - return 0; -} - static int handle_colon_syntax(git_object **out, git_repository *repo, git_object *obj, const char *path) { - git_tree *tree; - git_oid oid; - int error; + git_object *tree = obj; + int error = -1; + git_tree_entry *entry = NULL; /* Dereference until we reach a tree. */ - if (dereference_to_type(&obj, obj, GIT_OBJ_TREE) < 0) { + if (dereference_to_type(&tree, obj, GIT_OBJ_TREE) < 0) return GIT_ERROR; - } - tree = (git_tree*)obj; - /* Find the blob or tree at the given path. */ - error = oid_for_tree_path(&oid, tree, repo, path); - git_tree_free(tree); + if (*path == '\0') + return git_object_lookup(out, repo, git_object_id(tree), GIT_OBJ_TREE); - if (error < 0) - return error; + /* + * TODO: Handle the relative path syntax + * (:./relative/path and :../relative/path) + */ + if ((error = git_tree_entry_bypath(&entry, (git_tree *)tree, path)) < 0) + goto cleanup; + + error = git_tree_entry_to_object(out, repo, entry); - return git_object_lookup(out, repo, &oid, GIT_OBJ_ANY); +cleanup: + git_tree_entry_free(entry); + if (tree != obj) + git_object_free(tree); + + return error; } static int revparse_global_grep(git_object **out, git_repository *repo, const char *pattern) diff --git a/src/tree.c b/src/tree.c index b609eea33..31a581cdb 100644 --- a/src/tree.c +++ b/src/tree.c @@ -140,6 +140,9 @@ static int tree_key_search(git_vector *entries, const char *filename, size_t fil void git_tree_entry_free(git_tree_entry *entry) { + if (entry == NULL) + return; + git__free(entry); } @@ -727,7 +730,7 @@ int git_tree_entry_bypath( if (!git_tree_entry__is_tree(entry)) { giterr_set(GITERR_TREE, "The path '%s' does not exist in the given tree", path); - return -1; + return GIT_ENOTFOUND; } /* If there's only a slash left in the path, we |