Commit 92cb6aa9 by Carlos Martín Nieto

Add git_refspec_transform

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
parent fa9dcb7e
......@@ -29,4 +29,14 @@ const char *git_refspec_dst(const git_refspec *refspec);
*/
int git_refspec_src_match(const git_refspec *refspec, const char *refname);
/**
* Transform a reference to its target following the refspec's rules
*
* @param out where to store the target name
* @param in the source reference
* @param spec the refspec
* @param len the length of the out buffer
* @preturn GIT_SUCCESS, GIT_ESHORTBUFFER or another error
*/
int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name);
#endif
......@@ -23,6 +23,8 @@
* Boston, MA 02110-1301, USA.
*/
#include "git2/errors.h"
#include "common.h"
#include "refspec.h"
#include "util.h"
......@@ -70,3 +72,37 @@ int git_refspec_src_match(const git_refspec *refspec, const char *refname)
{
return git__fnmatch(refspec->src, refname, 0);
}
int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name)
{
size_t baselen, namelen;
baselen = strlen(spec->dst);
if (outlen <= baselen)
return git__throw(GIT_EINVALIDREFNAME, "Reference name too long");
/*
* No '*' at the end means that it's mapped to one specific local
* branch, so no actual transformation is needed.
*/
if (spec->dst[baselen - 1] != '*') {
memcpy(out, spec->dst, baselen + 1); /* include '\0' */
return GIT_SUCCESS;
}
/* There's a '*' at the end, so remove its length */
baselen--;
/* skip the prefix, -1 is for the '*' */
name += strlen(spec->src) - 1;
namelen = strlen(name);
if (outlen <= baselen + namelen)
return git__throw(GIT_EINVALIDREFNAME, "Reference name too long");
memcpy(out, spec->dst, baselen);
memcpy(out + baselen, name, namelen + 1);
return GIT_SUCCESS;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment