summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Strickroth <email@cs-ware.de>2020-09-09 10:48:00 +0200
committerEdward Thomson <ethomson@edwardthomson.com>2020-10-25 16:33:28 +0000
commit0caa4655ebdb7bf028df970d0651378d121fab3e (patch)
tree393ed8d70cd7e6d933459990e0679285c95f4df3
parentfe11160c724853fe8469a9788c5992420e4638de (diff)
downloadlibgit2-0caa4655ebdb7bf028df970d0651378d121fab3e.tar.gz
Add git_tag_name_is_valid
Signed-off-by: Sven Strickroth <email@cs-ware.de>
-rw-r--r--include/git2/tag.h12
-rw-r--r--src/tag.c25
-rw-r--r--tests/refs/tags/name.c17
3 files changed, 54 insertions, 0 deletions
diff --git a/include/git2/tag.h b/include/git2/tag.h
index 4e5fe1db1..a3921369d 100644
--- a/include/git2/tag.h
+++ b/include/git2/tag.h
@@ -365,6 +365,18 @@ GIT_EXTERN(int) git_tag_peel(
*/
GIT_EXTERN(int) git_tag_dup(git_tag **out, git_tag *source);
+/**
+ * Determine whether a tag name is valid, meaning that (when prefixed
+ * with `refs/tags/`) that it is a valid reference name, and that any
+ * additional tag name restrictions are imposed (eg, it cannot start
+ * with a `-`).
+ *
+ * @param valid output pointer to set with validity of given tag name
+ * @param name a tag name to test
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_tag_name_is_valid(int *valid, const char *name);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/tag.c b/src/tag.c
index 037dc6664..8a4d6eec8 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -522,6 +522,31 @@ int git_tag_peel(git_object **tag_target, const git_tag *tag)
return git_object_peel(tag_target, (const git_object *)tag, GIT_OBJECT_ANY);
}
+int git_tag_name_is_valid(int *valid, const char *name)
+{
+ git_buf ref_name = GIT_BUF_INIT;
+ int error = 0;
+
+ GIT_ASSERT(valid);
+
+ /*
+ * Discourage tag name starting with dash,
+ * https://github.com/git/git/commit/4f0accd638b8d2
+ */
+ if (!name || name[0] == '-')
+ goto done;
+
+ if ((error = git_buf_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 ||
+ (error = git_buf_puts(&ref_name, name)) < 0)
+ goto done;
+
+ error = git_reference_name_is_valid(valid, ref_name.ptr);
+
+done:
+ git_buf_dispose(&ref_name);
+ return error;
+}
+
/* Deprecated Functions */
#ifndef GIT_DEPRECATE_HARD
diff --git a/tests/refs/tags/name.c b/tests/refs/tags/name.c
new file mode 100644
index 000000000..0ca5df7d6
--- /dev/null
+++ b/tests/refs/tags/name.c
@@ -0,0 +1,17 @@
+#include "clar_libgit2.h"
+
+static int name_is_valid(const char *name)
+{
+ int valid;
+ cl_git_pass(git_tag_name_is_valid(&valid, name));
+ return valid;
+}
+
+void test_refs_tags_is_name_valid(void)
+{
+ cl_assert_equal_i(true, name_is_valid("sometag"));
+ cl_assert_equal_i(true, name_is_valid("test/sometag"));
+
+ cl_assert_equal_i(false, name_is_valid(""));
+ cl_assert_equal_i(false, name_is_valid("-dash"));
+}