3 Star 12 Fork 2

Git工具集/git-lfs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
.circleci
.github
commands
config
config.go
config_test.go
delayed_environment.go
environment.go
environment_test.go
extension.go
extension_test.go
fetcher.go
git_fetcher.go
git_fetcher_test.go
map_fetcher.go
netrc.go
netrc_nix.go
netrc_windows.go
os_fetcher.go
url_config.go
url_config_test.go
util_nix.go
util_windows.go
version.go
creds
debian
docker
docs
errors
filepathfilter
fs
git
lfs
lfsapi
lfshttp
locking
rpm
script
subprocess
t
tasklog
tools
tq
vendor
.gitattributes
.gitignore
.mailmap
.travis.yml
CHANGELOG.md
CODE-OF-CONDUCT.md
CONTRIBUTING.md
INSTALLING.md
LICENSE.md
Makefile
README.md
appveyor.yml
git-lfs.go
git-lfs_windows.go
go.mod
go.sum
versioninfo.json
克隆/下载
url_config.go 6.24 KB
一键复制 编辑 原始数据 按行查看 历史
package config
import (
"fmt"
"net/url"
"regexp"
"strings"
)
type URLConfig struct {
git Environment
}
func NewURLConfig(git Environment) *URLConfig {
if git == nil {
git = EnvironmentOf(make(mapFetcher))
}
return &URLConfig{
git: git,
}
}
// Get retrieves a `http.{url}.{key}` for the given key and urls, following the
// rules in https://git-scm.com/docs/git-config#git-config-httplturlgt.
// The value for `http.{key}` is returned as a fallback if no config keys are
// set for the given urls.
func (c *URLConfig) Get(prefix, rawurl, key string) (string, bool) {
if c == nil {
return "", false
}
key = strings.ToLower(key)
prefix = strings.ToLower(prefix)
if v := c.getAll(prefix, rawurl, key); len(v) > 0 {
return v[len(v)-1], true
}
return c.git.Get(strings.Join([]string{prefix, key}, "."))
}
func (c *URLConfig) GetAll(prefix, rawurl, key string) []string {
if c == nil {
return nil
}
key = strings.ToLower(key)
prefix = strings.ToLower(prefix)
if v := c.getAll(prefix, rawurl, key); len(v) > 0 {
return v
}
return c.git.GetAll(strings.Join([]string{prefix, key}, "."))
}
func (c *URLConfig) Bool(prefix, rawurl, key string, def bool) bool {
s, _ := c.Get(prefix, rawurl, key)
return Bool(s, def)
}
func (c *URLConfig) getAll(prefix, rawurl, key string) []string {
type urlMatch struct {
key string // The full configuration key
hostScore int // A score indicating the strength of the host match
pathScore int // A score indicating the strength of the path match
userMatch int // Whether we matched on a username. 1 for yes, else 0
}
searchURL, err := url.Parse(rawurl)
if err != nil {
return nil
}
config := c.git.All()
re := regexp.MustCompile(fmt.Sprintf(`%s.(\S+).%s`, prefix, key))
bestMatch := urlMatch{
key: "",
hostScore: 0,
pathScore: 0,
userMatch: 0,
}
for k := range config {
// Ensure we're examining the correct type of key and parse out the URL
matches := re.FindStringSubmatch(k)
if matches == nil {
continue
}
configURL, err := url.Parse(matches[1])
if err != nil {
continue
}
match := urlMatch{
key: k,
}
// Rule #1: Scheme must match exactly
if searchURL.Scheme != configURL.Scheme {
continue
}
// Rule #2: Hosts must match exactly, or through wildcards. More exact
// matches should take priority over wildcard matches
match.hostScore = compareHosts(searchURL.Hostname(), configURL.Hostname())
if match.hostScore == 0 {
continue
}
if match.hostScore < bestMatch.hostScore {
continue
}
// Rule #3: Port Number must match exactly
if searchURL.Port() != configURL.Port() {
continue
}
// Rule #4: Configured path must match exactly, or as a prefix of
// slash-delimited path elements
match.pathScore = comparePaths(searchURL.Path, configURL.Path)
if match.pathScore == 0 {
continue
}
// Rule #5: Username must match exactly if present in the config.
// If not present, config matches on any username but with lower
// priority than an exact username match.
if configURL.User != nil {
if searchURL.User == nil {
continue
}
if searchURL.User.Username() != configURL.User.Username() {
continue
}
match.userMatch = 1
}
// Now combine our various scores to determine if we have found a best
// match. Host score > path score > user score
if match.hostScore > bestMatch.hostScore {
bestMatch = match
continue
}
if match.pathScore > bestMatch.pathScore {
bestMatch = match
continue
}
if match.pathScore == bestMatch.pathScore && match.userMatch > bestMatch.userMatch {
bestMatch = match
continue
}
}
if bestMatch.key == "" {
return nil
}
return c.git.GetAll(bestMatch.key)
}
// compareHosts compares a hostname with a configuration hostname to determine
// a match. It returns an integer indicating the strength of the match, or 0 if
// the two hostnames did not match.
func compareHosts(searchHostname, configHostname string) int {
searchHost := strings.Split(searchHostname, ".")
configHost := strings.Split(configHostname, ".")
if len(searchHost) != len(configHost) {
return 0
}
score := len(searchHost) + 1
for i, subdomain := range searchHost {
if configHost[i] == "*" {
score--
continue
}
if subdomain != configHost[i] {
return 0
}
}
return score
}
// comparePaths compares a path with a configuration path to determine a match.
// It returns an integer indicating the strength of the match, or 0 if the two
// paths did not match.
func comparePaths(rawSearchPath, rawConfigPath string) int {
f := func(c rune) bool {
return c == '/'
}
searchPath := strings.FieldsFunc(rawSearchPath, f)
configPath := strings.FieldsFunc(rawConfigPath, f)
if len(searchPath) < len(configPath) {
return 0
}
// Start with a base score of 1, so we return something above 0 for a
// zero-length path
score := 1
for i, element := range configPath {
searchElement := searchPath[i]
if element == searchElement {
score += 2
continue
}
if isDefaultLFSUrl(searchElement, searchPath, i+1) {
if searchElement[0:len(searchElement)-4] == element {
// Since we matched without the `.git` prefix, only add one
// point to the score instead of 2
score++
continue
}
}
return 0
}
return score
}
func (c *URLConfig) hostsAndPaths(rawurl string) (hosts, paths []string) {
u, err := url.Parse(rawurl)
if err != nil {
return nil, nil
}
return c.hosts(u), c.paths(u.Path)
}
func (c *URLConfig) hosts(u *url.URL) []string {
hosts := make([]string, 0, 1)
if u.User != nil {
hosts = append(hosts, fmt.Sprintf("%s://%s@%s", u.Scheme, u.User.Username(), u.Host))
}
hosts = append(hosts, fmt.Sprintf("%s://%s", u.Scheme, u.Host))
return hosts
}
func (c *URLConfig) paths(path string) []string {
pLen := len(path)
if pLen <= 2 {
return nil
}
end := pLen
if strings.HasSuffix(path, slash) {
end--
}
return strings.Split(path[1:end], slash)
}
const (
gitExt = ".git"
infoPart = "info"
lfsPart = "lfs"
slash = "/"
)
func isDefaultLFSUrl(path string, parts []string, index int) bool {
if len(path) < 5 {
return false // shorter than ".git"
}
if !strings.HasSuffix(path, gitExt) {
return false
}
if index > len(parts)-2 {
return false
}
return parts[index] == infoPart && parts[index+1] == lfsPart
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/vcs-all-in-one/git-lfs.git
git@gitee.com:vcs-all-in-one/git-lfs.git
vcs-all-in-one
git-lfs
git-lfs
master

搜索帮助