Skip to content

Commit e422342

Browse files
authoredApr 19, 2023
1 parent 01214c8 commit e422342

31 files changed

+314
-138
lines changed
 

‎models/db/iterate_test.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ func TestIterate(t *testing.T) {
1919
xe := unittest.GetXORMEngine()
2020
assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
2121

22-
var repoCnt int
23-
err := db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error {
24-
repoCnt++
22+
cnt, err := db.GetEngine(db.DefaultContext).Count(&repo_model.RepoUnit{})
23+
assert.NoError(t, err)
24+
25+
var repoUnitCnt int
26+
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error {
27+
repoUnitCnt++
2528
return nil
2629
})
2730
assert.NoError(t, err)
28-
assert.EqualValues(t, 89, repoCnt)
31+
assert.EqualValues(t, cnt, repoUnitCnt)
2932

3033
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error {
3134
reopUnit2 := repo_model.RepoUnit{ID: repoUnit.ID}

‎models/db/list_test.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,20 @@ func TestFind(t *testing.T) {
3131
xe := unittest.GetXORMEngine()
3232
assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
3333

34+
var repoUnitCount int
35+
_, err := db.GetEngine(db.DefaultContext).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount)
36+
assert.NoError(t, err)
37+
assert.NotEmpty(t, repoUnitCount)
38+
3439
opts := mockListOptions{}
3540
var repoUnits []repo_model.RepoUnit
36-
err := db.Find(db.DefaultContext, &opts, &repoUnits)
41+
err = db.Find(db.DefaultContext, &opts, &repoUnits)
3742
assert.NoError(t, err)
38-
assert.EqualValues(t, 89, len(repoUnits))
43+
assert.EqualValues(t, repoUnitCount, len(repoUnits))
3944

4045
cnt, err := db.Count(db.DefaultContext, &opts, new(repo_model.RepoUnit))
4146
assert.NoError(t, err)
42-
assert.EqualValues(t, 89, cnt)
47+
assert.EqualValues(t, repoUnitCount, cnt)
4348

4449
repoUnits = make([]repo_model.RepoUnit, 0, 10)
4550
newCnt, err := db.FindAndCount(db.DefaultContext, &opts, &repoUnits)

‎models/dbfs/dbfs_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
"code.gitea.io/gitea/models/db"
1313

1414
"github.com/stretchr/testify/assert"
15-
16-
_ "github.com/mattn/go-sqlite3"
1715
)
1816

1917
func changeDefaultFileBlockSize(n int64) (restore func()) {

‎models/fixtures/repo_unit.yml

+6
Original file line numberDiff line numberDiff line change
@@ -601,3 +601,9 @@
601601
repo_id: 57
602602
type: 5
603603
created_unix: 946684810
604+
605+
-
606+
id: 90
607+
repo_id: 52
608+
type: 1
609+
created_unix: 946684810

‎models/fixtures/repository.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,7 @@
15601560
owner_name: user30
15611561
lower_name: empty
15621562
name: empty
1563+
default_branch: master
15631564
num_watches: 0
15641565
num_stars: 0
15651566
num_forks: 0

‎models/fixtures/user.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@
10911091
max_repo_creation: -1
10921092
is_active: true
10931093
is_admin: false
1094-
is_restricted: true
1094+
is_restricted: false
10951095
allow_git_hook: false
10961096
allow_import_local: false
10971097
allow_create_organization: true

‎models/repo/repo.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ func (repo *Repository) IsBroken() bool {
225225
return repo.Status == RepositoryBroken
226226
}
227227

228+
// MarkAsBrokenEmpty marks the repo as broken and empty
229+
func (repo *Repository) MarkAsBrokenEmpty() {
230+
repo.Status = RepositoryBroken
231+
repo.IsEmpty = true
232+
}
233+
228234
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
229235
func (repo *Repository) AfterLoad() {
230236
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
@@ -729,7 +735,7 @@ func IsRepositoryExist(ctx context.Context, u *user_model.User, repoName string)
729735
return false, err
730736
}
731737
isDir, err := util.IsDir(RepoPath(u.Name, repoName))
732-
return has && isDir, err
738+
return has || isDir, err
733739
}
734740

735741
// GetTemplateRepo populates repo.TemplateRepo for a generated repository and

‎models/unittest/fixtures.go

+9-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"xorm.io/xorm/schemas"
1818
)
1919

