1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package task
import (
"fmt"
"net/url"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/modules/config"
local_git "code.gitea.io/tea/modules/git"
"github.com/go-git/go-git/v5"
git_config "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
)
// RepoClone creates a local git clone in the given path, and sets up upstream remote
// for fork repos, for good usability with tea.
func RepoClone(
path string,
login *config.Login,
repoOwner, repoName string,
callback func(string) (string, error),
depth int,
) (*local_git.TeaRepo, error) {
repoMeta, _, err := login.Client().GetRepo(repoOwner, repoName)
if err != nil {
return nil, err
}
originURL, err := cloneURL(repoMeta, login)
if err != nil {
return nil, err
}
auth, err := local_git.GetAuthForURL(originURL, login.Token, login.SSHKey, callback)
if err != nil {
return nil, err
}
// default path behaviour as native git
if path == "" {
path = repoName
}
repo, err := git.PlainClone(path, false, &git.CloneOptions{
URL: originURL.String(),
Auth: auth,
Depth: depth,
InsecureSkipTLS: login.Insecure,
})
if err != nil {
return nil, err
}
// set up upstream remote for forks
if repoMeta.Fork && repoMeta.Parent != nil {
upstreamURL, err := cloneURL(repoMeta.Parent, login)
if err != nil {
return nil, err
}
upstreamBranch := repoMeta.Parent.DefaultBranch
repo.CreateRemote(&git_config.RemoteConfig{
Name: "upstream",
URLs: []string{upstreamURL.String()},
})
repoConf, err := repo.Config()
if err != nil {
return nil, err
}
if b, ok := repoConf.Branches[upstreamBranch]; ok {
b.Remote = "upstream"
b.Merge = plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", upstreamBranch))
}
if err = repo.SetConfig(repoConf); err != nil {
return nil, err
}
}
return &local_git.TeaRepo{Repository: repo}, nil
}
func cloneURL(repo *gitea.Repository, login *config.Login) (*url.URL, error) {
urlStr := repo.CloneURL
if login.SSHKey != "" {
urlStr = repo.SSHURL
}
return local_git.ParseURL(urlStr)
}
|