gitech

Форк
0
/
ref.go 
214 строк · 5.6 Кб
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
	"code.gitea.io/gitea/modules/util"
11
)
12

13
const (
14
	// RemotePrefix is the base directory of the remotes information of git.
15
	RemotePrefix = "refs/remotes/"
16
	// PullPrefix is the base directory of the pull information of git.
17
	PullPrefix = "refs/pull/"
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 ObjectID // 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
// ForPrefix special ref to create a pull request: refs/for/<target-branch>/<topic-branch>
67
// or refs/for/<targe-branch> -o topic='<topic-branch>'
68
const ForPrefix = "refs/for/"
69

70
// TODO: /refs/for-review for suggest change interface
71

72
// RefName represents a full git reference name
73
type RefName string
74

75
func RefNameFromBranch(shortName string) RefName {
76
	return RefName(BranchPrefix + shortName)
77
}
78

79
func RefNameFromTag(shortName string) RefName {
80
	return RefName(TagPrefix + shortName)
81
}
82

83
func (ref RefName) String() string {
84
	return string(ref)
85
}
86

87
func (ref RefName) IsBranch() bool {
88
	return strings.HasPrefix(string(ref), BranchPrefix)
89
}
90

91
func (ref RefName) IsTag() bool {
92
	return strings.HasPrefix(string(ref), TagPrefix)
93
}
94

95
func (ref RefName) IsRemote() bool {
96
	return strings.HasPrefix(string(ref), RemotePrefix)
97
}
98

99
func (ref RefName) IsPull() bool {
100
	return strings.HasPrefix(string(ref), PullPrefix) && strings.IndexByte(string(ref)[len(PullPrefix):], '/') > -1
101
}
102

103
func (ref RefName) IsFor() bool {
104
	return strings.HasPrefix(string(ref), ForPrefix)
105
}
106

107
func (ref RefName) nameWithoutPrefix(prefix string) string {
108
	if strings.HasPrefix(string(ref), prefix) {
109
		return strings.TrimPrefix(string(ref), prefix)
110
	}
111
	return ""
112
}
113

114
// TagName returns simple tag name if it's an operation to a tag
115
func (ref RefName) TagName() string {
116
	return ref.nameWithoutPrefix(TagPrefix)
117
}
118

119
// BranchName returns simple branch name if it's an operation to branch
120
func (ref RefName) BranchName() string {
121
	return ref.nameWithoutPrefix(BranchPrefix)
122
}
123

124
// PullName returns the pull request name part of refs like refs/pull/<pull_name>/head
125
func (ref RefName) PullName() string {
126
	refName := string(ref)
127
	lastIdx := strings.LastIndexByte(refName[len(PullPrefix):], '/')
128
	if strings.HasPrefix(refName, PullPrefix) && lastIdx > -1 {
129
		return refName[len(PullPrefix) : lastIdx+len(PullPrefix)]
130
	}
131
	return ""
132
}
133

134
// ForBranchName returns the branch name part of refs like refs/for/<branch_name>
135
func (ref RefName) ForBranchName() string {
136
	return ref.nameWithoutPrefix(ForPrefix)
137
}
138

139
func (ref RefName) RemoteName() string {
140
	return ref.nameWithoutPrefix(RemotePrefix)
141
}
142

143
// ShortName returns the short name of the reference name
144
func (ref RefName) ShortName() string {
145
	refName := string(ref)
146
	if ref.IsBranch() {
147
		return ref.BranchName()
148
	}
149
	if ref.IsTag() {
150
		return ref.TagName()
151
	}
152
	if ref.IsRemote() {
153
		return ref.RemoteName()
154
	}
155
	if ref.IsPull() {
156
		return ref.PullName()
157
	}
158
	if ref.IsFor() {
159
		return ref.ForBranchName()
160
	}
161

162
	return refName
163
}
164

165
// RefGroup returns the group type of the reference
166
// Using the name of the directory under .git/refs
167
func (ref RefName) RefGroup() string {
168
	if ref.IsBranch() {
169
		return "heads"
170
	}
171
	if ref.IsTag() {
172
		return "tags"
173
	}
174
	if ref.IsRemote() {
175
		return "remotes"
176
	}
177
	if ref.IsPull() {
178
		return "pull"
179
	}
180
	if ref.IsFor() {
181
		return "for"
182
	}
183
	return ""
184
}
185

186
// RefType returns the simple ref type of the reference, e.g. branch, tag
187
// It's differrent from RefGroup, which is using the name of the directory under .git/refs
188
// Here we using branch but not heads, using tag but not tags
189
func (ref RefName) RefType() string {
190
	var refType string
191
	if ref.IsBranch() {
192
		refType = "branch"
193
	} else if ref.IsTag() {
194
		refType = "tag"
195
	}
196
	return refType
197
}
198

199
// RefURL returns the absolute URL for a ref in a repository
200
func RefURL(repoURL, ref string) string {
201
	refFullName := RefName(ref)
202
	refName := util.PathEscapeSegments(refFullName.ShortName())
203
	switch {
204
	case refFullName.IsBranch():
205
		return repoURL + "/src/branch/" + refName
206
	case refFullName.IsTag():
207
		return repoURL + "/src/tag/" + refName
208
	case !Sha1ObjectFormat.IsValid(ref):
209
		// assume they mean a branch
210
		return repoURL + "/src/branch/" + refName
211
	default:
212
		return repoURL + "/src/commit/" + refName
213
	}
214
}
215

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.