Add git_branch_name_is_valid Signed-off-by: Sven Strickroth <email@cs-ware.de>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
diff --git a/include/git2/branch.h b/include/git2/branch.h
index ba62359..0c0cc7f 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -304,6 +304,18 @@ GIT_EXTERN(int) git_branch_remote_name(
*/
GIT_EXTERN(int) git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname);
+/**
+ * Determine whether a branch name is valid, meaning that (when prefixed
+ * with `refs/heads/`) that it is a valid reference name, and that any
+ * additional branch name restrictions are imposed (eg, it cannot start
+ * with a `-`).
+ *
+ * @param valid output pointer to set with validity of given branch name
+ * @param name a branch name to test
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_branch_name_is_valid(int *valid, const char *name);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/branch.c b/src/branch.c
index 715f6cf..000a63a 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -723,3 +723,32 @@ int git_branch_is_head(
return is_same;
}
+
+int git_branch_name_is_valid(int *valid, const char *name)
+{
+ git_buf ref_name = GIT_BUF_INIT;
+ int error = 0;
+
+ GIT_ASSERT(valid);
+
+ *valid = 0;
+
+ /*
+ * Discourage branch name starting with dash,
+ * https://github.com/git/git/commit/6348624010888b
+ * and discourage HEAD as branch name,
+ * https://github.com/git/git/commit/a625b092cc5994
+ */
+ if (!name || name[0] == '-' || !git__strcmp(name, "HEAD"))
+ goto done;
+
+ if ((error = git_buf_puts(&ref_name, GIT_REFS_HEADS_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;
+}
diff --git a/tests/refs/branches/name.c b/tests/refs/branches/name.c
index 176f836..290916e 100644
--- a/tests/refs/branches/name.c
+++ b/tests/refs/branches/name.c
@@ -43,3 +43,20 @@ void test_refs_branches_name__error_when_ref_is_no_branch(void)
cl_git_pass(git_reference_lookup(&ref,repo,"refs/notes/fanout"));
cl_git_fail(git_branch_name(&name,ref));
}
+
+static int name_is_valid(const char *name)
+{
+ int valid;
+ cl_git_pass(git_branch_name_is_valid(&valid, name));
+ return valid;
+}
+
+void test_refs_branches_is_name_valid(void)
+{
+ cl_assert_equal_i(true, name_is_valid("master"));
+ cl_assert_equal_i(true, name_is_valid("test/master"));
+
+ cl_assert_equal_i(false, name_is_valid(""));
+ cl_assert_equal_i(false, name_is_valid("HEAD"));
+ cl_assert_equal_i(false, name_is_valid("-dash"));
+}