From f9cbf5a1bcd38810432e9ca16270e1f7ccc63605 Mon Sep 17 00:00:00 2001
From: Jason Song <i@wolfogre.com>
Date: Thu, 1 Dec 2022 19:56:04 +0800
Subject: [PATCH] Util type to parse ref name (#21969)

Provide a new type to make it easier to parse a ref name.

Actually, it's picked up from #21937, to make the origin PR lighter.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
---
 modules/git/ref.go | 63 +++++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 23 deletions(-)

diff --git a/modules/git/ref.go b/modules/git/ref.go
index cd8d268184..47cc04b7fb 100644
--- a/modules/git/ref.go
+++ b/modules/git/ref.go
@@ -55,40 +55,57 @@ func (ref *Reference) Commit() (*Commit, error) {
 
 // ShortName returns the short name of the reference
 func (ref *Reference) ShortName() string {
-	if ref == nil {
-		return ""
-	}
-	if strings.HasPrefix(ref.Name, BranchPrefix) {
-		return strings.TrimPrefix(ref.Name, BranchPrefix)
-	}
-	if strings.HasPrefix(ref.Name, TagPrefix) {
-		return strings.TrimPrefix(ref.Name, TagPrefix)
-	}
-	if strings.HasPrefix(ref.Name, RemotePrefix) {
-		return strings.TrimPrefix(ref.Name, RemotePrefix)
-	}
-	if strings.HasPrefix(ref.Name, PullPrefix) && strings.IndexByte(ref.Name[pullLen:], '/') > -1 {
-		return ref.Name[pullLen : strings.IndexByte(ref.Name[pullLen:], '/')+pullLen]
-	}
-
-	return ref.Name
+	return RefName(ref.Name).ShortName()
 }
 
 // RefGroup returns the group type of the reference
 func (ref *Reference) RefGroup() string {
-	if ref == nil {
-		return ""
+	return RefName(ref.Name).RefGroup()
+}
+
+// RefName represents a git reference name
+type RefName string
+
+func (ref RefName) IsBranch() bool {
+	return strings.HasPrefix(string(ref), BranchPrefix)
+}
+
+func (ref RefName) IsTag() bool {
+	return strings.HasPrefix(string(ref), TagPrefix)
+}
+
+// ShortName returns the short name of the reference name
+func (ref RefName) ShortName() string {
+	refName := string(ref)
+	if strings.HasPrefix(refName, BranchPrefix) {
+		return strings.TrimPrefix(refName, BranchPrefix)
 	}
-	if strings.HasPrefix(ref.Name, BranchPrefix) {
+	if strings.HasPrefix(refName, TagPrefix) {
+		return strings.TrimPrefix(refName, TagPrefix)
+	}
+	if strings.HasPrefix(refName, RemotePrefix) {
+		return strings.TrimPrefix(refName, RemotePrefix)
+	}
+	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 {
+		return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen]
+	}
+
+	return refName
+}
+
+// RefGroup returns the group type of the reference
+func (ref RefName) RefGroup() string {
+	refName := string(ref)
+	if strings.HasPrefix(refName, BranchPrefix) {
 		return "heads"
 	}
-	if strings.HasPrefix(ref.Name, TagPrefix) {
+	if strings.HasPrefix(refName, TagPrefix) {
 		return "tags"
 	}
-	if strings.HasPrefix(ref.Name, RemotePrefix) {
+	if strings.HasPrefix(refName, RemotePrefix) {
 		return "remotes"
 	}
-	if strings.HasPrefix(ref.Name, PullPrefix) && strings.IndexByte(ref.Name[pullLen:], '/') > -1 {
+	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 {
 		return "pull"
 	}
 	return ""