code.gitea.io/gitea@v1.19.3/modules/git/ref.go (about)

     1  // Copyright 2018 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package git
     5  
     6  import (
     7  	"regexp"
     8  	"strings"
     9  )
    10  
    11  const (
    12  	// RemotePrefix is the base directory of the remotes information of git.
    13  	RemotePrefix = "refs/remotes/"
    14  	// PullPrefix is the base directory of the pull information of git.
    15  	PullPrefix = "refs/pull/"
    16  
    17  	pullLen = len(PullPrefix)
    18  )
    19  
    20  // refNamePatternInvalid is regular expression with unallowed characters in git reference name
    21  // They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere.
    22  // They cannot have question-mark ?, asterisk *, or open bracket [ anywhere
    23  var refNamePatternInvalid = regexp.MustCompile(
    24  	`[\000-\037\177 \\~^:?*[]|` + // No absolutely invalid characters
    25  		`(?:^[/.])|` + // Not HasPrefix("/") or "."
    26  		`(?:/\.)|` + // no "/."
    27  		`(?:\.lock$)|(?:\.lock/)|` + // No ".lock/"" or ".lock" at the end
    28  		`(?:\.\.)|` + // no ".." anywhere
    29  		`(?://)|` + // no "//" anywhere
    30  		`(?:@{)|` + // no "@{"
    31  		`(?:[/.]$)|` + // no terminal '/' or '.'
    32  		`(?:^@$)`) // Not "@"
    33  
    34  // IsValidRefPattern ensures that the provided string could be a valid reference
    35  func IsValidRefPattern(name string) bool {
    36  	return !refNamePatternInvalid.MatchString(name)
    37  }
    38  
    39  func SanitizeRefPattern(name string) string {
    40  	return refNamePatternInvalid.ReplaceAllString(name, "_")
    41  }
    42  
    43  // Reference represents a Git ref.
    44  type Reference struct {
    45  	Name   string
    46  	repo   *Repository
    47  	Object SHA1 // The id of this commit object
    48  	Type   string
    49  }
    50  
    51  // Commit return the commit of the reference
    52  func (ref *Reference) Commit() (*Commit, error) {
    53  	return ref.repo.getCommit(ref.Object)
    54  }
    55  
    56  // ShortName returns the short name of the reference
    57  func (ref *Reference) ShortName() string {
    58  	return RefName(ref.Name).ShortName()
    59  }
    60  
    61  // RefGroup returns the group type of the reference
    62  func (ref *Reference) RefGroup() string {
    63  	return RefName(ref.Name).RefGroup()
    64  }
    65  
    66  // RefName represents a git reference name
    67  type RefName string
    68  
    69  func (ref RefName) IsBranch() bool {
    70  	return strings.HasPrefix(string(ref), BranchPrefix)
    71  }
    72  
    73  func (ref RefName) IsTag() bool {
    74  	return strings.HasPrefix(string(ref), TagPrefix)
    75  }
    76  
    77  // ShortName returns the short name of the reference name
    78  func (ref RefName) ShortName() string {
    79  	refName := string(ref)
    80  	if strings.HasPrefix(refName, BranchPrefix) {
    81  		return strings.TrimPrefix(refName, BranchPrefix)
    82  	}
    83  	if strings.HasPrefix(refName, TagPrefix) {
    84  		return strings.TrimPrefix(refName, TagPrefix)
    85  	}
    86  	if strings.HasPrefix(refName, RemotePrefix) {
    87  		return strings.TrimPrefix(refName, RemotePrefix)
    88  	}
    89  	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 {
    90  		return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen]
    91  	}
    92  
    93  	return refName
    94  }
    95  
    96  // RefGroup returns the group type of the reference
    97  func (ref RefName) RefGroup() string {
    98  	refName := string(ref)
    99  	if strings.HasPrefix(refName, BranchPrefix) {
   100  		return "heads"
   101  	}
   102  	if strings.HasPrefix(refName, TagPrefix) {
   103  		return "tags"
   104  	}
   105  	if strings.HasPrefix(refName, RemotePrefix) {
   106  		return "remotes"
   107  	}
   108  	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 {
   109  		return "pull"
   110  	}
   111  	return ""
   112  }