mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-22 06:15:18 +02:00
before: gitrepo vs git packages after: git package fully handle all git operations by the way, use `WithRepo(repo)` instead of `WithDir(repo.Path)` to hide path details. benefits: 1. remove all unnecessary wrappers, developers no need to struggle with "which package should be used" 2. simplify code, RepositoryFacade can (will) be used everywhere, all "path" details are (will be) hidden
99 lines
3.2 KiB
Go
99 lines
3.2 KiB
Go
// Copyright 2018 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"gitea.dev/modules/git/gitcmd"
|
|
"gitea.dev/modules/setting"
|
|
"gitea.dev/modules/util"
|
|
)
|
|
|
|
// GetRefs returns all references of the repository.
|
|
func (repo *Repository) GetRefs(ctx context.Context) ([]*Reference, error) {
|
|
return repo.GetRefsFiltered(ctx, "")
|
|
}
|
|
|
|
// ListOccurrences lists all refs of the given refType the given commit appears in sorted by creation date DESC
|
|
// refType should only be a literal "branch" or "tag" and nothing else
|
|
func (repo *Repository) ListOccurrences(ctx context.Context, refType, commitSHA string) ([]string, error) {
|
|
cmd := gitcmd.NewCommand()
|
|
switch refType {
|
|
case "branch":
|
|
cmd.AddArguments("branch")
|
|
case "tag":
|
|
cmd.AddArguments("tag")
|
|
default:
|
|
return nil, util.NewInvalidArgumentErrorf(`can only use "branch" or "tag" for refType, but got %q`, refType)
|
|
}
|
|
stdout, _, err := cmd.AddArguments("--no-color", "--sort=-creatordate", "--contains").
|
|
AddDynamicArguments(commitSHA).WithRepo(repo).RunStdString(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
refs := strings.Split(strings.TrimSpace(stdout), "\n")
|
|
if refType == "branch" {
|
|
return parseBranches(refs), nil
|
|
}
|
|
return parseTags(refs), nil
|
|
}
|
|
|
|
func parseBranches(refs []string) []string {
|
|
results := make([]string, 0, len(refs))
|
|
for _, ref := range refs {
|
|
if strings.HasPrefix(ref, "* ") { // current branch (main branch)
|
|
results = append(results, ref[len("* "):])
|
|
} else if strings.HasPrefix(ref, " ") { // all other branches
|
|
results = append(results, ref[len(" "):])
|
|
} else if ref != "" {
|
|
results = append(results, ref)
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
func parseTags(refs []string) []string {
|
|
results := make([]string, 0, len(refs))
|
|
for _, ref := range refs {
|
|
if ref != "" {
|
|
results = append(results, ref)
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
// UnstableGuessRefByShortName does the best guess to see whether a "short name" provided by user is a branch, tag or commit.
|
|
// It could guess wrongly if the input is already ambiguous. For example:
|
|
// * "refs/heads/the-name" vs "refs/heads/refs/heads/the-name"
|
|
// * "refs/tags/1234567890" vs commit "1234567890"
|
|
// In most cases, it SHOULD AVOID using this function, unless there is an irresistible reason (eg: make API friendly to end users)
|
|
// If the function is used, the caller SHOULD CHECK the ref type carefully.
|
|
func (repo *Repository) UnstableGuessRefByShortName(ctx context.Context, shortName string) RefName {
|
|
if repo.IsBranchExist(ctx, shortName) {
|
|
return RefNameFromBranch(shortName)
|
|
}
|
|
if repo.IsTagExist(ctx, shortName) {
|
|
return RefNameFromTag(shortName)
|
|
}
|
|
if strings.HasPrefix(shortName, "refs/") {
|
|
if repo.IsReferenceExist(ctx, shortName) {
|
|
return RefName(shortName)
|
|
}
|
|
}
|
|
commit, err := repo.GetCommit(ctx, shortName)
|
|
if err == nil {
|
|
commitIDString := commit.ID.String()
|
|
// make sure the "shortName" is either partial commit ID, or it is HEAD
|
|
if strings.HasPrefix(commitIDString, shortName) || shortName == RefNameHead {
|
|
return RefName(commitIDString)
|
|
} else {
|
|
setting.PanicInDevOrTesting("abuse of UnstableGuessRefByShortName, queried %s, got %s", shortName, commitIDString)
|
|
}
|
|
}
|
|
return ""
|
|
}
|