diff options
author | Carlos Martín Nieto <carlos@cmartin.tk> | 2011-06-23 15:41:29 +0200 |
---|---|---|
committer | Carlos Martín Nieto <carlos@cmartin.tk> | 2011-06-26 18:18:11 +0200 |
commit | 92cb6aa929f60eaea66359c8e3258de821a0a965 (patch) | |
tree | b6b943246b68f9073634e5ad3849b8875a6a09db /src/refspec.c | |
parent | fa9dcb7edeccef2e31e6926259bc46d9cefdd706 (diff) | |
download | libgit2-92cb6aa929f60eaea66359c8e3258de821a0a965.tar.gz |
Add git_refspec_transform
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Diffstat (limited to 'src/refspec.c')
-rw-r--r-- | src/refspec.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/refspec.c b/src/refspec.c index 38cbb05ee..8500e07ea 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -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; +} |