Skip to content

Commit 4f57b9b

Browse files
github-actions[bot]Segev Finer
andauthored
Add ReferenceNormalizeName (#681) (#686)
(cherry picked from commit 2bd574b) Co-authored-by: Segev Finer <[email protected]>
1 parent c53a41c commit 4f57b9b

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

reference.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,42 @@ func ReferenceIsValidName(name string) bool {
488488
}
489489
return false
490490
}
491+
492+
const (
493+
// This should match GIT_REFNAME_MAX in src/refs.h
494+
_refnameMaxLength = C.size_t(1024)
495+
)
496+
497+
type ReferenceFormat uint
498+
499+
const (
500+
ReferenceFormatNormal ReferenceFormat = C.GIT_REFERENCE_FORMAT_NORMAL
501+
ReferenceFormatAllowOnelevel ReferenceFormat = C.GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL
502+
ReferenceFormatRefspecPattern ReferenceFormat = C.GIT_REFERENCE_FORMAT_REFSPEC_PATTERN
503+
ReferenceFormatRefspecShorthand ReferenceFormat = C.GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND
504+
)
505+
506+
// ReferenceNormalizeName normalizes the reference name and checks validity.
507+
//
508+
// This will normalize the reference name by removing any leading slash '/'
509+
// characters and collapsing runs of adjacent slashes between name components
510+
// into a single slash.
511+
//
512+
// See git_reference_symbolic_create() for rules about valid names.
513+
func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) {
514+
cname := C.CString(name)
515+
defer C.free(unsafe.Pointer(cname))
516+
517+
buf := (*C.char)(C.malloc(_refnameMaxLength))
518+
defer C.free(unsafe.Pointer(buf))
519+
520+
runtime.LockOSThread()
521+
defer runtime.UnlockOSThread()
522+
523+
ecode := C.git_reference_normalize_name(buf, _refnameMaxLength, cname, C.uint(flags))
524+
if ecode < 0 {
525+
return "", MakeGitError(ecode)
526+
}
527+
528+
return C.GoString(buf), nil
529+
}

reference_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,29 @@ func TestReferenceIsValidName(t *testing.T) {
224224
}
225225
}
226226

227+
func TestReferenceNormalizeName(t *testing.T) {
228+
t.Parallel()
229+
230+
ref, err := ReferenceNormalizeName("refs/heads//master", ReferenceFormatNormal)
231+
checkFatal(t, err)
232+
233+
if ref != "refs/heads/master" {
234+
t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "refs/heads//master", ref, "refs/heads/master")
235+
}
236+
237+
ref, err = ReferenceNormalizeName("master", ReferenceFormatAllowOnelevel|ReferenceFormatRefspecShorthand)
238+
checkFatal(t, err)
239+
240+
if ref != "master" {
241+
t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "master", ref, "master")
242+
}
243+
244+
ref, err = ReferenceNormalizeName("foo^", ReferenceFormatNormal)
245+
if !IsErrorCode(err, ErrInvalidSpec) {
246+
t.Errorf("foo^ should be invalid")
247+
}
248+
}
249+
227250
func compareStringList(t *testing.T, expected, actual []string) {
228251
for i, v := range expected {
229252
if actual[i] != v {

0 commit comments

Comments
 (0)