refactor: clean up git repo and model migration packages (#38564)

enable the golangci depguard lint rule: deny "models" and its sub
packages in "modelmigration" package.
This commit is contained in:
wxiaoguang
2026-07-23 09:22:26 +08:00
committed by GitHub
parent fa64b4627a
commit 1acf93d854
43 changed files with 243 additions and 167 deletions
+3 -3
View File
@@ -55,10 +55,10 @@ linters:
files:
- '**/modelmigration/**/*.go'
deny:
- pkg: gitea.dev/models$ # FIXME: it should deny all sub packages like "gitea.dev/models/repo"
desc: migrations must not depend on the models package
- pkg: gitea.dev/models
desc: "migrations must not depend on the models package. HINT: MIGRATION-STRUCT-FROZEN"
- pkg: gitea.dev/modules/structs
desc: migrations must not depend on modules/structs (API structures change over time)
desc: "migrations must not depend on modules/structs. HINT: MIGRATION-STRUCT-FROZEN"
nolintlint:
allow-unused: false
require-explanation: true
+6 -7
View File
@@ -11,19 +11,14 @@ import (
"regexp"
"strings"
"gitea.dev/models/db"
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
"xorm.io/builder"
"xorm.io/xorm/schemas"
)
// Migrations should never use model structs directly, because the model structs can be different in different releases.
// e.g. if one migration uses "User" model, it works in the early releases, then one day,
// when the User model changes, the migration breaks because it will use the new (incorrect) User model,
// it should only use the old User model. The same to "modules/structs".
// However, many the existing migrations already abuses "modules/structs" (search "gitea.dev/models/" in the migrations).
// TODO: need to fully decouple the migration package and models & structs package
type (
EngineMigration = db.EngineMigration
Session = db.Session
@@ -519,3 +514,7 @@ func ModifyColumn(x EngineMigration, tableName string, col *schemas.Column) erro
}
return nil
}
func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
return db.Iterate(ctx, cond, f)
}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package base
import (
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/git/gitcmd"
)
func LocalCodeGitRepo(ownerName, repoName string) gitcmd.RepositoryFacade {
return repo_model.CodeRepoByName(ownerName, repoName)
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package base
import (
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration
"gitea.dev/modules/git/gitrepo"
)
// HINT: MIGRATION-STRUCT-FROZEN: the structs used in migrations should not be affected by the changes happen in the future,
// because the details can be different in different releases.
// e.g. if one migration uses "User" model, it works in the early releases,
// then one day, when the User model changes, the existing migration will break because it will use the new (incorrect) User model,
// it should only use the old User model.
//
// Related: "models", "modules/structs", git repo directory layout on the disk, etc.
//
// If changes happen, the old migrations need to use a snapshot struct/function (copy the code and freeze)
type ResourceIndex = db.ResourceIndex
func LocalCodeGitRepo(ownerName, repoName string) gitrepo.RepositoryFacade {
return gitrepo.CodeRepoByName(ownerName, repoName)
}
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"testing"
"gitea.dev/modelmigration/base"
"gitea.dev/models/db"
"gitea.dev/models/unittest"
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration tests
"gitea.dev/models/unittest" //nolint:depguard // allow to access db in migration tests
"gitea.dev/modules/git"
"gitea.dev/modules/setting"
"gitea.dev/modules/testlogger"
+1 -1
View File
@@ -5,7 +5,7 @@ package v1_17
import (
"gitea.dev/modelmigration/base"
packages_model "gitea.dev/models/packages"
packages_model "gitea.dev/models/packages" //nolint:depguard // only consts are used
container_module "gitea.dev/modules/packages/container"
"xorm.io/xorm/schemas"
+11 -2
View File
@@ -7,7 +7,7 @@ import (
"fmt"
"gitea.dev/modelmigration/base"
"gitea.dev/models/issues"
"gitea.dev/modules/timeutil"
"xorm.io/builder"
)
@@ -19,6 +19,15 @@ func UpdateOpenMilestoneCounts(x base.EngineMigration) error {
return fmt.Errorf("error selecting open milestone IDs: %w", err)
}
type Milestone struct {
ID int64
IsClosed bool
NumIssues int
NumClosedIssues int
Completeness int
UpdatedUnix timeutil.TimeStamp
}
for _, id := range openMilestoneIDs {
_, err := x.ID(id).
Cols("num_issues", "num_closed_issues").
@@ -31,7 +40,7 @@ func UpdateOpenMilestoneCounts(x base.EngineMigration) error {
"is_closed": true,
},
)).
Update(&issues.Milestone{})
Update(&Milestone{})
if err != nil {
return fmt.Errorf("error updating issue counts in milestone %d: %w", id, err)
}
+22 -4
View File
@@ -7,16 +7,34 @@ import (
"testing"
"gitea.dev/modelmigration/migrationtest"
"gitea.dev/models/issues"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
)
func Test_UpdateOpenMilestoneCounts(t *testing.T) {
type ExpectedMilestone issues.Milestone
type Issue struct {
ID int64
RepoID int64
Index int64
MilestoneID int64
IsClosed bool
UpdatedUnix timeutil.TimeStamp
}
type Milestone struct {
ID int64
IsClosed bool
NumIssues int
NumClosedIssues int
Completeness int
UpdatedUnix timeutil.TimeStamp
}
type ExpectedMilestone Milestone
// Prepare and load the testing database
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(issues.Milestone), new(ExpectedMilestone), new(issues.Issue))
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(Milestone), new(ExpectedMilestone), new(Issue))
defer deferable()
if x == nil || t.Failed() {
return
@@ -32,7 +50,7 @@ func Test_UpdateOpenMilestoneCounts(t *testing.T) {
return
}
got := []issues.Milestone{}
got := []Milestone{}
if err := x.Table("milestone").Asc("id").Find(&got); !assert.NoError(t, err) {
return
}
+1 -2
View File
@@ -5,7 +5,6 @@ package v1_19
import (
"gitea.dev/modelmigration/base"
"gitea.dev/models/db"
"gitea.dev/modules/timeutil"
)
@@ -96,7 +95,7 @@ func AddActionsTables(x base.EngineMigration) error {
NumClosedActionRuns int `xorm:"NOT NULL DEFAULT 0"`
}
type ActionRunIndex db.ResourceIndex
type ActionRunIndex base.ResourceIndex
type ActionTask struct {
ID int64
+1 -2
View File
@@ -8,7 +8,6 @@ import (
"errors"
"gitea.dev/modelmigration/base"
"gitea.dev/models/db"
"gitea.dev/modules/timeutil"
)
@@ -60,7 +59,7 @@ func AddBranchTable(x base.EngineMigration) error {
}
branches := make([]Branch, 0, 100)
if err := db.Iterate(context.Background(), nil, func(ctx context.Context, deletedBranch *DeletedBranch) error {
if err := base.Iterate(context.Background(), nil, func(ctx context.Context, deletedBranch *DeletedBranch) error {
branches = append(branches, Branch{
RepoID: deletedBranch.RepoID,
Name: deletedBranch.Name,
+19 -15
View File
@@ -9,6 +9,24 @@ import (
"gitea.dev/modules/timeutil"
)
type ProjectBoardV293 struct {
ID int64 `xorm:"pk autoincr"`
Title string
Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board
Sorting int8 `xorm:"NOT NULL DEFAULT 0"`
Color string `xorm:"VARCHAR(7)"`
ProjectID int64 `xorm:"INDEX NOT NULL"`
CreatorID int64 `xorm:"NOT NULL"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}
func (ProjectBoardV293) TableName() string {
return "project_board"
}
// CheckProjectColumnsConsistency ensures there is exactly one default board per project present
func CheckProjectColumnsConsistency(x base.EngineMigration) error {
sess := x.NewSession()
@@ -25,20 +43,6 @@ func CheckProjectColumnsConsistency(x base.EngineMigration) error {
BoardID int64
}
type ProjectBoard struct {
ID int64 `xorm:"pk autoincr"`
Title string
Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board
Sorting int8 `xorm:"NOT NULL DEFAULT 0"`
Color string `xorm:"VARCHAR(7)"`
ProjectID int64 `xorm:"INDEX NOT NULL"`
CreatorID int64 `xorm:"NOT NULL"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}
for {
if err := sess.Begin(); err != nil {
return err
@@ -56,7 +60,7 @@ func CheckProjectColumnsConsistency(x base.EngineMigration) error {
}
for _, p := range projects {
if _, err := sess.Insert(ProjectBoard{
if _, err := sess.Insert(ProjectBoardV293{
ProjectID: p.ID,
Default: true,
Title: "Uncategorized",
+26 -6
View File
@@ -7,14 +7,30 @@ import (
"testing"
"gitea.dev/modelmigration/migrationtest"
"gitea.dev/models/project"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
)
func Test_CheckProjectColumnsConsistency(t *testing.T) {
// Prepare and load the testing database
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(project.Project), new(project.Column))
type Project struct {
ID int64
Title string
Description string
OwnerID int64
RepoID int64
CreatorID int64
IsClosed bool
TemplateType uint8
BoardType uint8
Type uint8
CreatedUnix timeutil.TimeStamp
UpdatedUnix timeutil.TimeStamp
ClosedDateUnix timeutil.TimeStamp
}
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(Project), new(ProjectBoardV293))
defer deferable()
if x == nil || t.Failed() {
return
@@ -23,7 +39,7 @@ func Test_CheckProjectColumnsConsistency(t *testing.T) {
assert.NoError(t, CheckProjectColumnsConsistency(x))
// check if default column was added
var defaultColumn project.Column
var defaultColumn ProjectBoardV293
has, err := x.Where("project_id=? AND `default` = ?", 1, true).Get(&defaultColumn)
assert.NoError(t, err)
assert.True(t, has)
@@ -31,13 +47,17 @@ func Test_CheckProjectColumnsConsistency(t *testing.T) {
assert.True(t, defaultColumn.Default)
// check if multiple defaults, previous were removed and last will be kept
expectDefaultColumn, err := project.GetColumn(t.Context(), 2)
var expectDefaultColumn ProjectBoardV293
has, err = x.ID(2).Get(&expectDefaultColumn)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, int64(2), expectDefaultColumn.ProjectID)
assert.False(t, expectDefaultColumn.Default)
expectNonDefaultColumn, err := project.GetColumn(t.Context(), 3)
var expectNonDefaultColumn ProjectBoardV293
has, err = x.ID(3).Get(&expectNonDefaultColumn)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, int64(2), expectNonDefaultColumn.ProjectID)
assert.True(t, expectNonDefaultColumn.Default)
}
+1 -2
View File
@@ -5,7 +5,6 @@ package v1_27
import (
"gitea.dev/modelmigration/base"
"gitea.dev/models/db"
"xorm.io/xorm"
)
@@ -25,7 +24,7 @@ func AddReusableWorkflowFieldsToActionRunJob(x base.EngineMigration) error {
ReusableWorkflowContent []byte `xorm:"LONGBLOB"`
}
type ActionRunAttemptJobIDIndex db.ResourceIndex
type ActionRunAttemptJobIDIndex base.ResourceIndex
if _, err := x.SyncWithOptions(xorm.SyncOptions{IgnoreDropIndices: true}, new(ActionRunJob)); err != nil {
return err
+8 -27
View File
@@ -5,42 +5,23 @@ package repo
import (
"strconv"
"strings"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
func repoCodeGitRepoRelativePath(ownerName, repoName string) string {
return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".git"
}
func repoWikiGitRepoRelativePath(ownerName, repoName string) string {
return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".wiki.git"
}
// CodeRepoByName returns an unmanaged repository facade for the code repository of the given owner and repository name.
// Usually it is used for migration fixes or repository adoption/creation/rename/transfer.
func CodeRepoByName(ownerName, repoName string) gitcmd.RepositoryFacade {
return gitcmd.RepositoryUnmanaged(repoCodeGitRepoRelativePath(ownerName, repoName))
}
func WikiRepoByName(ownerName, repoName string) gitcmd.RepositoryFacade {
return gitcmd.RepositoryUnmanaged(repoWikiGitRepoRelativePath(ownerName, repoName))
}
func repoCodeGitRepoManagedID(repoID int64) string {
return "repo-" + strconv.FormatInt(repoID, 10)
}
func (repo *Repository) CodeStorageRepo() gitcmd.RepositoryFacade {
func (repo *Repository) CodeStorageRepo() gitrepo.RepositoryFacade {
id := repoCodeGitRepoManagedID(repo.ID)
repoPath := repoCodeGitRepoRelativePath(repo.OwnerName, repo.Name)
return gitcmd.RepositoryManaged(id, repoPath)
repoPath := gitrepo.RepoCodeGitRepoRelativePath(repo.OwnerName, repo.Name)
return gitrepo.RepositoryManaged(id, repoPath)
}
func (repo *Repository) GitRepoLocation() string {
// TODO: use CodeGitRepo instead of this one
return repoCodeGitRepoRelativePath(repo.OwnerName, repo.Name)
return gitrepo.RepoCodeGitRepoRelativePath(repo.OwnerName, repo.Name)
}
func (repo *Repository) GitRepoManagedID() string {
@@ -48,9 +29,9 @@ func (repo *Repository) GitRepoManagedID() string {
return repoCodeGitRepoManagedID(repo.ID)
}
func (repo *Repository) WikiStorageRepo() gitcmd.RepositoryFacade {
func (repo *Repository) WikiStorageRepo() gitrepo.RepositoryFacade {
// The wiki repository should have the same object format as the code repository. TODO: old comment, REALLY? Why?
id := "repo-wiki-" + strconv.FormatInt(repo.ID, 10)
repoPath := repoWikiGitRepoRelativePath(repo.OwnerName, repo.Name)
return gitcmd.RepositoryManaged(id, repoPath)
repoPath := gitrepo.RepoWikiGitRepoRelativePath(repo.OwnerName, repo.Name)
return gitrepo.RepositoryManaged(id, repoPath)
}
+3 -2
View File
@@ -8,6 +8,7 @@ import (
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
"gitea.dev/modules/git/gitrepo"
"github.com/stretchr/testify/assert"
)
@@ -16,11 +17,11 @@ func TestRepository_GitRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.Equal(t, "user2/repo1.git", repo_model.CodeRepoByName(repo.OwnerName, repo.Name).GitRepoLocation())
assert.Equal(t, "user2/repo1.git", gitrepo.CodeRepoByName(repo.OwnerName, repo.Name).GitRepoLocation())
assert.Equal(t, "user2/repo1.git", repo.CodeStorageRepo().GitRepoLocation())
assert.Equal(t, "repo-1", repo.CodeStorageRepo().GitRepoManagedID())
assert.Equal(t, "user2/repo1.wiki.git", repo_model.WikiRepoByName(repo.OwnerName, repo.Name).GitRepoLocation())
assert.Equal(t, "user2/repo1.wiki.git", gitrepo.WikiRepoByName(repo.OwnerName, repo.Name).GitRepoLocation())
assert.Equal(t, "user2/repo1.wiki.git", repo.WikiStorageRepo().GitRepoLocation())
assert.Equal(t, "repo-wiki-1", repo.WikiStorageRepo().GitRepoManagedID())
}
+2 -1
View File
@@ -13,6 +13,7 @@ import (
"strings"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
)
@@ -48,7 +49,7 @@ func CreateBundle(ctx context.Context, repo RepositoryFacade, commit string, out
}
defer cleanup()
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(gitcmd.RepoLocalPath(repo), "objects"))
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(gitrepo.RepoLocalPath(repo), "objects"))
gitTmpCmd := func() *gitcmd.Command {
return gitcmd.NewCommand().WithDir(tmpDir).WithEnv(env)
}
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"io"
"os"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/util"
)
@@ -50,7 +50,7 @@ type CatFileBatchCloser interface {
// NewBatch creates a "batch object provider (CatFileBatch)" for the given repository path to retrieve object info and content efficiently.
// The CatFileBatch and the readers create by it should only be used in the same goroutine.
func NewBatch(ctx context.Context, repo RepositoryFacade) (CatFileBatchCloser, error) {
repoPath := gitcmd.RepoLocalPath(repo)
repoPath := gitrepo.RepoLocalPath(repo)
if _, err := os.Stat(repoPath); err != nil {
return nil, util.NewNotExistErrorf("repo %q doesn't exist", repo.LogString())
}
+3 -3
View File
@@ -9,7 +9,7 @@ import (
"path/filepath"
"testing"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/test"
"github.com/stretchr/testify/assert"
@@ -26,10 +26,10 @@ func TestCatFileBatch(t *testing.T) {
func testCatFileBatch(t *testing.T) {
repo1Path, _ := filepath.Abs(filepath.Join(testReposDir, "repo1_bare"))
repo1 := gitcmd.RepositoryUnmanaged(repo1Path)
repo1 := gitrepo.RepositoryUnmanaged(repo1Path)
t.Run("CorruptedGitRepo", func(t *testing.T) {
tmpDir := t.TempDir()
batch, err := NewBatch(t.Context(), gitcmd.RepositoryUnmanaged(tmpDir))
batch, err := NewBatch(t.Context(), gitrepo.RepositoryUnmanaged(tmpDir))
// as long as the directory exists, no error, because we can't really know whether the git repo is valid until we run commands
require.NoError(t, err)
defer batch.Close()
+4 -4
View File
@@ -6,19 +6,19 @@ package git
import (
"context"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
// CloneExternalRepo clones an external repository to the managed repository.
func CloneExternalRepo(ctx context.Context, fromRemoteURL string, toRepo RepositoryFacade, opts CloneRepoOptions) error {
return Clone(ctx, fromRemoteURL, gitcmd.RepoLocalPath(toRepo), opts)
return Clone(ctx, fromRemoteURL, gitrepo.RepoLocalPath(toRepo), opts)
}
// CloneRepoToLocal clones a managed repository to a local path.
func CloneRepoToLocal(ctx context.Context, fromRepo RepositoryFacade, toLocalPath string, opts CloneRepoOptions) error {
return Clone(ctx, gitcmd.RepoLocalPath(fromRepo), toLocalPath, opts)
return Clone(ctx, gitrepo.RepoLocalPath(fromRepo), toLocalPath, opts)
}
func CloneManaged(ctx context.Context, fromRepo, toRepo RepositoryFacade, opts CloneRepoOptions) error {
return Clone(ctx, gitcmd.RepoLocalPath(fromRepo), gitcmd.RepoLocalPath(toRepo), opts)
return Clone(ctx, gitrepo.RepoLocalPath(fromRepo), gitrepo.RepoLocalPath(toRepo), opts)
}
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"context"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
// FetchRemoteCommit fetches a specific commit and its related objects from a remote
@@ -21,7 +22,7 @@ import (
func FetchRemoteCommit(ctx context.Context, repo, remoteRepo RepositoryFacade, commitID string) error {
return LockWriteAndDo(ctx, repo, func(ctx context.Context) error {
return gitcmd.NewCommand("fetch", "--no-tags").
AddDynamicArguments(gitcmd.RepoLocalPath(remoteRepo)).
AddDynamicArguments(gitrepo.RepoLocalPath(remoteRepo)).
AddDynamicArguments(commitID).
WithRepo(repo).Run(ctx)
})
+6
View File
@@ -16,6 +16,7 @@ import (
"strings"
"time"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/git/internal" //nolint:depguard // only this file can use the internal type CmdArg, other files and packages should use AddXxx functions
"gitea.dev/modules/gtprof"
"gitea.dev/modules/log"
@@ -261,6 +262,11 @@ func (c *Command) WithDir(dir string) *Command {
return c
}
func (c *Command) WithRepo(repo gitrepo.RepositoryFacade) *Command {
c.gitDir = gitrepo.RepoLocalPath(repo)
return c
}
func (c *Command) WithEnv(env []string) *Command {
c.cmdEnv = env
return c
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package gitrepo
import "strings"
func RepoCodeGitRepoRelativePath(ownerName, repoName string) string {
return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".git"
}
func RepoWikiGitRepoRelativePath(ownerName, repoName string) string {
return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".wiki.git"
}
// CodeRepoByName returns an unmanaged repository facade for the code repository of the given owner and repository name.
// Usually it is used for migration fixes or repository adoption/creation/rename/transfer.
func CodeRepoByName(ownerName, repoName string) RepositoryFacade {
return RepositoryUnmanaged(RepoCodeGitRepoRelativePath(ownerName, repoName))
}
func WikiRepoByName(ownerName, repoName string) RepositoryFacade {
return RepositoryUnmanaged(RepoWikiGitRepoRelativePath(ownerName, repoName))
}
@@ -1,7 +1,7 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package gitcmd
package gitrepo
import (
"path/filepath"
@@ -24,11 +24,6 @@ type RepositoryFacade interface {
LogString() string
}
func (c *Command) WithRepo(repo RepositoryFacade) *Command {
c.gitDir = RepoLocalPath(repo)
return c
}
// RepoLocalPath returns an absolute path for a RepositoryFacade.
// TODO: most of the calls to this function should be replaced with a "Repo FS" in the future
// to handle file accesses in the git repo (e.g.: read, write, list, remove).
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"path/filepath"
"testing"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
"gitea.dev/modules/test"
@@ -79,7 +79,7 @@ func TestGrepSearch(t *testing.T) {
assert.NoError(t, err)
assert.Empty(t, res)
nonExistingRepo := &Repository{RepositoryBase: RepositoryBase{repoFacade: gitcmd.RepositoryUnmanaged("no-such-git-repo")}}
nonExistingRepo := &Repository{RepositoryBase: RepositoryBase{repoFacade: gitrepo.RepositoryUnmanaged("no-such-git-repo")}}
res, err = GrepSearch(t.Context(), nonExistingRepo, "no-such-content", GrepOptions{})
assert.Error(t, err)
assert.Empty(t, res)
+3 -3
View File
@@ -11,7 +11,7 @@ import (
"slices"
"strings"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/util"
)
@@ -41,7 +41,7 @@ type Hook struct {
// GetHook returns a Git hook by given name and repository.
func GetHook(repo RepositoryFacade, name string) (*Hook, error) {
repoPath := gitcmd.RepoLocalPath(repo)
repoPath := gitrepo.RepoLocalPath(repo)
if !IsValidHookName(name) {
return nil, ErrNotValidHook
}
@@ -100,7 +100,7 @@ func (h *Hook) Update() error {
// ListHooks returns a list of Git hooks of given repository.
func ListHooks(repo RepositoryFacade) (_ []*Hook, err error) {
exist, err := util.IsDir(filepath.Join(gitcmd.RepoLocalPath(repo), "hooks"))
exist, err := util.IsDir(filepath.Join(gitrepo.RepoLocalPath(repo), "hooks"))
if err != nil {
return nil, err
} else if !exist {
+3 -3
View File
@@ -10,7 +10,7 @@ import (
"path/filepath"
"runtime"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
"gitea.dev/modules/util"
)
@@ -109,7 +109,7 @@ done
// CreateDelegateHooks creates all the hooks scripts for the repo
func CreateDelegateHooks(_ context.Context, repo RepositoryFacade) (err error) {
return createDelegateHooks(filepath.Join(gitcmd.RepoLocalPath(repo), "hooks"))
return createDelegateHooks(filepath.Join(gitrepo.RepoLocalPath(repo), "hooks"))
}
func createDelegateHooks(hookDir string) (err error) {
@@ -176,7 +176,7 @@ func ensureExecutable(filename string) error {
// CheckDelegateHooks checks the hooks scripts for the repo
func CheckDelegateHooks(_ context.Context, repo RepositoryFacade) ([]string, error) {
return checkDelegateHooks(filepath.Join(gitcmd.RepoLocalPath(repo), "hooks"))
return checkDelegateHooks(filepath.Join(gitrepo.RepoLocalPath(repo), "hooks"))
}
func checkDelegateHooks(hookDir string) ([]string, error) {
+11 -11
View File
@@ -11,59 +11,59 @@ import (
"os"
"path/filepath"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/util"
)
// IsRepositoryExist returns true if the repository directory exists in the disk
func IsRepositoryExist(ctx context.Context, repo RepositoryFacade) (bool, error) {
return util.IsExist(gitcmd.RepoLocalPath(repo))
return util.IsExist(gitrepo.RepoLocalPath(repo))
}
// DeleteRepository deletes the repository directory from the disk, it will return
// nil if the repository does not exist.
func DeleteRepository(ctx context.Context, repo RepositoryFacade) error {
return util.RemoveAll(gitcmd.RepoLocalPath(repo))
return util.RemoveAll(gitrepo.RepoLocalPath(repo))
}
// RenameRepository renames a repository's name on disk
func RenameRepository(ctx context.Context, repo, newRepo RepositoryFacade) error {
dstDir := gitcmd.RepoLocalPath(newRepo)
dstDir := gitrepo.RepoLocalPath(newRepo)
if err := os.MkdirAll(filepath.Dir(dstDir), os.ModePerm); err != nil {
return fmt.Errorf("Failed to create dir %s: %w", filepath.Dir(dstDir), err)
}
if err := util.Rename(gitcmd.RepoLocalPath(repo), dstDir); err != nil {
if err := util.Rename(gitrepo.RepoLocalPath(repo), dstDir); err != nil {
return fmt.Errorf("rename repository directory: %w", err)
}
return nil
}
func InitRepository(ctx context.Context, repo RepositoryFacade, objectFormatName string) error {
return InitRepositoryLocal(ctx, gitcmd.RepoLocalPath(repo), true, objectFormatName)
return InitRepositoryLocal(ctx, gitrepo.RepoLocalPath(repo), true, objectFormatName)
}
func GetRepoFS(repo RepositoryFacade) fs.FS {
return os.DirFS(gitcmd.RepoLocalPath(repo))
return os.DirFS(gitrepo.RepoLocalPath(repo))
}
func IsRepoFileExist(ctx context.Context, repo RepositoryFacade, relativeFilePath string) (bool, error) {
absoluteFilePath := filepath.Join(gitcmd.RepoLocalPath(repo), relativeFilePath)
absoluteFilePath := filepath.Join(gitrepo.RepoLocalPath(repo), relativeFilePath)
return util.IsExist(absoluteFilePath)
}
func IsRepoDirExist(ctx context.Context, repo RepositoryFacade, relativeDirPath string) (bool, error) {
absoluteDirPath := filepath.Join(gitcmd.RepoLocalPath(repo), relativeDirPath)
absoluteDirPath := filepath.Join(gitrepo.RepoLocalPath(repo), relativeDirPath)
return util.IsDir(absoluteDirPath)
}
func RemoveRepoFileOrDir(ctx context.Context, repo RepositoryFacade, relativeFileOrDirPath string) error {
absoluteFilePath := filepath.Join(gitcmd.RepoLocalPath(repo), relativeFileOrDirPath)
absoluteFilePath := filepath.Join(gitrepo.RepoLocalPath(repo), relativeFileOrDirPath)
return util.Remove(absoluteFilePath)
}
func CreateRepoFile(ctx context.Context, repo RepositoryFacade, relativeFilePath string) (io.WriteCloser, error) {
absoluteFilePath := filepath.Join(gitcmd.RepoLocalPath(repo), relativeFilePath)
absoluteFilePath := filepath.Join(gitrepo.RepoLocalPath(repo), relativeFilePath)
if err := os.MkdirAll(filepath.Dir(absoluteFilePath), os.ModePerm); err != nil {
return nil, err
}
+3 -3
View File
@@ -7,17 +7,17 @@ import (
"path/filepath"
"testing"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
const testReposDir = "tests/repos/"
func mockRepository(repoPath string) gitcmd.RepositoryFacade {
func mockRepository(repoPath string) RepositoryFacade {
if !filepath.IsAbs(repoPath) {
// resolve repository path relative to the unit test fixture directory
repoPath, _ = filepath.Abs(filepath.Join(testReposDir, repoPath))
}
return gitcmd.RepositoryUnmanaged(repoPath)
return gitrepo.RepositoryUnmanaged(repoPath)
}
func TestMain(m *testing.M) {
+5 -5
View File
@@ -6,22 +6,22 @@ package git
import (
"context"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
// PushToExternal pushes a managed repository to an external remote.
func PushToExternal(ctx context.Context, repo RepositoryFacade, opts PushOptions) error {
return Push(ctx, gitcmd.RepoLocalPath(repo), opts)
return Push(ctx, gitrepo.RepoLocalPath(repo), opts)
}
// PushManaged pushes from one managed repository to another managed repository.
func PushManaged(ctx context.Context, fromRepo, toRepo RepositoryFacade, opts PushOptions) error {
opts.Remote = gitcmd.RepoLocalPath(toRepo)
return Push(ctx, gitcmd.RepoLocalPath(fromRepo), opts)
opts.Remote = gitrepo.RepoLocalPath(toRepo)
return Push(ctx, gitrepo.RepoLocalPath(fromRepo), opts)
}
// PushFromLocal pushes from a local path to a managed repository.
func PushFromLocal(ctx context.Context, fromLocalPath string, toRepo RepositoryFacade, opts PushOptions) error {
opts.Remote = gitcmd.RepoLocalPath(toRepo)
opts.Remote = gitrepo.RepoLocalPath(toRepo)
return Push(ctx, fromLocalPath, opts)
}
+6 -5
View File
@@ -17,12 +17,13 @@ import (
"time"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/proxy"
"gitea.dev/modules/setting"
"gitea.dev/modules/util"
)
type RepositoryFacade = gitcmd.RepositoryFacade
type RepositoryFacade = gitrepo.RepositoryFacade
type RepositoryBase struct {
LastCommitCache *LastCommitCache
@@ -36,7 +37,7 @@ type RepositoryBase struct {
catFileBatchInUse bool
}
var _ gitcmd.RepositoryFacade = (*Repository)(nil)
var _ RepositoryFacade = (*Repository)(nil)
func (repo *Repository) GitRepoManagedID() string {
return repo.repoFacade.GitRepoManagedID()
@@ -51,7 +52,7 @@ func (repo *Repository) LogString() string {
}
func OpenRepository(repo RepositoryFacade) (*Repository, error) {
repoPath := gitcmd.RepoLocalPath(repo)
repoPath := gitrepo.RepoLocalPath(repo)
exist, err := util.IsDir(repoPath)
if err != nil {
return nil, err
@@ -77,7 +78,7 @@ func OpenRepositoryLocal(localPath string) (_ *Repository, err error) {
return nil, err
}
}
return OpenRepository(gitcmd.RepositoryUnmanaged(localPath))
return OpenRepository(gitrepo.RepositoryUnmanaged(localPath))
}
func (repo *Repository) Close() error {
@@ -130,7 +131,7 @@ func InitRepositoryLocal(ctx context.Context, localRepoPath string, bare bool, o
// IsEmpty Check if repository is empty.
func (repo *Repository) IsEmpty(ctx context.Context) (bool, error) {
stdout, _, err := gitcmd.NewCommand().
AddOptionFormat("--git-dir=%s", gitcmd.RepoLocalPath(repo)). // TODO: all git commands should use "--git-dir" or "GIT_DIR=..."
AddOptionFormat("--git-dir=%s", gitrepo.RepoLocalPath(repo)). // TODO: all git commands should use "--git-dir" or "GIT_DIR=..."
AddArguments("rev-list", "-n", "1", "--all").
WithRepo(repo).
RunStdString(ctx)
+2 -2
View File
@@ -9,7 +9,7 @@ package git
import (
"path/filepath"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
"github.com/go-git/go-billy/v5"
@@ -30,7 +30,7 @@ type Repository struct {
}
func openRepositoryInternal(gitRepo *Repository) error {
repoPath := gitcmd.RepoLocalPath(gitRepo)
repoPath := gitrepo.RepoLocalPath(gitRepo)
fs := osfs.New(repoPath)
_, err := fs.Stat(".git")
if err == nil {
+2 -2
View File
@@ -10,7 +10,7 @@ import (
"os"
"path/filepath"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/log"
commitgraph "github.com/go-git/go-git/v5/plumbing/format/commitgraph/v2"
@@ -19,7 +19,7 @@ import (
// CommitNodeIndex returns the index for walking commit graph
func (repo *Repository) CommitNodeIndex() (_ cgobject.CommitNodeIndex, closer func()) {
indexPath := filepath.Join(gitcmd.RepoLocalPath(repo), "objects", "info", "commit-graph")
indexPath := filepath.Join(gitrepo.RepoLocalPath(repo), "objects", "info", "commit-graph")
file, err := os.Open(indexPath)
if err == nil {
var index commitgraph.Index
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"os"
"path/filepath"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
)
const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular
@@ -15,7 +15,7 @@ const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | o
// CalcRepositorySize returns the disk consumption for a given path
func CalcRepositorySize(repo RepositoryFacade) (int64, error) {
var size int64
err := filepath.WalkDir(gitcmd.RepoLocalPath(repo), func(_ string, entry os.DirEntry, err error) error {
err := filepath.WalkDir(gitrepo.RepoLocalPath(repo), func(_ string, entry os.DirEntry, err error) error {
if os.IsNotExist(err) { // ignore the error because some files (like temp/lock file) may be deleted during traversing.
return nil
} else if err != nil {
+1 -1
View File
@@ -19,7 +19,7 @@ type TemplateSubmoduleCommit struct {
// GetTemplateSubmoduleCommits returns a list of submodules paths and their commits from a repository
// This function is only for generating new repos based on existing template, the template couldn't be too large.
func GetTemplateSubmoduleCommits(ctx context.Context, repo gitcmd.RepositoryFacade) (submoduleCommits []TemplateSubmoduleCommit, _ error) {
func GetTemplateSubmoduleCommits(ctx context.Context, repo RepositoryFacade) (submoduleCommits []TemplateSubmoduleCommit, _ error) {
cmd := gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD")
stdoutReader, stdoutReaderClose := cmd.MakeStdoutPipe()
defer stdoutReaderClose()
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"fmt"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
)
@@ -19,6 +19,6 @@ func CreateTemporaryGitRepo(prefix string) (tmpPath string, tmpRepo git.Reposito
if err != nil {
return "", nil, nil, fmt.Errorf("failed to create temp dir with prefix %s: %w", tmpNamePrefix, err)
}
tmpRepo = gitcmd.RepositoryUnmanaged(tmpPath)
tmpRepo = gitrepo.RepositoryUnmanaged(tmpPath)
return tmpPath, tmpRepo, cancel, nil
}
+3 -2
View File
@@ -9,6 +9,7 @@ import (
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/routers/api/v1/utils"
"gitea.dev/services/context"
repo_service "gitea.dev/services/repository"
@@ -99,7 +100,7 @@ func AdoptRepository(ctx *context.APIContext) {
ctx.APIErrorInternal(err)
return
}
exist, err := git.IsRepositoryExist(ctx, repo_model.CodeRepoByName(ctxUser.Name, repoName))
exist, err := git.IsRepositoryExist(ctx, gitrepo.CodeRepoByName(ctxUser.Name, repoName))
if err != nil {
ctx.APIErrorInternal(err)
return
@@ -161,7 +162,7 @@ func DeleteUnadoptedRepository(ctx *context.APIContext) {
ctx.APIErrorInternal(err)
return
}
exist, err := git.IsRepositoryExist(ctx, repo_model.CodeRepoByName(ctxUser.Name, repoName))
exist, err := git.IsRepositoryExist(ctx, gitrepo.CodeRepoByName(ctxUser.Name, repoName))
if err != nil {
ctx.APIErrorInternal(err)
return
+2 -2
View File
@@ -14,7 +14,7 @@ import (
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/log"
"gitea.dev/modules/private"
"gitea.dev/modules/setting"
@@ -320,7 +320,7 @@ func ServCommand(ctx *context.PrivateContext) {
}
gitRepo := util.Iif(results.IsWiki, repo.WikiStorageRepo(), repo.CodeStorageRepo())
results.RepoStoragePath = gitcmd.RepoLocalPath(gitRepo)
results.RepoStoragePath = gitrepo.RepoLocalPath(gitRepo)
log.Debug("Serv Results: %+v", results)
ctx.JSON(http.StatusOK, results)
// We will update the keys in a different call.
+2 -1
View File
@@ -12,6 +12,7 @@ import (
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
"gitea.dev/modules/templates"
@@ -134,7 +135,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
ctx.ServerError("IsRepositoryExist", err)
return
}
exist, err := git.IsRepositoryExist(ctx, repo_model.CodeRepoByName(ctxUser.Name, repoName))
exist, err := git.IsRepositoryExist(ctx, gitrepo.CodeRepoByName(ctxUser.Name, repoName))
if err != nil {
ctx.ServerError("IsDir", err)
return
+2 -1
View File
@@ -6,6 +6,7 @@ package setting
import (
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/setting"
"gitea.dev/services/context"
repo_service "gitea.dev/services/repository"
@@ -32,7 +33,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
return
}
exist, err := git.IsRepositoryExist(ctx, repo_model.CodeRepoByName(ctxUser.Name, dir))
exist, err := git.IsRepositoryExist(ctx, gitrepo.CodeRepoByName(ctxUser.Name, dir))
if err != nil {
ctx.ServerError("IsDir", err)
return
+3 -2
View File
@@ -18,6 +18,7 @@ import (
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/log"
base "gitea.dev/modules/migration"
"gitea.dev/modules/repository"
@@ -161,7 +162,7 @@ func (g *RepositoryDumper) CreateRepo(ctx context.Context, repo *base.Repository
return fmt.Errorf("clone code: %w", err)
}
repoLocal := gitcmd.RepositoryUnmanaged(repoAbsPath)
repoLocal := gitrepo.RepositoryUnmanaged(repoAbsPath)
if err := git.WriteCommitGraph(ctx, repoLocal); err != nil {
return err
}
@@ -176,7 +177,7 @@ func (g *RepositoryDumper) CreateRepo(ctx context.Context, repo *base.Repository
if err := os.MkdirAll(wikiAbsPath, os.ModePerm); err != nil {
return fmt.Errorf("failed to create %s: %w", wikiAbsPath, err)
}
wikiLocal := gitcmd.RepositoryUnmanaged(wikiAbsPath)
wikiLocal := gitrepo.RepositoryUnmanaged(wikiAbsPath)
if err := git.Clone(ctx, wikiRemotePath, wikiAbsPath, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
+2 -1
View File
@@ -17,6 +17,7 @@ import (
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/glob"
"gitea.dev/modules/graceful"
"gitea.dev/modules/log"
@@ -213,7 +214,7 @@ func DeleteUnadoptedRepository(ctx context.Context, doer, u *user_model.User, re
return err
}
codeRepo := repo_model.CodeRepoByName(u.Name, repoName)
codeRepo := gitrepo.CodeRepoByName(u.Name, repoName)
exist, err := git.IsRepositoryExist(ctx, codeRepo)
if err != nil {
log.Error("Unable to check if repo %s/%s exists. Error: %v", u.Name, repoName, err)
+2 -1
View File
@@ -19,6 +19,7 @@ import (
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
git2 "gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/graceful"
issue_indexer "gitea.dev/modules/indexer/issues"
"gitea.dev/modules/log"
@@ -331,7 +332,7 @@ func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, na
} else if has {
return repo_model.ErrRepoAlreadyExist{Uname: owner.Name, Name: name}
}
repo := repo_model.CodeRepoByName(owner.Name, name)
repo := gitrepo.CodeRepoByName(owner.Name, name)
isExist, err := git2.IsRepositoryExist(ctx, repo)
if err != nil {
log.Error("Unable to check if repo %s/%s exists, error: %v", owner.Name, name, err)
+12 -11
View File
@@ -18,6 +18,7 @@ import (
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/globallock"
"gitea.dev/modules/log"
"gitea.dev/modules/util"
@@ -94,7 +95,7 @@ func isRepositoryModelOrDirExist(ctx context.Context, u *user_model.User, repoNa
if err != nil {
return false, err
}
repo := repo_model.CodeRepoByName(u.Name, repoName)
repo := gitrepo.CodeRepoByName(u.Name, repoName)
isExist, err := git.IsRepositoryExist(ctx, repo)
return has || isExist, err
}
@@ -117,16 +118,16 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
if repoRenamed {
// revert the rename
from := repo_model.CodeRepoByName(newOwnerName, repo.Name)
to := repo_model.CodeRepoByName(oldOwnerName, repo.Name)
from := gitrepo.CodeRepoByName(newOwnerName, repo.Name)
to := gitrepo.CodeRepoByName(oldOwnerName, repo.Name)
if err := git.RenameRepository(ctx, from, to); err != nil {
log.Error("Unable to revert repository %s/%s to %s/%s: %v", newOwnerName, repo.Name, oldOwnerName, repo.Name, err)
}
}
if wikiRenamed {
from := repo_model.WikiRepoByName(newOwnerName, repo.Name)
to := repo_model.WikiRepoByName(oldOwnerName, repo.Name)
from := gitrepo.WikiRepoByName(newOwnerName, repo.Name)
to := gitrepo.WikiRepoByName(oldOwnerName, repo.Name)
if err := git.RenameRepository(ctx, from, to); err != nil {
log.Error("Unable to revert wiki repository %s/%s to %s/%s: %v", newOwnerName, repo.Name, oldOwnerName, repo.Name, err)
}
@@ -303,20 +304,20 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
}
// Rename remote repository to new path and delete local copy.
oldCodeRepo := repo_model.CodeRepoByName(oldOwner.Name, repo.Name)
newCodeRepo := repo_model.CodeRepoByName(newOwner.Name, repo.Name)
oldCodeRepo := gitrepo.CodeRepoByName(oldOwner.Name, repo.Name)
newCodeRepo := gitrepo.CodeRepoByName(newOwner.Name, repo.Name)
if err := git.RenameRepository(ctx, oldCodeRepo, newCodeRepo); err != nil {
return fmt.Errorf("rename repository directory: %w", err)
}
repoRenamed = true
// Rename remote wiki repository to new path and delete local copy.
oldWikiRepo := repo_model.WikiRepoByName(oldOwner.Name, repo.Name)
oldWikiRepo := gitrepo.WikiRepoByName(oldOwner.Name, repo.Name)
if isExist, err := git.IsRepositoryExist(ctx, oldWikiRepo); err != nil {
log.Error("Unable to check if wiki of repo %s/%s exists. Error: %v", oldOwner.Name, repo.Name, err)
return err
} else if isExist {
newWikiRepo := repo_model.WikiRepoByName(newOwner.Name, repo.Name)
newWikiRepo := gitrepo.WikiRepoByName(newOwner.Name, repo.Name)
if err := git.RenameRepository(ctx, oldWikiRepo, newWikiRepo); err != nil {
return fmt.Errorf("rename repository wiki: %w", err)
}
@@ -376,13 +377,13 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR
}
}
newCodeRepo := repo_model.CodeRepoByName(repo.OwnerName, newRepoName)
newCodeRepo := gitrepo.CodeRepoByName(repo.OwnerName, newRepoName)
if err = git.RenameRepository(ctx, repo, newCodeRepo); err != nil {
return fmt.Errorf("rename repository directory: %w", err)
}
if HasWiki(ctx, repo) {
newWikiRepo := repo_model.WikiRepoByName(repo.OwnerName, newRepoName)
newWikiRepo := gitrepo.WikiRepoByName(repo.OwnerName, newRepoName)
if err = git.RenameRepository(ctx, repo.WikiStorageRepo(), newWikiRepo); err != nil {
return fmt.Errorf("rename repository wiki: %w", err)
}