`tea pr checkout`: fetch via ssh if available (#192)
improved logging try to use local branch before creating pulls/<PR> useful for checking out your own PRs reorder imports refactor pulls checkout isolated "gitea API to local git cfg" aspect work around go-git limitation As we cant manage multiple remote URLs properly, we just set the correct URL protocol ahead of time. This logic won't apply for already existing HTTPS remotes, these should be deleted before using `tea pr checkout`. use SSH if user has key in gitea Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Norwin Roosen <git@nroo.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/192 Reviewed-by: 6543 <6543@noreply.gitea.io> Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-Authored-By: Norwin <noerw@noreply.gitea.io> Co-Committed-By: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
parent
33468630e6
commit
355fd7aa53
|
@ -13,6 +13,7 @@ import (
|
|||
local_git "code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -32,40 +33,33 @@ func runPullsCheckout(ctx *cli.Context) error {
|
|||
if ctx.Args().Len() != 1 {
|
||||
log.Fatal("Must specify a PR index")
|
||||
}
|
||||
|
||||
// fetch PR source-repo & -branch from gitea
|
||||
idx, err := utils.ArgToIndex(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pr, _, err := login.Client().GetPullRequest(owner, repo, idx)
|
||||
|
||||
localRepo, err := local_git.RepoForWorkdir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remoteURL := pr.Head.Repository.CloneURL
|
||||
remoteBranchName := pr.Head.Ref
|
||||
|
||||
// open local git repo
|
||||
localRepo, err := local_git.RepoForWorkdir()
|
||||
localBranchName, remoteBranchName, newRemoteName, remoteURL, err :=
|
||||
gitConfigForPR(localRepo, login, owner, repo, idx)
|
||||
if err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// verify related remote is in local repo, otherwise add it
|
||||
newRemoteName := fmt.Sprintf("pulls/%v", pr.Head.Repository.Owner.UserName)
|
||||
localRemote, err := localRepo.GetOrCreateRemote(remoteURL, newRemoteName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
localRemoteName := localRemote.Config().Name
|
||||
localBranchName := fmt.Sprintf("pulls/%v-%v", idx, remoteBranchName)
|
||||
|
||||
// fetch remote
|
||||
// get auth & fetch remote
|
||||
fmt.Printf("Fetching PR %v (head %s:%s) from remote '%s'\n",
|
||||
idx, remoteURL, remoteBranchName, localRemoteName)
|
||||
|
||||
url, err := local_git.ParseURL(localRemote.Config().URLs[0])
|
||||
url, err := local_git.ParseURL(remoteURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -73,7 +67,6 @@ func runPullsCheckout(ctx *cli.Context) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = localRemote.Fetch(&git.FetchOptions{Auth: auth})
|
||||
if err == git.NoErrAlreadyUpToDate {
|
||||
fmt.Println(err)
|
||||
|
@ -85,13 +78,38 @@ func runPullsCheckout(ctx *cli.Context) error {
|
|||
fmt.Printf("Creating branch '%s'\n", localBranchName)
|
||||
err = localRepo.TeaCreateBranch(localBranchName, remoteBranchName, localRemoteName)
|
||||
if err == git.ErrBranchExists {
|
||||
fmt.Println(err)
|
||||
fmt.Println("There may be changes since you last checked out, run `git pull` to get them.")
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Checking out PR %v\n", idx)
|
||||
err = localRepo.TeaCheckout(localBranchName)
|
||||
|
||||
return err
|
||||
return localRepo.TeaCheckout(localBranchName)
|
||||
}
|
||||
|
||||
func gitConfigForPR(repo *local_git.TeaRepo, login *config.Login, owner, repoName string, idx int64) (localBranch, remoteBranch, remoteName, remoteURL string, err error) {
|
||||
// fetch PR source-repo & -branch from gitea
|
||||
pr, _, err := login.Client().GetPullRequest(owner, repoName, idx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// test if we can pull via SSH, and configure git remote accordingly
|
||||
remoteURL = pr.Head.Repository.CloneURL
|
||||
keys, _, err := login.Client().ListMyPublicKeys(gitea.ListPublicKeysOptions{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(keys) != 0 {
|
||||
remoteURL = pr.Head.Repository.SSHURL
|
||||
}
|
||||
|
||||
// try to find a matching existing branch, otherwise return branch in pulls/ namespace
|
||||
localBranch = fmt.Sprintf("pulls/%v-%v", idx, pr.Head.Ref)
|
||||
if b, _ := repo.TeaFindBranchBySha(pr.Head.Sha, remoteURL); b != nil {
|
||||
localBranch = b.Name
|
||||
}
|
||||
|
||||
remoteBranch = pr.Head.Ref
|
||||
remoteName = fmt.Sprintf("pulls/%v", pr.Head.Repository.Owner.UserName)
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue