From 54b535a527c24c64a97127b66c39b57a0e363f3a Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 25 Oct 2022 06:38:39 +0800 Subject: [PATCH] Find DefaultPRHead based on branch and SHA (#514) Reviewed-on: https://gitea.com/gitea/tea/pulls/514 Reviewed-by: strk Reviewed-by: Norwin --- modules/git/branch.go | 51 +++++++++++++++++++++++++++---------- modules/task/pull_create.go | 5 ++-- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/modules/git/branch.go b/modules/git/branch.go index 6fef68d..f39c837 100644 --- a/modules/git/branch.go +++ b/modules/git/branch.go @@ -173,6 +173,7 @@ func (r TeaRepo) TeaFindBranchByName(branchName, repoURL string) (b *git_config. // TeaFindBranchRemote gives the first remote that has a branch with the same name or sha, // depending on what is passed in. // This function is needed, as git does not always define branches in .git/config with remote entries. +// Priority order is: first match of sha and branch -> first match of branch -> first match of sha func (r TeaRepo) TeaFindBranchRemote(branchName, hash string) (*git.Remote, error) { remotes, err := r.Remotes() if err != nil { @@ -193,35 +194,57 @@ func (r TeaRepo) TeaFindBranchRemote(branchName, hash string) (*git.Remote, erro } defer iter.Close() - var match *git.Remote - err = iter.ForEach(func(ref *git_plumbing.Reference) error { + var shaMatch *git.Remote + var branchMatch *git.Remote + var fullMatch *git.Remote + if err := iter.ForEach(func(ref *git_plumbing.Reference) error { if ref.Name().IsRemote() { names := strings.SplitN(ref.Name().Short(), "/", 2) remote := names[0] branch := names[1] - hashMatch := hash != "" && hash == ref.Hash().String() - nameMatch := branchName != "" && branchName == branch - if hashMatch || nameMatch { - match, err = r.Remote(remote) - return err + if branchMatch == nil && branchName != "" && branchName == branch { + if branchMatch, err = r.Remote(remote); err != nil { + return err + } + } + if shaMatch == nil && hash != "" && hash == ref.Hash().String() { + if shaMatch, err = r.Remote(remote); err != nil { + return err + } + } + if fullMatch == nil && branchName != "" && branchName == branch && hash != "" && hash == ref.Hash().String() { + if fullMatch, err = r.Remote(remote); err != nil { + return err + } + // stop asap you have a full match + return nil } } return nil - }) + }); err != nil { + return nil, err + } - return match, err + if fullMatch != nil { + return fullMatch, nil + } else if branchMatch != nil { + return branchMatch, nil + } else if shaMatch != nil { + return shaMatch, nil + } + return nil, nil } -// TeaGetCurrentBranchName return the name of the branch witch is currently active -func (r TeaRepo) TeaGetCurrentBranchName() (string, error) { +// TeaGetCurrentBranchNameAndSHA return the name and sha of the branch witch is currently active +func (r TeaRepo) TeaGetCurrentBranchNameAndSHA() (string, string, error) { localHead, err := r.Head() if err != nil { - return "", err + return "", "", err } if !localHead.Name().IsBranch() { - return "", fmt.Errorf("active ref is no branch") + return "", "", fmt.Errorf("active ref is no branch") } - return localHead.Name().Short(), nil + return localHead.Name().Short(), localHead.Hash().String(), nil } diff --git a/modules/task/pull_create.go b/modules/task/pull_create.go index 736fe63..f61108e 100644 --- a/modules/task/pull_create.go +++ b/modules/task/pull_create.go @@ -99,11 +99,12 @@ func GetDefaultPRBase(login *config.Login, owner, repo string) (string, error) { // that has a branch with the same name, and extracts the owner from its URL. // If no remote matches, owner is empty, meaning same as head repo owner. func GetDefaultPRHead(localRepo *local_git.TeaRepo) (owner, branch string, err error) { - if branch, err = localRepo.TeaGetCurrentBranchName(); err != nil { + var sha string + if branch, sha, err = localRepo.TeaGetCurrentBranchNameAndSHA(); err != nil { return } - remote, err := localRepo.TeaFindBranchRemote(branch, "") + remote, err := localRepo.TeaFindBranchRemote(branch, sha) if err != nil { err = fmt.Errorf("could not determine remote for current branch: %s", err) return