diff --git a/reference.go b/reference.go index 452de46..140082f 100644 --- a/reference.go +++ b/reference.go @@ -430,3 +430,22 @@ func (v *ReferenceIterator) Free() { runtime.SetFinalizer(v, nil) C.git_reference_iterator_free(v.ptr) } + +// ReferenceIsValidName ensures the reference name is well-formed. +// +// Valid reference names must follow one of two patterns: +// +// 1. Top-level names must contain only capital letters and underscores, +// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). +// +// 2. Names prefixed with "refs/" can be almost anything. You must avoid +// the characters '~', '^', ':', ' \ ', '?', '[', and '*', and the sequences +// ".." and " @ {" which have special meaning to revparse. +func ReferenceIsValidName(name string) bool { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + if C.git_reference_is_valid_name(cname) == 1 { + return true + } + return false +} diff --git a/reference_test.go b/reference_test.go index b69a274..761daf8 100644 --- a/reference_test.go +++ b/reference_test.go @@ -208,6 +208,16 @@ func TestIsNote(t *testing.T) { t.Fatalf("%s should not be a note", ref.Name()) } } + +func TestReferenceIsValidName(t *testing.T) { + if !ReferenceIsValidName("HEAD") { + t.Errorf("HEAD should be a valid reference name") + } + if ReferenceIsValidName("HEAD1") { + t.Errorf("HEAD1 should not be a valid reference name") + } +} + func compareStringList(t *testing.T, expected, actual []string) { for i, v := range expected { if actual[i] != v {