vendor/libgit2/src/refspec.c in rugged-0.27.10 vs vendor/libgit2/src/refspec.c in rugged-0.27.10.1
- old
+ new
@@ -7,18 +7,18 @@
#include "refspec.h"
#include "git2/errors.h"
-#include "refs.h"
#include "util.h"
+#include "posix.h"
+#include "refs.h"
#include "vector.h"
-#include "wildmatch.h"
int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
{
- /* Ported from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/remote.c#L518-636 */
+ // Ported from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/remote.c#L518-636
size_t llen;
int is_glob = 0;
const char *lhs, *rhs;
int flags;
@@ -41,15 +41,15 @@
* for matching refs.
*/
if (!is_fetch && rhs == lhs && rhs[1] == '\0') {
refspec->matching = 1;
refspec->string = git__strdup(input);
- GIT_ERROR_CHECK_ALLOC(refspec->string);
+ GITERR_CHECK_ALLOC(refspec->string);
refspec->src = git__strdup("");
- GIT_ERROR_CHECK_ALLOC(refspec->src);
+ GITERR_CHECK_ALLOC(refspec->src);
refspec->dst = git__strdup("");
- GIT_ERROR_CHECK_ALLOC(refspec->dst);
+ GITERR_CHECK_ALLOC(refspec->dst);
return 0;
}
if (rhs) {
size_t rlen = strlen(++rhs);
@@ -67,13 +67,12 @@
} else if (rhs && is_glob)
goto invalid;
refspec->pattern = is_glob;
refspec->src = git__strndup(lhs, llen);
- flags = GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL |
- GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND |
- (is_glob ? GIT_REFERENCE_FORMAT_REFSPEC_PATTERN : 0);
+ flags = GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND
+ | (is_glob ? GIT_REF_FORMAT_REFSPEC_PATTERN : 0);
if (is_fetch) {
/*
* LHS
* - empty is allowed; it means HEAD.
@@ -130,28 +129,28 @@
}
/* if the RHS is empty, then it's a copy of the LHS */
if (!refspec->dst) {
refspec->dst = git__strdup(refspec->src);
- GIT_ERROR_CHECK_ALLOC(refspec->dst);
+ GITERR_CHECK_ALLOC(refspec->dst);
}
}
refspec->string = git__strdup(input);
- GIT_ERROR_CHECK_ALLOC(refspec->string);
+ GITERR_CHECK_ALLOC(refspec->string);
return 0;
invalid:
- git_error_set(
- GIT_ERROR_INVALID,
+ giterr_set(
+ GITERR_INVALID,
"'%s' is not a valid refspec.", input);
- git_refspec__dispose(refspec);
+ git_refspec__free(refspec);
return -1;
}
-void git_refspec__dispose(git_refspec *refspec)
+void git_refspec__free(git_refspec *refspec)
{
if (refspec == NULL)
return;
git__free(refspec->src);
@@ -159,35 +158,10 @@
git__free(refspec->string);
memset(refspec, 0x0, sizeof(git_refspec));
}
-int git_refspec_parse(git_refspec **out_refspec, const char *input, int is_fetch)
-{
- git_refspec *refspec;
- assert(out_refspec && input);
-
- *out_refspec = NULL;
-
- refspec = git__malloc(sizeof(git_refspec));
- GIT_ERROR_CHECK_ALLOC(refspec);
-
- if (git_refspec__parse(refspec, input, !!is_fetch) != 0) {
- git__free(refspec);
- return -1;
- }
-
- *out_refspec = refspec;
- return 0;
-}
-
-void git_refspec_free(git_refspec *refspec)
-{
- git_refspec__dispose(refspec);
- git__free(refspec);
-}
-
const char *git_refspec_src(const git_refspec *refspec)
{
return refspec == NULL ? NULL : refspec->src;
}
@@ -211,25 +185,26 @@
int git_refspec_src_matches(const git_refspec *refspec, const char *refname)
{
if (refspec == NULL || refspec->src == NULL)
return false;
- return (wildmatch(refspec->src, refname, 0) == 0);
+ return (p_fnmatch(refspec->src, refname, 0) == 0);
}
int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
{
if (refspec == NULL || refspec->dst == NULL)
return false;
- return (wildmatch(refspec->dst, refname, 0) == 0);
+ return (p_fnmatch(refspec->dst, refname, 0) == 0);
}
static int refspec_transform(
git_buf *out, const char *from, const char *to, const char *name)
{
const char *from_star, *to_star;
+ const char *name_slash, *from_slash;
size_t replacement_len, star_offset;
git_buf_sanitize(out);
git_buf_clear(out);
@@ -248,15 +223,21 @@
star_offset = from_star - from;
/* the first half is copied over */
git_buf_put(out, to, to_star - to);
- /*
- * Copy over the name, but exclude the trailing part in "from" starting
- * after the glob
- */
- replacement_len = strlen(name + star_offset) - strlen(from_star + 1);
+ /* then we copy over the replacement, from the star's offset to the next slash in 'name' */
+ name_slash = strchr(name + star_offset, '/');
+ if (!name_slash)
+ name_slash = strrchr(name, '\0');
+
+ /* if there is no slash after the star in 'from', we want to copy everything over */
+ from_slash = strchr(from + star_offset, '/');
+ if (!from_slash)
+ name_slash = strrchr(name, '\0');
+
+ replacement_len = (name_slash - name) - star_offset;
git_buf_put(out, name + star_offset, replacement_len);
return git_buf_puts(out, to_star + 1);
}
@@ -264,27 +245,27 @@
{
assert(out && spec && name);
git_buf_sanitize(out);
if (!git_refspec_src_matches(spec, name)) {
- git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the source", name);
+ giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name);
return -1;
}
if (!spec->pattern)
- return git_buf_puts(out, spec->dst ? spec->dst : "");
+ return git_buf_puts(out, spec->dst);
return refspec_transform(out, spec->src, spec->dst, name);
}
int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
{
assert(out && spec && name);
git_buf_sanitize(out);
if (!git_refspec_dst_matches(spec, name)) {
- git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the destination", name);
+ giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name);
return -1;
}
if (!spec->pattern)
return git_buf_puts(out, spec->src);
@@ -333,11 +314,11 @@
};
assert(out && spec && refs);
cur = git__calloc(1, sizeof(git_refspec));
- GIT_ERROR_CHECK_ALLOC(cur);
+ GITERR_CHECK_ALLOC(cur);
cur->force = spec->force;
cur->push = spec->push;
cur->pattern = spec->pattern;
cur->matching = spec->matching;
@@ -346,11 +327,11 @@
/* shorthand on the lhs */
if (git__prefixcmp(spec->src, GIT_REFS_DIR)) {
for (j = 0; formatters[j]; j++) {
git_buf_clear(&buf);
git_buf_printf(&buf, formatters[j], spec->src);
- GIT_ERROR_CHECK_ALLOC_BUF(&buf);
+ GITERR_CHECK_ALLOC_BUF(&buf);
key.name = (char *) git_buf_cstr(&buf);
if (!git_vector_search(&pos, refs, &key)) {
/* we found something to match the shorthand, set src to that */
cur->src = git_buf_detach(&buf);
@@ -359,11 +340,11 @@
}
/* No shorthands found, copy over the name */
if (cur->src == NULL && spec->src != NULL) {
cur->src = git__strdup(spec->src);
- GIT_ERROR_CHECK_ALLOC(cur->src);
+ GITERR_CHECK_ALLOC(cur->src);
}
if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) {
/* if it starts with "remotes" then we just prepend "refs/" */
if (!git__prefixcmp(spec->dst, "remotes/")) {
@@ -371,19 +352,19 @@
} else {
git_buf_puts(&buf, GIT_REFS_HEADS_DIR);
}
git_buf_puts(&buf, spec->dst);
- GIT_ERROR_CHECK_ALLOC_BUF(&buf);
+ GITERR_CHECK_ALLOC_BUF(&buf);
cur->dst = git_buf_detach(&buf);
}
- git_buf_dispose(&buf);
+ git_buf_free(&buf);
if (cur->dst == NULL && spec->dst != NULL) {
cur->dst = git__strdup(spec->dst);
- GIT_ERROR_CHECK_ALLOC(cur->dst);
+ GITERR_CHECK_ALLOC(cur->dst);
}
return git_vector_insert(out, cur);
}