Skip to content

Abstract for RepoPath #28966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
}
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), gitrepo.RepoGitURL(repo))
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil {
log.Warn("OpenRepository: %v", err)
Expand Down
9 changes: 5 additions & 4 deletions models/git/commit_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
Expand Down Expand Up @@ -453,9 +454,9 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA)
}

repoPath := opts.Repo.RepoPath()
repoURL := gitrepo.RepoGitURL(opts.Repo)
if opts.Creator == nil {
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA)
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoURL, opts.SHA)
}

ctx, committer, err := db.TxContext(ctx)
Expand All @@ -477,13 +478,13 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
opts.CommitStatus.CreatorID = opts.Creator.ID
opts.CommitStatus.RepoID = opts.Repo.ID
opts.CommitStatus.Index = idx
log.Debug("NewCommitStatus[%s, %s]: %d", repoPath, opts.SHA, opts.CommitStatus.Index)
log.Debug("NewCommitStatus[%s, %s]: %d", repoURL, opts.SHA, opts.CommitStatus.Index)

opts.CommitStatus.ContextHash = hashCommitStatusContext(opts.CommitStatus.Context)

// Insert new CommitStatus
if _, err = db.GetEngine(ctx).Insert(opts.CommitStatus); err != nil {
return fmt.Errorf("insert CommitStatus[%s, %s]: %w", repoPath, opts.SHA, err)
return fmt.Errorf("insert CommitStatus[%s, %s]: %w", repoURL, opts.SHA, err)
}

return committer.Commit()
Expand Down
5 changes: 0 additions & 5 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,3 @@ func configUnsetAll(key, value string) error {
}
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
}

// Fsck verifies the connectivity and validity of the objects in the database
func Fsck(ctx context.Context, repoPath string, timeout time.Duration, args TrustedCmdArgs) error {
return NewCommand(ctx, "fsck").AddArguments(args...).Run(&RunOpts{Timeout: timeout, Dir: repoPath})
}
11 changes: 0 additions & 11 deletions modules/git/repo_branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ import (
// 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
Expand Down
6 changes: 0 additions & 6 deletions modules/git/repo_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package git

import (
"context"
"fmt"
"io"
"strings"
Expand All @@ -17,11 +16,6 @@ import (
// TagPrefix tags prefix path on the repository
const TagPrefix = "refs/tags/"

// IsTagExist returns true if given tag exists in the repository.
func IsTagExist(ctx context.Context, repoPath, name string) bool {
return IsReferenceExist(ctx, repoPath, TagPrefix+name)
}

// CreateTag create one tag in the repository
func (repo *Repository) CreateTag(name, revision string) error {
_, _, err := NewCommand(repo.Ctx, "tag").AddDashesAndList(name, revision).RunStdString(&RunOpts{Dir: repo.Path})
Expand Down
20 changes: 20 additions & 0 deletions modules/gitrepo/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (str
return gitRepo.GetBranchCommitID(branch)
}

// IsReferenceExist returns true if given reference exists in the repository.
func IsReferenceExist(ctx context.Context, repo Repository, name string) bool {
_, _, err := git.NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&git.RunOpts{Dir: repoPath(repo)})
return err == nil
}

func IsWikiReferenceExist(ctx context.Context, repo Repository, name string) bool {
_, _, err := git.NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&git.RunOpts{Dir: wikiPath(repo)})
return err == nil
}

// IsBranchExist returns true if given branch exists in the repository.
func IsBranchExist(ctx context.Context, repo Repository, name string) bool {
return IsReferenceExist(ctx, repo, git.BranchPrefix+name)
}

func IsWikiBranchExist(ctx context.Context, repo Repository, name string) bool {
return IsWikiReferenceExist(ctx, repo, git.BranchPrefix+name)
}

// SetDefaultBranch sets default branch of repository.
func SetDefaultBranch(ctx context.Context, repo Repository, name string) error {
_, _, err := git.NewCommand(ctx, "symbolic-ref", "HEAD").
Expand Down
38 changes: 38 additions & 0 deletions modules/gitrepo/format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"
"errors"
"strings"

"code.gitea.io/gitea/modules/git"
)

// GetObjectFormatOfRepo returns the hash type of repository at a given path
func GetObjectFormatOfRepo(ctx context.Context, repo Repository) (git.ObjectFormat, error) {
var stdout, stderr strings.Builder

err := git.NewCommand(ctx, "hash-object", "--stdin").Run(&git.RunOpts{
Dir: repoPath(repo),
Stdout: &stdout,
Stderr: &stderr,
Stdin: &strings.Reader{},
})
if err != nil {
return nil, err
}

if stderr.Len() > 0 {
return nil, errors.New(stderr.String())
}

h, err := git.NewIDFromString(strings.TrimRight(stdout.String(), "\n"))
if err != nil {
return nil, err
}

return h.Type(), nil
}
16 changes: 16 additions & 0 deletions modules/gitrepo/fsck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"
"time"

"code.gitea.io/gitea/modules/git"
)

// Fsck verifies the connectivity and validity of the objects in the database
func Fsck(ctx context.Context, repo Repository, timeout time.Duration, args git.TrustedCmdArgs) error {
return git.NewCommand(ctx, "fsck").AddArguments(args...).Run(&git.RunOpts{Timeout: timeout, Dir: repoPath(repo)})
}
47 changes: 47 additions & 0 deletions modules/gitrepo/gitrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@ package gitrepo

import (
"context"
"fmt"
"io"
"path/filepath"
"strings"
"time"

"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)

type Repository interface {
GetName() string
GetOwnerName() string
}

func fullName(repo Repository) string {
return repo.GetOwnerName() + "/" + repo.GetName()
}

func repoPath(repo Repository) string {
return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".git")
}
Expand Down Expand Up @@ -101,3 +109,42 @@ func RepositoryFromContextOrOpenPath(ctx context.Context, path string) (*git.Rep
gitRepo, err := git.OpenRepository(ctx, path)
return gitRepo, gitRepo, err
}

func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) {
return util.IsExist(repoPath(repo))
}

