mirror of
https://gitcode.com/gitea/gitea.git
synced 2025-06-11 23:29:09 +08:00
.devcontainer
.gitea
.github
assets
build
cmd
contrib
custom
docker
docs
models
modules
actions
activitypub
analyze
assetfs
auth
avatar
badge
base
cache
charset
container
csv
dump
emoji
eventsource
generate
git
foreachref
internal
pipeline
tests
url
README.md
attribute.go
batch_reader.go
blame.go
blame_sha256_test.go
blame_test.go
blob.go
blob_gogit.go
blob_nogogit.go
blob_test.go
command.go
command_race_test.go
command_test.go
commit.go
commit_convert_gogit.go
commit_info.go
commit_info_gogit.go
commit_info_nogogit.go
commit_info_test.go
commit_reader.go
commit_sha256_test.go
commit_test.go
diff.go
diff_test.go
error.go
git.go
git_test.go
grep.go
grep_test.go
hook.go
last_commit_cache.go
last_commit_cache_gogit.go
last_commit_cache_nogogit.go
log_name_status.go
notes.go
notes_gogit.go
notes_nogogit.go
notes_test.go
object_format.go
object_id.go
object_id_gogit.go
object_id_test.go
parse_gogit.go
parse_gogit_test.go
parse_nogogit.go
parse_nogogit_test.go
ref.go
ref_test.go
remote.go
repo.go
repo_archive.go
repo_attribute.go
repo_attribute_test.go
repo_base.go
repo_base_gogit.go
repo_base_nogogit.go
repo_blame.go
repo_blob.go
repo_blob_gogit.go
repo_blob_nogogit.go
repo_blob_test.go
repo_branch.go
repo_branch_gogit.go
repo_branch_nogogit.go
repo_branch_test.go
repo_commit.go
repo_commit_gogit.go
repo_commit_nogogit.go
repo_commit_test.go
repo_commitgraph.go
repo_commitgraph_gogit.go
repo_compare.go
repo_compare_test.go
repo_gpg.go
repo_hook.go
repo_index.go
repo_language_stats.go
repo_language_stats_gogit.go
repo_language_stats_nogogit.go
repo_language_stats_test.go
repo_object.go
repo_ref.go
repo_ref_gogit.go
repo_ref_nogogit.go
repo_ref_test.go
repo_stats.go
repo_stats_test.go
repo_tag.go
repo_tag_gogit.go
repo_tag_nogogit.go
repo_tag_test.go
repo_test.go
repo_tree.go
repo_tree_gogit.go
repo_tree_nogogit.go
signature.go
signature_gogit.go
signature_nogogit.go
signature_test.go
submodule.go
submodule_test.go
tag.go
tag_test.go
tree.go
tree_blob.go
tree_blob_gogit.go
tree_blob_nogogit.go
tree_entry.go
tree_entry_gogit.go
tree_entry_mode.go
tree_entry_nogogit.go
tree_entry_test.go
tree_gogit.go
tree_nogogit.go
tree_test.go
utils.go
gitgraph
gitrepo
graceful
hcaptcha
highlight
hostmatcher
html
httpcache
httplib
indexer
issue
json
label
lfs
log
markup
mcaptcha
metrics
migration
nosql
optional
options
packages
paginator
pprof
private
process
proxy
proxyprotocol
public
queue
recaptcha
references
regexplru
repository
secret
session
setting
sitemap
ssh
storage
structs
svg
sync
system
templates
test
testlogger
timeutil
translation
turnstile
typesniffer
updatechecker
uri
user
util
validation
web
webhook
options
public
routers
services
snap
templates
tests
tools
web_src
.air.toml
.changelog.yml
.dockerignore
.editorconfig
.eslintrc.yaml
.gitattributes
.gitignore
.gitpod.yml
.golangci.yml
.ignore
.markdownlint.yaml
.npmrc
.spectral.yaml
.yamllint.yaml
BSDmakefile
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
DCO
Dockerfile
Dockerfile.rootless
LICENSE
MAINTAINERS
Makefile
README.md
README_ZH.md
SECURITY.md
build.go
crowdin.yml
go.mod
go.sum
main.go
package-lock.json
package.json
playwright.config.js
poetry.lock
poetry.toml
pyproject.toml
stylelint.config.js
tailwind.config.js
updates.config.js
vitest.config.js
webpack.config.js
160 lines
4.2 KiB
Go
160 lines
4.2 KiB
Go
// Copyright 2015 The Gogs Authors. All rights reserved.
|
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// BranchPrefix base dir of the branch information file store on git
|
|
const BranchPrefix = "refs/heads/"
|
|
|
|
// IsReferenceExist returns true if given reference exists in the repository.
|
|
func IsReferenceExist(ctx context.Context, repoPath, name string) bool {
|
|
_, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath})
|
|
return err == nil
|
|
}
|
|
|
|
// IsBranchExist returns true if given branch exists in the repository.
|
|
func IsBranchExist(ctx context.Context, repoPath, name string) bool {
|
|
return IsReferenceExist(ctx, repoPath, BranchPrefix+name)
|
|
}
|
|
|
|
// Branch represents a Git branch.
|
|
type Branch struct {
|
|
Name string
|
|
Path string
|
|
|
|
gitRepo *Repository
|
|
}
|
|
|
|
// GetHEADBranch returns corresponding branch of HEAD.
|
|
func (repo *Repository) GetHEADBranch() (*Branch, error) {
|
|
if repo == nil {
|
|
return nil, fmt.Errorf("nil repo")
|
|
}
|
|
stdout, _, err := NewCommand(repo.Ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repo.Path})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stdout = strings.TrimSpace(stdout)
|
|
|
|
if !strings.HasPrefix(stdout, BranchPrefix) {
|
|
return nil, fmt.Errorf("invalid HEAD branch: %v", stdout)
|
|
}
|
|
|
|
return &Branch{
|
|
Name: stdout[len(BranchPrefix):],
|
|
Path: stdout,
|
|
gitRepo: repo,
|
|
}, nil
|
|
}
|
|
|
|
func GetDefaultBranch(ctx context.Context, repoPath string) (string, error) {
|
|
stdout, _, err := NewCommand(ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repoPath})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
stdout = strings.TrimSpace(stdout)
|
|
if !strings.HasPrefix(stdout, BranchPrefix) {
|
|
return "", errors.New("the HEAD is not a branch: " + stdout)
|
|
}
|
|
return strings.TrimPrefix(stdout, BranchPrefix), nil
|
|
}
|
|
|
|
// GetBranch returns a branch by it's name
|
|
func (repo *Repository) GetBranch(branch string) (*Branch, error) {
|
|
if !repo.IsBranchExist(branch) {
|
|
return nil, ErrBranchNotExist{branch}
|
|
}
|
|
return &Branch{
|
|
Path: repo.Path,
|
|
Name: branch,
|
|
gitRepo: repo,
|
|
}, nil
|
|
}
|
|
|
|
// GetBranches returns a slice of *git.Branch
|
|
func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) {
|
|
brs, countAll, err := repo.GetBranchNames(skip, limit)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
branches := make([]*Branch, len(brs))
|
|
for i := range brs {
|
|
branches[i] = &Branch{
|
|
Path: repo.Path,
|
|
Name: brs[i],
|
|
gitRepo: repo,
|
|
}
|
|
}
|
|
|
|
return branches, countAll, nil
|
|
}
|
|
|
|
// DeleteBranchOptions Option(s) for delete branch
|
|
type DeleteBranchOptions struct {
|
|
Force bool
|
|
}
|
|
|
|
// DeleteBranch delete a branch by name on repository.
|
|
func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) error {
|
|
cmd := NewCommand(repo.Ctx, "branch")
|
|
|
|
if opts.Force {
|
|
cmd.AddArguments("-D")
|
|
} else {
|
|
cmd.AddArguments("-d")
|
|
}
|
|
|
|
cmd.AddDashesAndList(name)
|
|
_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
|
|
|
|
return err
|
|
}
|
|
|
|
// CreateBranch create a new branch
|
|
func (repo *Repository) CreateBranch(branch, oldbranchOrCommit string) error {
|
|
cmd := NewCommand(repo.Ctx, "branch")
|
|
cmd.AddDashesAndList(branch, oldbranchOrCommit)
|
|
|
|
_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
|
|
|
|
return err
|
|
}
|
|
|
|
// AddRemote adds a new remote to repository.
|
|
func (repo *Repository) AddRemote(name, url string, fetch bool) error {
|
|
cmd := NewCommand(repo.Ctx, "remote", "add")
|
|
if fetch {
|
|
cmd.AddArguments("-f")
|
|
}
|
|
cmd.AddDynamicArguments(name, url)
|
|
|
|
_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
|
|
return err
|
|
}
|
|
|
|
// RemoveRemote removes a remote from repository.
|
|
func (repo *Repository) RemoveRemote(name string) error {
|
|
_, _, err := NewCommand(repo.Ctx, "remote", "rm").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
|
|
return err
|
|
}
|
|
|
|
// GetCommit returns the head commit of a branch
|
|
func (branch *Branch) GetCommit() (*Commit, error) {
|
|
return branch.gitRepo.GetBranchCommit(branch.Name)
|
|
}
|
|
|
|
// RenameBranch rename a branch
|
|
func (repo *Repository) RenameBranch(from, to string) error {
|
|
_, _, err := NewCommand(repo.Ctx, "branch", "-m").AddDynamicArguments(from, to).RunStdString(&RunOpts{Dir: repo.Path})
|
|
return err
|
|
}
|