Add ReferenceNormalizeName (#681) #688

Merged
github-actions[bot] merged 2 commits from cherry-pick-362582535-release-0.27 into release-0.27 2020-11-13 21:01:24 -06:00
2 changed files with 62 additions and 0 deletions

View File

@ -488,3 +488,42 @@ func ReferenceIsValidName(name string) bool {
}
return false
}
const (
// This should match GIT_REFNAME_MAX in src/refs.h
_refnameMaxLength = C.size_t(1024)
)
type ReferenceFormat uint
const (
ReferenceFormatNormal ReferenceFormat = C.GIT_REF_FORMAT_NORMAL
ReferenceFormatAllowOnelevel ReferenceFormat = C.GIT_REF_FORMAT_ALLOW_ONELEVEL
ReferenceFormatRefspecPattern ReferenceFormat = C.GIT_REF_FORMAT_REFSPEC_PATTERN
ReferenceFormatRefspecShorthand ReferenceFormat = C.GIT_REF_FORMAT_REFSPEC_SHORTHAND
)
// ReferenceNormalizeName normalizes the reference name and checks validity.
//
// This will normalize the reference name by removing any leading slash '/'
// characters and collapsing runs of adjacent slashes between name components
// into a single slash.
//
// See git_reference_symbolic_create() for rules about valid names.
func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
buf := (*C.char)(C.malloc(_refnameMaxLength))
defer C.free(unsafe.Pointer(buf))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_normalize_name(buf, _refnameMaxLength, cname, C.uint(flags))
if ecode < 0 {
return "", MakeGitError(ecode)
}
return C.GoString(buf), nil
}

View File

@ -224,6 +224,29 @@ func TestReferenceIsValidName(t *testing.T) {
}
}
func TestReferenceNormalizeName(t *testing.T) {
t.Parallel()
ref, err := ReferenceNormalizeName("refs/heads//master", ReferenceFormatNormal)
checkFatal(t, err)
if ref != "refs/heads/master" {
t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "refs/heads//master", ref, "refs/heads/master")
}
ref, err = ReferenceNormalizeName("master", ReferenceFormatAllowOnelevel|ReferenceFormatRefspecShorthand)
checkFatal(t, err)
if ref != "master" {
t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "master", ref, "master")
}
ref, err = ReferenceNormalizeName("foo^", ReferenceFormatNormal)
if !IsErrorCode(err, ErrInvalidSpec) {
t.Errorf("foo^ should be invalid")
}
}
func compareStringList(t *testing.T, expected, actual []string) {
for i, v := range expected {
if actual[i] != v {