diff options
| author | 2026-03-26 09:19:01 +0000 | |
|---|---|---|
| committer | 2026-03-26 09:19:01 +0000 | |
| commit | 929b8cc620abca70b3444b09be5249f6c6cb7812 (patch) | |
| tree | 29b1edba8f597d09a2a51a6b2c901389cc40e242 /ref/name/validate.go | |
| parent | format: Move commitgraph and packfile here (diff) | |
| signature | No signature | |
ref/name: Rename from ref/refname
Diffstat (limited to 'ref/name/validate.go')
| -rw-r--r-- | ref/name/validate.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/ref/name/validate.go b/ref/name/validate.go new file mode 100644 index 00000000..1b8ad396 --- /dev/null +++ b/ref/name/validate.go @@ -0,0 +1,65 @@ +package refname + +import "strings" + +// Validate checks whether name is one valid Git refname. +func Validate(name string, options Options) error { + return validate(name, options.flags()) +} + +func validate(name string, flags int) error { + return checkOrSanitizeRefname(name, flags, nil) +} + +func checkOrSanitizeRefname(name string, flags int, sanitized *strings.Builder) error { + componentCount := 0 + remaining := name + + if name == "@" { + if sanitized == nil { + return &NameError{Name: name, Reason: "single @ is not allowed"} + } + + sanitized.WriteByte('-') + } + + for { + if sanitized != nil && sanitized.Len() > 0 { + sanitized.WriteByte('/') + } + + componentLen, err := checkRefnameComponent(remaining, &flags, sanitized, name) + switch { + case sanitized != nil && componentLen == 0: + case componentLen <= 0: + if err != nil { + return err + } + + return &NameError{Name: name, Reason: "component has zero length"} + case err != nil: + return err + } + + componentCount++ + + if componentLen == len(remaining) { + break + } + + remaining = remaining[componentLen+1:] + } + + componentLen := len(remaining) + if componentLen > 0 && remaining[componentLen-1] == '.' { + if sanitized == nil { + return &NameError{Name: name, Reason: "name ends with '.'"} + } + } + + if flags&refnameAllowOneLevel == 0 && componentCount < 2 { + return &NameError{Name: name, Reason: "one-level refname is not allowed"} + } + + return nil +} |
