vendor/libgit2/src/refspec.c in rugged-0.27.9 vs vendor/libgit2/src/refspec.c in rugged-0.27.10
- old
+ new
@@ -7,18 +7,18 @@
#include "refspec.h"
#include "git2/errors.h"
-#include "util.h"
-#include "posix.h"
#include "refs.h"
+#include "util.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);
- GITERR_CHECK_ALLOC(refspec->string);
+ GIT_ERROR_CHECK_ALLOC(refspec->string);
refspec->src = git__strdup("");
- GITERR_CHECK_ALLOC(refspec->src);
+ GIT_ERROR_CHECK_ALLOC(refspec->src);
refspec->dst = git__strdup("");
- GITERR_CHECK_ALLOC(refspec->dst);
+ GIT_ERROR_CHECK_ALLOC(refspec->dst);
return 0;
}
if (rhs) {
size_t rlen = strlen(++rhs);
@@ -67,12 +67,13 @@
} else if (rhs && is_glob)
goto invalid;
refspec->pattern = is_glob;
refspec->src = git__strndup(lhs, llen);
- flags = GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND
- | (is_glob ? GIT_REF_FORMAT_REFSPEC_PATTERN : 0);
+ flags = GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL |
+ GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND |
+ (is_glob ? GIT_REFERENCE_FORMAT_REFSPEC_PATTERN : 0);
if (is_fetch) {
/*
* LHS
* - empty is allowed; it means HEAD.
@@ -129,28 +130,28 @@
}
/* if the RHS is empty, then it's a copy of the LHS */
if (!refspec->dst) {
refspec->dst = git__strdup(refspec->src);
- GITERR_CHECK_ALLOC(refspec->dst);
+ GIT_ERROR_CHECK_ALLOC(refspec->dst);
}
}
refspec->string = git__strdup(input);
- GITERR_CHECK_ALLOC(refspec->string);
+ GIT_ERROR_CHECK_ALLOC(refspec->string);
return 0;
invalid:
- giterr_set(
- GITERR_INVALID,
+ git_error_set(
+ GIT_ERROR_INVALID,
"'%s' is not a valid refspec.", input);
- git_refspec__free(refspec);
+ git_refspec__dispose(refspec);
return -1;
}
-void git_refspec__free(git_refspec *refspec)
+void git_refspec__dispose(git_refspec *refspec)
{
if (refspec == NULL)
return;
git__free(refspec->src);
@@ -158,10 +159,35 @@
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;
}
@@ -185,26 +211,25 @@
int git_refspec_src_matches(const git_refspec *refspec, const char *refname)
{
if (refspec == NULL || refspec->src == NULL)
return false;
- return (p_fnmatch(refspec->src, refname, 0) == 0);
+ return (wildmatch(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 (p_fnmatch(refspec->dst, refname, 0) == 0);
+ return (wildmatch(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);
@@ -223,21 +248,15 @@
star_offset = from_star - from;
/* the first half is copied over */
git_buf_put(out, to, to_star - to);
- /* 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;
+ /*
+ * 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);
git_buf_put(out, name + star_offset, replacement_len);
return git_buf_puts(out, to_star + 1);
}
@@ -245,27 +264,27 @@
{
assert(out && spec && name);
git_buf_sanitize(out);
if (!git_refspec_src_matches(spec, name)) {
- giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name);
+ git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the source", name);
return -1;
}
if (!spec->pattern)
- return git_buf_puts(out, spec->dst);
+ return git_buf_puts(out, spec->dst ? 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)) {
- giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name);
+ git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the destination", name);
return -1;
}
if (!spec->pattern)
return git_buf_puts(out, spec->src);
@@ -314,11 +333,11 @@
};
assert(out && spec && refs);
cur = git__calloc(1, sizeof(git_refspec));
- GITERR_CHECK_ALLOC(cur);
+ GIT_ERROR_CHECK_ALLOC(cur);
cur->force = spec->force;
cur->push = spec->push;
cur->pattern = spec->pattern;
cur->matching = spec->matching;
@@ -327,11 +346,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);
- GITERR_CHECK_ALLOC_BUF(&buf);
+ GIT_ERROR_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);
@@ -340,11 +359,11 @@
}
/* No shorthands found, copy over the name */
if (cur->src == NULL && spec->src != NULL) {
cur->src = git__strdup(spec->src);
- GITERR_CHECK_ALLOC(cur->src);
+ GIT_ERROR_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/")) {
@@ -352,19 +371,19 @@
} else {
git_buf_puts(&buf, GIT_REFS_HEADS_DIR);
}
git_buf_puts(&buf, spec->dst);
- GITERR_CHECK_ALLOC_BUF(&buf);
+ GIT_ERROR_CHECK_ALLOC_BUF(&buf);
cur->dst = git_buf_detach(&buf);
}
- git_buf_free(&buf);
+ git_buf_dispose(&buf);
if (cur->dst == NULL && spec->dst != NULL) {
cur->dst = git__strdup(spec->dst);
- GITERR_CHECK_ALLOC(cur->dst);
+ GIT_ERROR_CHECK_ALLOC(cur->dst);
}
return git_vector_insert(out, cur);
}