func RenameRepository(ctx context.Context, repo Repository, newName string) error {
newRepoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(newName)+".git")
if err := util.Rename(repoPath(repo), newRepoPath); err != nil {
return fmt.Errorf("rename repository directory: %w", err)
}
return nil
}

func RenameWikiRepository(ctx context.Context, repo Repository, newName string) error {
newWikiRepoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(newName)+".wiki.git")
if err := util.Rename(wikiPath(repo), newWikiRepoPath); err != nil {
return fmt.Errorf("rename repository wiki directory: %w", err)
}
return nil
}

func DeleteRepository(ctx context.Context, repo Repository) error {
return util.RemoveAll(repoPath(repo))
}

func ForkRepository(ctx context.Context, baseRepo, targetRepo Repository, singleBranch string) error {
cloneCmd := git.NewCommand(ctx, "clone", "--bare")
if singleBranch != "" {
cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(singleBranch)
}

if stdout, _, err := cloneCmd.AddDynamicArguments(repoPath(baseRepo), repoPath(targetRepo)).
SetDescription(fmt.Sprintf("ForkRepository(git clone): %s to %s", fullName(baseRepo), fullName(targetRepo))).
RunStdBytes(&git.RunOpts{Timeout: 10 * time.Minute}); err != nil {
log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", targetRepo, baseRepo, stdout, err)
return fmt.Errorf("git clone: %w", err)
}
return nil
}
21 changes: 16 additions & 5 deletions modules/repository/hooks.go → modules/gitrepo/hooks.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repository
package gitrepo

import (
"context"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -106,9 +107,14 @@ done
}