20-
var fixtures *testfixtures.Loader
20+
var fixturesLoader *testfixtures.Loader
2121

2222
// GetXORMEngine gets the XORM engine
2323
func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) {
@@ -30,11 +30,11 @@ func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) {
3030
// InitFixtures initialize test fixtures for a test database
3131
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
3232
e := GetXORMEngine(engine...)
33-
var testfiles func(*testfixtures.Loader) error
33+
var fixtureOptionFiles func(*testfixtures.Loader) error
3434
if opts.Dir != "" {
35-
testfiles = testfixtures.Directory(opts.Dir)
35+
fixtureOptionFiles = testfixtures.Directory(opts.Dir)
3636
} else {
37-
testfiles = testfixtures.Files(opts.Files...)
37+
fixtureOptionFiles = testfixtures.Files(opts.Files...)
3838
}
3939
dialect := "unknown"
4040
switch e.Dialect().URI().DBType {
@@ -54,14 +54,14 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
5454
testfixtures.Database(e.DB().DB),
5555
testfixtures.Dialect(dialect),
5656
testfixtures.DangerousSkipTestDatabaseCheck(),
57-
testfiles,
57+
fixtureOptionFiles,
5858
}
5959

6060
if e.Dialect().URI().DBType == schemas.POSTGRES {
6161
loaderOptions = append(loaderOptions, testfixtures.SkipResetSequences())
6262
}
6363

64-
fixtures, err = testfixtures.New(loaderOptions...)
64+
fixturesLoader, err = testfixtures.New(loaderOptions...)
6565
if err != nil {
6666
return err
6767
}
@@ -78,11 +78,9 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
7878
func LoadFixtures(engine ...*xorm.Engine) error {
7979
e := GetXORMEngine(engine...)
8080
var err error
81-
// Database transaction conflicts could occur and result in ROLLBACK
82-
// As a simple workaround, we just retry 20 times.
83-
for i := 0; i < 20; i++ {
84-
err = fixtures.Load()
85-
if err == nil {
81+
// (doubt) database transaction conflicts could occur and result in ROLLBACK? just try for a few times.
82+
for i := 0; i < 5; i++ {
83+
if err = fixturesLoader.Load(); err == nil {
8684
break
8785
}
8886
time.Sleep(200 * time.Millisecond)

‎models/user/user_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package user_test
55

66
import (
77
"context"
8+
"fmt"
89
"math/rand"
910
"strings"
1011
"testing"
@@ -64,9 +65,10 @@ func TestSearchUsers(t *testing.T) {
6465
testSuccess := func(opts *user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) {
6566
users, _, err := user_model.SearchUsers(opts)
6667
assert.NoError(t, err)
67-
if assert.Len(t, users, len(expectedUserOrOrgIDs), opts) {
68+
cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts)
69+
if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) {
6870
for i, expectedID := range expectedUserOrOrgIDs {
69-
assert.EqualValues(t, expectedID, users[i].ID)
71+
assert.EqualValues(t, expectedID, users[i].ID, "case: %s", cassText)
7072
}
7173
}
7274
}
@@ -118,7 +120,7 @@ func TestSearchUsers(t *testing.T) {
118120
[]int64{1})
119121

120122
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: util.OptionalBoolTrue},
121-
[]int64{29, 30})
123+
[]int64{29})
122124

123125
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: util.OptionalBoolTrue},
124126
[]int64{30})

‎modules/context/context.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (ctx *Context) serverErrorInternal(logMsg string, logErr error) {
301301

302302
// it's safe to show internal error to admin users, and it helps
303303
if !setting.IsProd || (ctx.Doer != nil && ctx.Doer.IsAdmin) {
304-
ctx.Data["ErrorMsg"] = logErr
304+
ctx.Data["ErrorMsg"] = fmt.Sprintf("%s, %s", logMsg, logErr)
305305
}
306306
}
307307

‎modules/context/repo.go

+23-14
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ func (r *Repository) CanCreateIssueDependencies(user *user_model.User, isPull bo
184184

185185
// GetCommitsCount returns cached commit count for current view
186186
func (r *Repository) GetCommitsCount() (int64, error) {
187+
if r.Commit == nil {
188+
return 0, nil
189+
}
187190
var contextName string
188191
if r.IsViewBranch {
189192
contextName = r.BranchName
@@ -642,8 +645,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
642645
if err != nil {
643646
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
644647
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
645-
ctx.Repo.Repository.Status = repo_model.RepositoryBroken
646-
ctx.Repo.Repository.IsEmpty = true
648+
ctx.Repo.Repository.MarkAsBrokenEmpty()
647649
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
648650
// Only allow access to base of repo or settings
649651
if !isHomeOrSettings {
@@ -689,7 +691,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
689691
ctx.Data["BranchesCount"] = len(brs)
690692

691693
// If not branch selected, try default one.
692-
// If default branch doesn't exists, fall back to some other branch.
694+
// If default branch doesn't exist, fall back to some other branch.
693695
if len(ctx.Repo.BranchName) == 0 {
694696
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
695697
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
@@ -878,6 +880,10 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
878880
return func(ctx *Context) (cancel context.CancelFunc) {
879881
// Empty repository does not have reference information.
880882
if ctx.Repo.Repository.IsEmpty {
883+
// assume the user is viewing the (non-existent) default branch
884+
ctx.Repo.IsViewBranch = true
885+
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
886+
ctx.Data["TreePath"] = ""
881887
return
882888
}
883889

@@ -907,27 +913,30 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
907913
refName = ctx.Repo.Repository.DefaultBranch
908914
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
909915
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
910-
if err != nil {
911-
ctx.ServerError("GetBranches", err)
912-
return
916+
if err == nil && len(brs) != 0 {
917+
refName = brs[0]
913918
} else if len(brs) == 0 {
914-
err = fmt.Errorf("No branches in non-empty repository %s",
915-
ctx.Repo.GitRepo.Path)
916-
ctx.ServerError("GetBranches", err)
917-
return
919+
log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path)
920+
ctx.Repo.Repository.MarkAsBrokenEmpty()
921+
} else {
922+
log.Error("GetBranches error: %v", err)
923+
ctx.Repo.Repository.MarkAsBrokenEmpty()
918924
}
919-
refName = brs[0]
920925
}
921926
ctx.Repo.RefName = refName
922927
ctx.Repo.BranchName = refName
923928
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
924-
if err != nil {
929+
if err == nil {
930+
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
931+
} else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") {
932+
// if the repository is broken, we can continue to the handler code, to show "Settings -> Delete Repository" for end users
933+
log.Error("GetBranchCommit: %v", err)
934+
ctx.Repo.Repository.MarkAsBrokenEmpty()
935+
} else {
925936
ctx.ServerError("GetBranchCommit", err)
926937
return
927938
}
928-
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
929939
ctx.Repo.IsViewBranch = true
930-
931940
} else {
932941
refName = getRefName(ctx, refType)
933942
ctx.Repo.RefName = refName

‎modules/git/command.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,18 @@ type RunOpts struct {
211211
Env []string
212212
Timeout time.Duration
213213
UseContextTimeout bool
214-
Dir string
215-
Stdout, Stderr io.Writer
216-
Stdin io.Reader
217-
PipelineFunc func(context.Context, context.CancelFunc) error
214+
215+
// Dir is the working dir for the git command, however:
216+
// FIXME: this could be incorrect in many cases, for example:
217+
// * /some/path/.git
218+
// * /some/path/.git/gitea-data/data/repositories/user/repo.git
219+
// If "user/repo.git" is invalid/broken, then running git command in it will use "/some/path/.git", and produce unexpected results
220+
// The correct approach is to use `--git-dir" global argument
221+
Dir string
222+
223+
Stdout, Stderr io.Writer
224+
Stdin io.Reader
225+
PipelineFunc func(context.Context, context.CancelFunc) error
218226
}
219227

220228
func commonBaseEnvs() []string {

‎modules/git/repo.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func InitRepository(ctx context.Context, repoPath string, bare bool) error {
8080
// IsEmpty Check if repository is empty.
8181
func (repo *Repository) IsEmpty() (bool, error) {
8282
var errbuf, output strings.Builder
83-
if err := NewCommand(repo.Ctx, "show-ref", "--head", "^HEAD$").
83+
if err := NewCommand(repo.Ctx).AddOptionFormat("--git-dir=%s", repo.Path).AddArguments("show-ref", "--head", "^HEAD$").
8484
Run(&RunOpts{
8585
Dir: repo.Path,
8686
Stdout: &output,

‎modules/git/repo_base_nogogit.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
6161
}
6262

6363
repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath)
64-
repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repo.Path)
64+
repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repoPath)
6565

6666
return repo, nil
6767
}

‎modules/indexer/code/indexer.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ func Init() {
154154
log.Trace("IndexerData Process Repo: %d", indexerData.RepoID)
155155

156156
if err := index(ctx, indexer, indexerData.RepoID); err != nil {
157-
log.Error("index: %v", err)
157+
if !setting.IsInTesting {
158+
log.Error("indexer index error for repo %v: %v", indexerData.RepoID, err)
159+
}
158160
if indexer.Ping() {
159161
continue
160162
}

‎modules/indexer/stats/db.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"code.gitea.io/gitea/modules/graceful"
1212
"code.gitea.io/gitea/modules/log"
1313
"code.gitea.io/gitea/modules/process"
14+
"code.gitea.io/gitea/modules/setting"
1415
)
1516

1617
// DBIndexer implements Indexer interface to use database's like search
@@ -46,7 +47,7 @@ func (db *DBIndexer) Index(id int64) error {
4647
// Get latest commit for default branch
4748
commitID, err := gitRepo.GetBranchCommitID(repo.DefaultBranch)
4849
if err != nil {
49-
if git.IsErrBranchNotExist(err) || git.IsErrNotExist(err) {
50+
if git.IsErrBranchNotExist(err) || git.IsErrNotExist(err) || setting.IsInTesting {
5051
log.Debug("Unable to get commit ID for default branch %s in %s ... skipping this repository", repo.DefaultBranch, repo.RepoPath())
5152
return nil
5253
}
@@ -62,7 +63,9 @@ func (db *DBIndexer) Index(id int64) error {
6263
// Calculate and save language statistics to database
6364
stats, err := gitRepo.GetLanguageStats(commitID)
6465
if err != nil {
65-
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err)
66+
if !setting.IsInTesting {
67+
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err)
68+
}
6669
return err
6770
}
6871
err = repo_model.UpdateLanguageStats(repo, commitID, stats)

‎modules/indexer/stats/queue.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"code.gitea.io/gitea/modules/graceful"
1111
"code.gitea.io/gitea/modules/log"
1212
"code.gitea.io/gitea/modules/queue"
13+
"code.gitea.io/gitea/modules/setting"
1314
)
1415

1516
// statsQueue represents a queue to handle repository stats updates
@@ -20,7 +21,9 @@ func handle(data ...queue.Data) []queue.Data {
2021
for _, datum := range data {
2122
opts := datum.(int64)
2223
if err := indexer.Index(opts); err != nil {
23-
log.Error("stats queue indexer.Index(%d) failed: %v", opts, err)
24+
if !setting.IsInTesting {
25+
log.Error("stats queue indexer.Index(%d) failed: %v", opts, err)
26+
}
2427
}
2528
}
2629
return nil

0 commit comments

Comments
 (0)
Please sign in to comment.