summaryrefslogtreecommitdiff
path: root/src/refspec.c
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlos@cmartin.tk>2011-06-23 15:41:29 +0200
committerCarlos Martín Nieto <carlos@cmartin.tk>2011-06-26 18:18:11 +0200
commit92cb6aa929f60eaea66359c8e3258de821a0a965 (patch)
treeb6b943246b68f9073634e5ad3849b8875a6a09db /src/refspec.c
parentfa9dcb7edeccef2e31e6926259bc46d9cefdd706 (diff)
downloadlibgit2-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.c36
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;
+}