From bf522e08114a4dc25815b09db201266a0791381c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 26 Jan 2014 16:59:36 +0100 Subject: [PATCH] refspec: move to git_buf for outputting strings --- include/git2/refspec.h | 7 ++--- src/branch.c | 4 +-- src/clone.c | 4 +-- src/push.c | 2 +- src/refspec.c | 54 +++------------------------------- src/refspec.h | 22 -------------- src/remote.c | 4 +-- tests/network/remote/remotes.c | 21 +++++-------- tests/online/push.c | 2 +- 9 files changed, 22 insertions(+), 98 deletions(-) diff --git a/include/git2/refspec.h b/include/git2/refspec.h index d96b83ce2..9acdc72d5 100644 --- a/include/git2/refspec.h +++ b/include/git2/refspec.h @@ -10,6 +10,7 @@ #include "common.h" #include "types.h" #include "net.h" +#include "buffer.h" /** * @file git2/refspec.h @@ -82,23 +83,21 @@ GIT_EXTERN(int) git_refspec_dst_matches(const git_refspec *refspec, const char * * Transform a reference to its target following the refspec's rules * * @param out where to store the target name - * @param outlen the size of the `out` buffer * @param spec the refspec * @param name the name of the reference to transform * @return 0, GIT_EBUFS or another error */ -GIT_EXTERN(int) git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name); +GIT_EXTERN(int) git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name); /** * Transform a target reference to its source reference following the refspec's rules * * @param out where to store the source reference name - * @param outlen the size of the `out` buffer * @param spec the refspec * @param name the name of the reference to transform * @return 0, GIT_EBUFS or another error */ -GIT_EXTERN(int) git_refspec_rtransform(char *out, size_t outlen, const git_refspec *spec, const char *name); +GIT_EXTERN(int) git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name); GIT_END_DECL diff --git a/src/branch.c b/src/branch.c index a702c661e..a1a04b2b4 100644 --- a/src/branch.c +++ b/src/branch.c @@ -329,7 +329,7 @@ int git_branch_upstream_name( goto cleanup; } - if (git_refspec_transform_r(&buf, refspec, merge_name) < 0) + if (git_refspec_transform(&buf, refspec, merge_name) < 0) goto cleanup; } else if (git_buf_sets(&buf, merge_name) < 0) @@ -520,7 +520,7 @@ int git_branch_set_upstream(git_reference *branch, const char *upstream_name) fetchspec = git_remote__matching_dst_refspec(remote, git_reference_name(upstream)); git_buf_clear(&value); - if (!fetchspec || git_refspec_transform_l(&value, fetchspec, git_reference_name(upstream)) < 0) + if (!fetchspec || git_refspec_rtransform(&value, fetchspec, git_reference_name(upstream)) < 0) goto on_error; git_remote_free(remote); diff --git a/src/clone.c b/src/clone.c index 828c47ffb..2e9d72ab9 100644 --- a/src/clone.c +++ b/src/clone.c @@ -131,7 +131,7 @@ static int reference_matches_remote_head( if (!error && !git_oid__cmp(&head_info->remote_head_oid, &oid)) { /* Determine the local reference name from the remote tracking one */ - error = git_refspec_transform_l( + error = git_refspec_rtransform( &head_info->branchname, head_info->refspec, reference_name); if (!error && @@ -199,7 +199,7 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) } /* Determine the remote tracking reference name from the local master */ - if ((error = git_refspec_transform_r( + if ((error = git_refspec_transform( &remote_master_name, head_info.refspec, GIT_REFS_HEADS_MASTER_FILE)) < 0) diff --git a/src/push.c b/src/push.c index 0be82f3b2..d39a27182 100644 --- a/src/push.c +++ b/src/push.c @@ -214,7 +214,7 @@ int git_push_update_tips(git_push *push) if (!fetch_spec) continue; - if ((error = git_refspec_transform_r(&remote_ref_name, fetch_spec, status->ref)) < 0) + if ((error = git_refspec_transform(&remote_ref_name, fetch_spec, status->ref)) < 0) goto on_error; /* Find matching push ref spec */ diff --git a/src/refspec.c b/src/refspec.c index a97340071..fa60aa7aa 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -178,54 +178,6 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname) return (p_fnmatch(refspec->dst, refname, 0) == 0); } -static int refspec_transform_internal(char *out, size_t outlen, const char *from, const char *to, const char *name) -{ - size_t baselen, namelen; - - baselen = strlen(to); - if (outlen <= baselen) { - giterr_set(GITERR_INVALID, "Reference name too long"); - return GIT_EBUFS; - } - - /* - * No '*' at the end means that it's mapped to one specific local - * branch, so no actual transformation is needed. - */ - if (to[baselen - 1] != '*') { - memcpy(out, to, baselen + 1); /* include '\0' */ - return 0; - } - - /* There's a '*' at the end, so remove its length */ - baselen--; - - /* skip the prefix, -1 is for the '*' */ - name += strlen(from) - 1; - - namelen = strlen(name); - - if (outlen <= baselen + namelen) { - giterr_set(GITERR_INVALID, "Reference name too long"); - return GIT_EBUFS; - } - - memcpy(out, to, baselen); - memcpy(out + baselen, name, namelen + 1); - - return 0; -} - -int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name) -{ - return refspec_transform_internal(out, outlen, spec->src, spec->dst, name); -} - -int git_refspec_rtransform(char *out, size_t outlen, const git_refspec *spec, const char *name) -{ - return refspec_transform_internal(out, outlen, spec->dst, spec->src, name); -} - static int refspec_transform( git_buf *out, const char *from, const char *to, const char *name) { @@ -233,6 +185,8 @@ static int refspec_transform( size_t from_len = from ? strlen(from) : 0; size_t name_len = name ? strlen(name) : 0; + git_buf_sanitize(out); + if (git_buf_set(out, to, to_len) < 0) return -1; @@ -253,12 +207,12 @@ static int refspec_transform( return git_buf_put(out, name + from_len, name_len - from_len); } -int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name) +int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) { return refspec_transform(out, spec->src, spec->dst, name); } -int git_refspec_transform_l(git_buf *out, const git_refspec *spec, const char *name) +int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) { return refspec_transform(out, spec->dst, spec->src, name); } diff --git a/src/refspec.h b/src/refspec.h index 51b7bfee9..375465f61 100644 --- a/src/refspec.h +++ b/src/refspec.h @@ -31,28 +31,6 @@ int git_refspec__parse( void git_refspec__free(git_refspec *refspec); -/** - * Transform a reference to its target following the refspec's rules, - * and writes the results into a git_buf. - * - * @param out where to store the target name - * @param spec the refspec - * @param name the name of the reference to transform - * @return 0 or error if buffer allocation fails - */ -int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name); - -/** - * Transform a reference from its target following the refspec's rules, - * and writes the results into a git_buf. - * - * @param out where to store the source name - * @param spec the refspec - * @param name the name of the reference to transform - * @return 0 or error if buffer allocation fails - */ -int git_refspec_transform_l(git_buf *out, const git_refspec *spec, const char *name); - int git_refspec__serialize(git_buf *out, const git_refspec *refspec); /** diff --git a/src/remote.c b/src/remote.c index 5b3656a81..5d35affd1 100644 --- a/src/remote.c +++ b/src/remote.c @@ -896,7 +896,7 @@ static int remote_head_for_ref(git_remote_head **out, git_refspec *spec, git_vec if ((error = git_reference_resolve(&resolved_ref, ref)) < 0 || (!git_reference_is_branch(resolved_ref)) || (error = git_branch_upstream(&tracking_ref, resolved_ref)) < 0 || - (error = git_refspec_transform_l(&remote_name, spec, git_reference_name(tracking_ref))) < 0) { + (error = git_refspec_rtransform(&remote_name, spec, git_reference_name(tracking_ref))) < 0) { /* Not an error if HEAD is unborn or no tracking branch */ if (error == GIT_ENOTFOUND) error = 0; @@ -1011,7 +1011,7 @@ static int update_tips_for_spec(git_remote *remote, git_refspec *spec, git_vecto continue; if (git_refspec_src_matches(spec, head->name) && spec->dst) { - if (git_refspec_transform_r(&refname, spec, head->name) < 0) + if (git_refspec_transform(&refname, spec, head->name) < 0) goto on_error; } else if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) { diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index 44a98d31a..09963e8ef 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -230,27 +230,20 @@ void test_network_remote_remotes__fnmatch(void) void test_network_remote_remotes__transform(void) { - char ref[1024] = {0}; + git_buf ref = GIT_BUF_INIT; - cl_git_pass(git_refspec_transform(ref, sizeof(ref), _refspec, "refs/heads/master")); + cl_git_pass(git_refspec_transform(&ref, _refspec, "refs/heads/master")); cl_assert_equal_s(ref, "refs/remotes/test/master"); + git_buf_free(&ref); } void test_network_remote_remotes__transform_destination_to_source(void) { - char ref[1024] = {0}; + git_buf ref = GIT_BUF_INIT; - cl_git_pass(git_refspec_rtransform(ref, sizeof(ref), _refspec, "refs/remotes/test/master")); - cl_assert_equal_s(ref, "refs/heads/master"); -} - -void test_network_remote_remotes__transform_r(void) -{ - git_buf buf = GIT_BUF_INIT; - - cl_git_pass(git_refspec_transform_r(&buf, _refspec, "refs/heads/master")); - cl_assert_equal_s(git_buf_cstr(&buf), "refs/remotes/test/master"); - git_buf_free(&buf); + cl_git_pass(git_refspec_rtransform(&ref, _refspec, "refs/remotes/test/master")); + cl_assert_equal_s(ref.ptr, "refs/heads/master"); + git_buf_free(&ref); } void test_network_remote_remotes__missing_refspecs(void) diff --git a/tests/online/push.c b/tests/online/push.c index 33f174654..8efe21e0e 100644 --- a/tests/online/push.c +++ b/tests/online/push.c @@ -219,7 +219,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r if (!fetch_spec) continue; - cl_git_pass(git_refspec_transform_r(&ref_name, fetch_spec, expected_refs[i].name)); + cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name)); /* Find matching remote branch */ git_vector_foreach(&actual_refs, j, actual_ref) {