// CreateDelegateHooks creates all the hooks scripts for the repo
func CreateDelegateHooks(repoPath string) (err error) {
func CreateDelegateHooks(ctx context.Context, repo Repository, iswiki bool) (err error) {
hookNames, hookTpls, giteaHookTpls := getHookTemplates()
hookDir := filepath.Join(repoPath, "hooks")
var hookDir string
if iswiki {
hookDir = filepath.Join(wikiPath(repo), "hooks")
} else {
hookDir = filepath.Join(repoPath(repo), "hooks")
}

for i, hookName := range hookNames {
oldHookPath := filepath.Join(hookDir, hookName)
Expand Down Expand Up @@ -170,10 +176,15 @@ func ensureExecutable(filename string) error {
}

// CheckDelegateHooks checks the hooks scripts for the repo
func CheckDelegateHooks(repoPath string) ([]string, error) {
func CheckDelegateHooks(ctx context.Context, repo Repository, isWiki bool) ([]string, error) {
hookNames, hookTpls, giteaHookTpls := getHookTemplates()

hookDir := filepath.Join(repoPath, "hooks")
var hookDir string
if isWiki {
hookDir = filepath.Join(wikiPath(repo), "hooks")
} else {
hookDir = filepath.Join(repoPath(repo), "hooks")
}
results := make([]string, 0, 10)

for i, hookName := range hookNames {
Expand Down
19 changes: 19 additions & 0 deletions modules/gitrepo/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"

"code.gitea.io/gitea/modules/git"
)

// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
func CountDivergingCommits(ctx context.Context, repo Repository, baseBranch, branch string) (*git.DivergeObject, error) {
divergence, err := git.GetDivergingCommits(ctx, repoPath(repo), baseBranch, branch)
if err != nil {
return nil, err
}
return &divergence, nil
}
15 changes: 15 additions & 0 deletions modules/gitrepo/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"

"code.gitea.io/gitea/modules/git"
)

// IsTagExist returns true if given tag exists in the repository.
func IsTagExist(ctx context.Context, repo Repository, name string) bool {
return IsReferenceExist(ctx, repo, git.TagPrefix+name)
}
4 changes: 4 additions & 0 deletions modules/gitrepo/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ package gitrepo
func RepoGitURL(repo Repository) string {
return repoPath(repo)
}

func WikiRepoGitURL(repo Repository) string {
return repoPath(repo)
}
17 changes: 17 additions & 0 deletions modules/gitrepo/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"
"path/filepath"
"strings"

"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)

func RenameDir(ctx context.Context, oldName, newName string) error {
return util.Rename(filepath.Join(setting.RepoRootPath, strings.ToLower(oldName)), filepath.Join(setting.RepoRootPath, strings.ToLower(newName)))
}
10 changes: 5 additions & 5 deletions modules/indexer/stats/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ func (db *DBIndexer) Index(id int64) error {
commitID, err := gitRepo.GetBranchCommitID(repo.DefaultBranch)
if err != nil {
if git.IsErrBranchNotExist(err) || git.IsErrNotExist(err) || setting.IsInTesting {
log.Debug("Unable to get commit ID for default branch %s in %s ... skipping this repository", repo.DefaultBranch, repo.RepoPath())
log.Debug("Unable to get commit ID for default branch %s in %s ... skipping this repository", repo.DefaultBranch, gitrepo.RepoGitURL(repo))
return nil
}
log.Error("Unable to get commit ID for default branch %s in %s. Error: %v", repo.DefaultBranch, repo.RepoPath(), err)
log.Error("Unable to get commit ID for default branch %s in %s. Error: %v", repo.DefaultBranch, gitrepo.RepoGitURL(repo), err)
return err
}

Expand All @@ -65,17 +65,17 @@ func (db *DBIndexer) Index(id int64) error {
stats, err := gitRepo.GetLanguageStats(commitID)
if err != nil {
if !setting.IsInTesting {
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err)
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, gitrepo.RepoGitURL(repo), err)
}
return err
}
err = repo_model.UpdateLanguageStats(ctx, repo, commitID, stats)
if err != nil {
log.Error("Unable to update language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err)
log.Error("Unable to update language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, gitrepo.RepoGitURL(repo), err)
return err
}

log.Debug("DBIndexer completed language stats for ID %s for default branch %s in %s. stats count: %d", commitID, repo.DefaultBranch, repo.RepoPath(), len(stats))
log.Debug("DBIndexer completed language stats for ID %s for default branch %s in %s. stats count: %d", commitID, repo.DefaultBranch, gitrepo.RepoGitURL(repo), len(stats))
return nil
}

Expand Down
Loading