Add Close() method to gogitRepository (#8901) (#8956)

Backport #8901 

In investigating #7947 it has become clear that the storage component of go-git repositories needs closing.

This PR adds this Close function and adds the Close functions as necessary.

In TransferOwnership the ctx.Repo.GitRepo is closed if it is open to help prevent the risk of multiple open files.

Fixes #7947
This commit is contained in:
zeripath 2019-11-13 13:54:04 +00:00 committed by GitHub
parent 43fc99a7ed
commit 3497efac4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 390 additions and 106 deletions

View File

@ -375,17 +375,20 @@ func runRepoSyncReleases(c *cli.Context) error {
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil { if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
log.Warn(" SyncReleasesWithTags: %v", err) log.Warn(" SyncReleasesWithTags: %v", err)
gitRepo.Close()
continue continue
} }
count, err = getReleaseCount(repo.ID) count, err = getReleaseCount(repo.ID)
if err != nil { if err != nil {
log.Warn(" GetReleaseCountByRepoID: %v", err) log.Warn(" GetReleaseCountByRepoID: %v", err)
gitRepo.Close()
continue continue
} }
log.Trace(" repo %s releases synchronized to tags: from %d to %d", log.Trace(" repo %s releases synchronized to tags: from %d to %d",
repo.FullName(), oldnum, count) repo.FullName(), oldnum, count)
gitRepo.Close()
} }
} }

View File

@ -68,6 +68,7 @@ type Uploader interface {
CreateComment(issueNumber int64, comment *Comment) error CreateComment(issueNumber int64, comment *Comment) error
CreatePullRequest(pr *PullRequest) error CreatePullRequest(pr *PullRequest) error
Rollback() error Rollback() error
Close()
} }
``` ```

View File

@ -51,6 +51,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
gitRepo, err := git.OpenRepository(repo.RepoPath()) gitRepo, err := git.OpenRepository(repo.RepoPath())
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
err = gitRepo.CreateTag("v0.0.1", "master") err = gitRepo.CreateTag("v0.0.1", "master")
assert.NoError(t, err) assert.NoError(t, err)
@ -112,6 +113,7 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
gitRepo, err := git.OpenRepository(repo.RepoPath()) gitRepo, err := git.OpenRepository(repo.RepoPath())
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
err = gitRepo.CreateTag("v0.0.1", "master") err = gitRepo.CreateTag("v0.0.1", "master")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -139,6 +139,7 @@ func TestAPICreateFile(t *testing.T) {
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
gitRepo.Close()
} }
// Test creating a file in a new branch // Test creating a file in a new branch

View File

@ -143,6 +143,7 @@ func TestAPIUpdateFile(t *testing.T) {
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
gitRepo.Close()
} }
// Test updating a file in a new branch // Test updating a file in a new branch

View File

@ -74,6 +74,8 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch) repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
// Get the commit ID of the default branch // Get the commit ID of the default branch
gitRepo, _ := git.OpenRepository(repo1.RepoPath()) gitRepo, _ := git.OpenRepository(repo1.RepoPath())
defer gitRepo.Close()
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch) commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
// Make a new tag in repo1 // Make a new tag in repo1
newTag := "test_tag" newTag := "test_tag"

View File

@ -75,6 +75,8 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch) repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
// Get the commit ID of the default branch // Get the commit ID of the default branch
gitRepo, _ := git.OpenRepository(repo1.RepoPath()) gitRepo, _ := git.OpenRepository(repo1.RepoPath())
defer gitRepo.Close()
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch) commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
// Make a new tag in repo1 // Make a new tag in repo1
newTag := "test_tag" newTag := "test_tag"

View File

@ -29,6 +29,8 @@ func TestAPIGitTags(t *testing.T) {
git.NewCommand("config", "user.email", user.Email).RunInDir(repo.RepoPath()) git.NewCommand("config", "user.email", user.Email).RunInDir(repo.RepoPath())
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit("master") commit, _ := gitRepo.GetBranchCommit("master")
lTagName := "lightweightTag" lTagName := "lightweightTag"
gitRepo.CreateTag(lTagName, commit.ID.String()) gitRepo.CreateTag(lTagName, commit.ID.String())

View File

@ -73,6 +73,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getDeleteRepoFileOptions(repo) opts := getDeleteRepoFileOptions(repo)
@ -111,6 +112,8 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getDeleteRepoFileOptions(repo) opts := getDeleteRepoFileOptions(repo)
@ -139,6 +142,8 @@ func TestDeleteRepoFileErrors(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User

View File

@ -191,6 +191,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getCreateRepoFileOptions(repo) opts := getCreateRepoFileOptions(repo)
@ -201,6 +203,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
// asserts // asserts
assert.Nil(t, err) assert.Nil(t, err)
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID) expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID)
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
@ -220,6 +224,8 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getUpdateRepoFileOptions(repo) opts := getUpdateRepoFileOptions(repo)
@ -230,6 +236,8 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
// asserts // asserts
assert.Nil(t, err) assert.Nil(t, err)
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath) expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
@ -249,6 +257,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getUpdateRepoFileOptions(repo) opts := getUpdateRepoFileOptions(repo)
@ -261,6 +271,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
// asserts // asserts
assert.Nil(t, err) assert.Nil(t, err)
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath) expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath)
// assert that the old file no longer exists in the last commit of the branch // assert that the old file no longer exists in the last commit of the branch
@ -288,6 +300,8 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User
opts := getUpdateRepoFileOptions(repo) opts := getUpdateRepoFileOptions(repo)
@ -300,6 +314,8 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
// asserts // asserts
assert.Nil(t, err) assert.Nil(t, err)
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch) commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch)
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath) expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
@ -315,6 +331,8 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
doer := ctx.User doer := ctx.User

View File

@ -17,6 +17,7 @@ func BenchmarkGetCommitGraph(b *testing.B) {
if err != nil { if err != nil {
b.Error("Could not open repository") b.Error("Could not open repository")
} }
defer currentRepo.Close()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
graph, err := GetCommitGraph(currentRepo) graph, err := GetCommitGraph(currentRepo)

View File

@ -47,6 +47,7 @@ func releaseAddColumnIsTagAndSyncTags(x *xorm.Engine) error {
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil { if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
log.Warn("SyncReleasesWithTags: %v", err) log.Warn("SyncReleasesWithTags: %v", err)
} }
gitRepo.Close()
} }
if len(repos) < pageSize { if len(repos) < pageSize {
break break

View File

@ -91,6 +91,7 @@ func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
if err != nil { if err != nil {
return err return err
} }
defer gitRepo.Close()
gitRepoCache[release.RepoID] = gitRepo gitRepoCache[release.RepoID] = gitRepo
} }

View File

@ -382,6 +382,7 @@ func (pr *PullRequest) GetLastCommitStatus() (status *CommitStatus, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer headGitRepo.Close()
lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch) lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
if err != nil { if err != nil {
@ -571,6 +572,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err) return nil, fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
commit, err := gitRepo.GetCommit(mergeCommit[:40]) commit, err := gitRepo.GetCommit(mergeCommit[:40])
if err != nil { if err != nil {
@ -955,6 +957,7 @@ func (pr *PullRequest) UpdatePatch() (err error) {
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %v", err) return fmt.Errorf("OpenRepository: %v", err)
} }
defer headGitRepo.Close()
// Add a temporary remote. // Add a temporary remote.
tmpRemote := com.ToStr(time.Now().UnixNano()) tmpRemote := com.ToStr(time.Now().UnixNano())
@ -996,6 +999,7 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %v", err) return fmt.Errorf("OpenRepository: %v", err)
} }
defer headGitRepo.Close()
tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID) tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID)
if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil { if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil {
@ -1185,6 +1189,7 @@ func checkForInvalidation(requests PullRequestList, repoID int64, doer *User, br
if err != nil { if err != nil {
log.Error("PullRequestList.InvalidateCodeComments: %v", err) log.Error("PullRequestList.InvalidateCodeComments: %v", err)
} }
gitRepo.Close()
}() }()
return nil return nil
} }

View File

@ -998,6 +998,7 @@ func MigrateRepositoryGitData(doer, u *User, repo *Repository, opts api.MigrateR
if err != nil { if err != nil {
return repo, fmt.Errorf("OpenRepository: %v", err) return repo, fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
repo.IsEmpty, err = gitRepo.IsEmpty() repo.IsEmpty, err = gitRepo.IsEmpty()
if err != nil { if err != nil {

View File

@ -64,6 +64,8 @@ func GetActivityStats(repo *Repository, timeFrom time.Time, releases, issues, pr
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err) return nil, fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch) code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
if err != nil { if err != nil {
return nil, fmt.Errorf("FillFromGit: %v", err) return nil, fmt.Errorf("FillFromGit: %v", err)
@ -79,6 +81,8 @@ func GetActivityStatsTopAuthors(repo *Repository, timeFrom time.Time, count int)
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err) return nil, fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
code, err := gitRepo.GetCodeActivityStats(timeFrom, "") code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
if err != nil { if err != nil {
return nil, fmt.Errorf("FillFromGit: %v", err) return nil, fmt.Errorf("FillFromGit: %v", err)

View File

@ -23,6 +23,7 @@ func (repo *Repository) GetBranch(branch string) (*git.Branch, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
return gitRepo.GetBranch(branch) return gitRepo.GetBranch(branch)
} }
@ -38,6 +39,7 @@ func (repo *Repository) CheckBranchName(name string) error {
if err != nil { if err != nil {
return err return err
} }
defer gitRepo.Close()
branches, err := repo.GetBranches() branches, err := repo.GetBranches()
if err != nil { if err != nil {
@ -94,6 +96,7 @@ func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName st
log.Error("Unable to open temporary repository: %s (%v)", basePath, err) log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err) return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
} }
defer gitRepo.Close()
if err = gitRepo.CreateBranch(branchName, oldBranchName); err != nil { if err = gitRepo.CreateBranch(branchName, oldBranchName); err != nil {
log.Error("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err) log.Error("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err)
@ -140,6 +143,7 @@ func (repo *Repository) CreateNewBranchFromCommit(doer *User, commit, branchName
log.Error("Unable to open temporary repository: %s (%v)", basePath, err) log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err) return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
} }
defer gitRepo.Close()
if err = gitRepo.CreateBranch(branchName, commit); err != nil { if err = gitRepo.CreateBranch(branchName, commit); err != nil {
log.Error("Unable to create branch: %s from %s. (%v)", branchName, commit, err) log.Error("Unable to create branch: %s from %s. (%v)", branchName, commit, err)

View File

@ -1,24 +0,0 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"code.gitea.io/gitea/modules/git"
)
// GetTagsByPath returns repo tags by its path
func GetTagsByPath(path string) ([]*git.Tag, error) {
gitRepo, err := git.OpenRepository(path)
if err != nil {
return nil, err
}
return gitRepo.GetTagInfos()
}
// GetTags return repo's tags
func (repo *Repository) GetTags() ([]*git.Tag, error) {
return GetTagsByPath(repo.RepoPath())
}

View File

@ -140,6 +140,7 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiName, newWikiName, con
log.Error("Unable to open temporary repository: %s (%v)", basePath, err) log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err) return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
} }
defer gitRepo.Close()
if hasMasterBranch { if hasMasterBranch {
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil { if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
@ -276,6 +277,7 @@ func (repo *Repository) DeleteWikiPage(doer *User, wikiName string) (err error)
log.Error("Unable to open temporary repository: %s (%v)", basePath, err) log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err) return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
} }
defer gitRepo.Close()
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil { if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err) log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)

View File

@ -161,6 +161,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
// Now need to show that the page has been added: // Now need to show that the page has been added:
gitRepo, err := git.OpenRepository(repo.WikiPath()) gitRepo, err := git.OpenRepository(repo.WikiPath())
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
masterTree, err := gitRepo.GetTree("master") masterTree, err := gitRepo.GetTree("master")
assert.NoError(t, err) assert.NoError(t, err)
wikiPath := WikiNameToFilename(wikiName) wikiPath := WikiNameToFilename(wikiName)
@ -214,6 +215,7 @@ func TestRepository_EditWikiPage(t *testing.T) {
_, err := masterTree.GetTreeEntryByPath("Home.md") _, err := masterTree.GetTreeEntryByPath("Home.md")
assert.Error(t, err) assert.Error(t, err)
} }
gitRepo.Close()
} }
} }
@ -226,6 +228,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
// Now need to show that the page has been added: // Now need to show that the page has been added:
gitRepo, err := git.OpenRepository(repo.WikiPath()) gitRepo, err := git.OpenRepository(repo.WikiPath())
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
masterTree, err := gitRepo.GetTree("master") masterTree, err := gitRepo.GetTree("master")
assert.NoError(t, err) assert.NoError(t, err)
wikiPath := WikiNameToFilename("Home") wikiPath := WikiNameToFilename("Home")

View File

@ -186,7 +186,16 @@ func ReferencesGitRepo(allowEmpty bool) macaron.Handler {
return return
} }
ctx.Repo.GitRepo = gitRepo ctx.Repo.GitRepo = gitRepo
// We opened it, we should close it
defer func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
} }
ctx.Next()
} }
} }

View File

@ -427,9 +427,18 @@ func RepoAssignment() macaron.Handler {
} }
ctx.Repo.GitRepo = gitRepo ctx.Repo.GitRepo = gitRepo
// We opened it, we should close it
defer func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
// Stop at this point when the repo is empty. // Stop at this point when the repo is empty.
if ctx.Repo.Repository.IsEmpty { if ctx.Repo.Repository.IsEmpty {
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
ctx.Next()
return return
} }
@ -488,6 +497,7 @@ func RepoAssignment() macaron.Handler {
ctx.Data["GoDocDirectory"] = prefix + "{/dir}" ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}" ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
} }
ctx.Next()
} }
} }
@ -593,6 +603,13 @@ func RepoRefByType(refType RepoRefType) macaron.Handler {
ctx.ServerError("RepoRef Invalid repo "+repoPath, err) ctx.ServerError("RepoRef Invalid repo "+repoPath, err)
return return
} }
// We opened it, we should close it
defer func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
} }
// Get default branch. // Get default branch.
@ -681,6 +698,8 @@ func RepoRefByType(refType RepoRefType) macaron.Handler {
return return
} }
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
ctx.Next()
} }
} }

View File

@ -87,10 +87,11 @@ func (r *BlameReader) Close() error {
// CreateBlameReader creates reader for given repository, commit and file // CreateBlameReader creates reader for given repository, commit and file
func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) { func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) {
_, err := OpenRepository(repoPath) gitRepo, err := OpenRepository(repoPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
gitRepo.Close()
return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file) return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
} }

View File

@ -37,6 +37,8 @@ THE SOFTWARE.
` `
repo, err := OpenRepository("../../.git") repo, err := OpenRepository("../../.git")
assert.NoError(t, err) assert.NoError(t, err)
defer repo.Close()
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697") testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
assert.NoError(t, err) assert.NoError(t, err)
@ -55,6 +57,8 @@ func Benchmark_Blob_Data(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
defer repo.Close()
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697") testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)

View File

@ -77,6 +77,8 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
testGetCommitsInfo(t, bareRepo1) testGetCommitsInfo(t, bareRepo1)
clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo") clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo")
@ -84,6 +86,8 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
defer os.RemoveAll(clonedPath) defer os.RemoveAll(clonedPath)
clonedRepo1, err := OpenRepository(clonedPath) clonedRepo1, err := OpenRepository(clonedPath)
assert.NoError(t, err) assert.NoError(t, err)
defer clonedRepo1.Close()
testGetCommitsInfo(t, clonedRepo1) testGetCommitsInfo(t, clonedRepo1)
} }
@ -101,13 +105,16 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
for _, benchmark := range benchmarks { for _, benchmark := range benchmarks {
var commit *Commit var commit *Commit
var entries Entries var entries Entries
var repo *Repository
if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil { if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil {
b.Fatal(err) b.Fatal(err)
} else if repo, err := OpenRepository(repoPath); err != nil { } else if repo, err = OpenRepository(repoPath); err != nil {
b.Fatal(err) b.Fatal(err)
} else if commit, err = repo.GetBranchCommit("master"); err != nil { } else if commit, err = repo.GetBranchCommit("master"); err != nil {
repo.Close()
b.Fatal(err) b.Fatal(err)
} else if entries, err = commit.Tree.ListEntries(); err != nil { } else if entries, err = commit.Tree.ListEntries(); err != nil {
repo.Close()
b.Fatal(err) b.Fatal(err)
} }
entries.Sort() entries.Sort()
@ -120,5 +127,6 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
} }
} }
}) })
repo.Close()
} }
} }

View File

@ -15,6 +15,7 @@ func TestGetNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
note := Note{} note := Note{}
err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note) err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
@ -27,6 +28,7 @@ func TestGetNestedNotes(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo3_notes") repoPath := filepath.Join(testReposDir, "repo3_notes")
repo, err := OpenRepository(repoPath) repo, err := OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer repo.Close()
note := Note{} note := Note{}
err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note) err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note)

View File

@ -17,6 +17,7 @@ import (
"strings" "strings"
"time" "time"
gitealog "code.gitea.io/gitea/modules/log"
"github.com/unknwon/com" "github.com/unknwon/com"
"gopkg.in/src-d/go-billy.v4/osfs" "gopkg.in/src-d/go-billy.v4/osfs"
gogit "gopkg.in/src-d/go-git.v4" gogit "gopkg.in/src-d/go-git.v4"
@ -107,6 +108,21 @@ func OpenRepository(repoPath string) (*Repository, error) {
}, nil }, nil
} }
// Close this repository, in particular close the underlying gogitStorage if this is not nil
func (repo *Repository) Close() {
if repo == nil || repo.gogitStorage == nil {
return
}
if err := repo.gogitStorage.Close(); err != nil {
gitealog.Error("Error closing storage: %v", err)
}
}
// GoGitRepo gets the go-git repo representation
func (repo *Repository) GoGitRepo() *gogit.Repository {
return repo.gogitRepo
}
// IsEmpty Check if repository is empty. // IsEmpty Check if repository is empty.
func (repo *Repository) IsEmpty() (bool, error) { func (repo *Repository) IsEmpty() (bool, error) {
var errbuf strings.Builder var errbuf strings.Builder

View File

@ -17,6 +17,7 @@ func TestRepository_GetBlob_Found(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare") repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepository(repoPath) r, err := OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer r.Close()
testCases := []struct { testCases := []struct {
OID string OID string
@ -44,6 +45,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare") repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepository(repoPath) r, err := OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer r.Close()
testCase := "0000000000000000000000000000000000000000" testCase := "0000000000000000000000000000000000000000"
testError := ErrNotExist{testCase, ""} testError := ErrNotExist{testCase, ""}
@ -57,6 +59,7 @@ func TestRepository_GetBlob_NoId(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare") repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepository(repoPath) r, err := OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer r.Close()
testCase := "" testCase := ""
testError := fmt.Errorf("Length must be 40: %s", testCase) testError := fmt.Errorf("Length must be 40: %s", testCase)

View File

@ -108,6 +108,7 @@ func GetBranchesByPath(path string) ([]*Branch, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
brs, err := gitRepo.GetBranches() brs, err := gitRepo.GetBranches()
if err != nil { if err != nil {

View File

@ -15,6 +15,7 @@ func TestRepository_GetBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
branches, err := bareRepo1.GetBranches() branches, err := bareRepo1.GetBranches()
@ -29,6 +30,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
defer bareRepo1.Close()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_, err := bareRepo1.GetBranches() _, err := bareRepo1.GetBranches()

View File

@ -15,6 +15,7 @@ func TestRepository_GetCommitBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
// these test case are specific to the repo1_bare test repo // these test case are specific to the repo1_bare test repo
testCases := []struct { testCases := []struct {
@ -41,6 +42,7 @@ func TestGetTagCommitWithSignature(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a") commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a")
assert.NoError(t, err) assert.NoError(t, err)
@ -54,6 +56,7 @@ func TestGetCommitWithBadCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
commit, err := bareRepo1.GetCommit("bad_branch") commit, err := bareRepo1.GetCommit("bad_branch")
assert.Nil(t, commit) assert.Nil(t, commit)

View File

@ -20,6 +20,7 @@ func TestGetFormatPatch(t *testing.T) {
defer os.RemoveAll(clonedPath) defer os.RemoveAll(clonedPath)
repo, err := OpenRepository(clonedPath) repo, err := OpenRepository(clonedPath)
assert.NoError(t, err) assert.NoError(t, err)
defer repo.Close()
rd, err := repo.GetFormatPatch("8d92fc95^", "8d92fc95") rd, err := repo.GetFormatPatch("8d92fc95^", "8d92fc95")
assert.NoError(t, err) assert.NoError(t, err)
patchb, err := ioutil.ReadAll(rd) patchb, err := ioutil.ReadAll(rd)

View File

@ -15,6 +15,7 @@ func TestRepository_GetRefs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
refs, err := bareRepo1.GetRefs() refs, err := bareRepo1.GetRefs()
@ -38,6 +39,7 @@ func TestRepository_GetRefsFiltered(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
refs, err := bareRepo1.GetRefsFiltered(TagPrefix) refs, err := bareRepo1.GetRefsFiltered(TagPrefix)

View File

@ -16,6 +16,7 @@ func TestRepository_GetCodeActivityStats(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
timeFrom, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00+00:00") timeFrom, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00+00:00")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -16,6 +16,7 @@ func TestRepository_GetTags(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepository(bareRepo1Path) bareRepo1, err := OpenRepository(bareRepo1Path)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
tags, err := bareRepo1.GetTagInfos() tags, err := bareRepo1.GetTagInfos()
assert.NoError(t, err) assert.NoError(t, err)
@ -34,6 +35,7 @@ func TestRepository_GetTag(t *testing.T) {
bareRepo1, err := OpenRepository(clonedPath) bareRepo1, err := OpenRepository(clonedPath)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1" lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
lTagName := "lightweightTag" lTagName := "lightweightTag"
@ -83,6 +85,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
bareRepo1, err := OpenRepository(clonedPath) bareRepo1, err := OpenRepository(clonedPath)
assert.NoError(t, err) assert.NoError(t, err)
defer bareRepo1.Close()
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1" lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
lTagName := "lightweightTag" lTagName := "lightweightTag"

View File

@ -30,6 +30,7 @@ func TestRepoIsEmpty(t *testing.T) {
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty") emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
repo, err := OpenRepository(emptyRepo2Path) repo, err := OpenRepository(emptyRepo2Path)
assert.NoError(t, err) assert.NoError(t, err)
defer repo.Close()
isEmpty, err := repo.IsEmpty() isEmpty, err := repo.IsEmpty()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, isEmpty) assert.True(t, isEmpty)

View File

@ -56,6 +56,7 @@ func TestEntriesCustomSort(t *testing.T) {
func TestFollowLink(t *testing.T) { func TestFollowLink(t *testing.T) {
r, err := OpenRepository("tests/repos/repo1_bare") r, err := OpenRepository("tests/repos/repo1_bare")
assert.NoError(t, err) assert.NoError(t, err)
defer r.Close()
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123") commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -17,4 +17,5 @@ type Uploader interface {
CreateComments(comments ...*Comment) error CreateComments(comments ...*Comment) error
CreatePullRequests(prs ...*PullRequest) error CreatePullRequests(prs ...*PullRequest) error
Rollback() error Rollback() error
Close()
} }

View File

@ -131,6 +131,13 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
return err return err
} }
// Close closes this uploader
func (g *GiteaLocalUploader) Close() {
if g.gitRepo != nil {
g.gitRepo.Close()
}
}
// CreateTopics creates topics // CreateTopics creates topics
func (g *GiteaLocalUploader) CreateTopics(topics ...string) error { func (g *GiteaLocalUploader) CreateTopics(topics ...string) error {
return models.SaveTopics(g.repo.ID, topics...) return models.SaveTopics(g.repo.ID, topics...)

View File

@ -94,6 +94,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
if err := uploader.CreateRepo(repo, opts); err != nil { if err := uploader.CreateRepo(repo, opts); err != nil {
return err return err
} }
defer uploader.Close()
log.Trace("migrating topics") log.Trace("migrating topics")
topics, err := downloader.GetTopics() topics, err := downloader.GetTopics()

View File

@ -53,9 +53,11 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
} }
if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil { if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) { if !git.IsErrUnsupportedVersion(err) {
gitRepo.Close()
return err return err
} }
} }
gitRepo.Close()
} }
} }
@ -132,8 +134,10 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
shaSum, err = gitRepo.GetBranchCommitID(refName) shaSum, err = gitRepo.GetBranchCommitID(refName)
if err != nil { if err != nil {
gitRepo.Close()
log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err) log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
} }
gitRepo.Close()
if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{ if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
Ref: refName, Ref: refName,
Sha: shaSum, Sha: shaSum,
@ -167,8 +171,10 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
} }
shaSum, err = gitRepo.GetTagCommitID(refName) shaSum, err = gitRepo.GetTagCommitID(refName)
if err != nil { if err != nil {
gitRepo.Close()
log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err) log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
} }
gitRepo.Close()
if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{ if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
Ref: refName, Ref: refName,
Sha: shaSum, Sha: shaSum,

View File

@ -17,6 +17,7 @@ func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
gitBlob, err := gitRepo.GetBlob(sha) gitBlob, err := gitRepo.GetBlob(sha)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -21,6 +21,8 @@ func TestGetBlobBySHA(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
ctx.SetParams(":sha", sha) ctx.SetParams(":sha", sha)

View File

@ -23,8 +23,10 @@ func CreateCommitStatus(repo *models.Repository, creator *models.User, sha strin
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err) return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
} }
if _, err := gitRepo.GetCommit(sha); err != nil { if _, err := gitRepo.GetCommit(sha); err != nil {
gitRepo.Close()
return fmt.Errorf("GetCommit[%s]: %v", sha, err) return fmt.Errorf("GetCommit[%s]: %v", sha, err)
} }
gitRepo.Close()
if err := models.NewCommitStatus(models.NewCommitStatusOptions{ if err := models.NewCommitStatus(models.NewCommitStatusOptions{
Repo: repo, Repo: repo,

View File

@ -59,6 +59,7 @@ func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
// Get the commit object for the ref // Get the commit object for the ref
commit, err := gitRepo.GetCommit(ref) commit, err := gitRepo.GetCommit(ref)
@ -117,6 +118,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
// Get the commit object for the ref // Get the commit object for the ref
commit, err := gitRepo.GetCommit(ref) commit, err := gitRepo.GetCommit(ref)

View File

@ -56,6 +56,8 @@ func TestGetContents(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
treePath := "README.md" treePath := "README.md"
ref := ctx.Repo.Repository.DefaultBranch ref := ctx.Repo.Repository.DefaultBranch
@ -82,6 +84,8 @@ func TestGetContentsOrListForDir(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
treePath := "" // root dir treePath := "" // root dir
ref := ctx.Repo.Repository.DefaultBranch ref := ctx.Repo.Repository.DefaultBranch
@ -115,6 +119,8 @@ func TestGetContentsOrListForFile(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
treePath := "README.md" treePath := "README.md"
ref := ctx.Repo.Repository.DefaultBranch ref := ctx.Repo.Repository.DefaultBranch
@ -141,6 +147,8 @@ func TestGetContentsErrors(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
treePath := "README.md" treePath := "README.md"
ref := repo.DefaultBranch ref := repo.DefaultBranch
@ -170,6 +178,8 @@ func TestGetContentsOrListErrors(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
treePath := "README.md" treePath := "README.md"
ref := repo.DefaultBranch ref := repo.DefaultBranch
@ -198,6 +208,8 @@ func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
test.LoadRepo(t, ctx, 15) test.LoadRepo(t, ctx, 15)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
t.Run("empty repo", func(t *testing.T) { t.Run("empty repo", func(t *testing.T) {

View File

@ -22,6 +22,8 @@ func TestGetDiffPreview(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
branch := ctx.Repo.Repository.DefaultBranch branch := ctx.Repo.Repository.DefaultBranch
treePath := "README.md" treePath := "README.md"
content := "# repo1\n\nDescription for repo1\nthis is a new line" content := "# repo1\n\nDescription for repo1\nthis is a new line"
@ -119,6 +121,8 @@ func TestGetDiffPreviewErrors(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
branch := ctx.Repo.Repository.DefaultBranch branch := ctx.Repo.Repository.DefaultBranch
treePath := "README.md" treePath := "README.md"
content := "# repo1\n\nDescription for repo1\nthis is a new line" content := "# repo1\n\nDescription for repo1\nthis is a new line"

View File

@ -88,10 +88,13 @@ func TestGetFileResponseFromCommit(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
branch := repo.DefaultBranch branch := repo.DefaultBranch
treePath := "README.md" treePath := "README.md"
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit(branch) commit, _ := gitRepo.GetBranchCommit(branch)
expectedFileResponse := getExpectedFileResponse() expectedFileResponse := getExpectedFileResponse()

View File

@ -44,6 +44,7 @@ func NewTemporaryUploadRepository(repo *models.Repository) (*TemporaryUploadRepo
// Close the repository cleaning up all files // Close the repository cleaning up all files
func (t *TemporaryUploadRepository) Close() { func (t *TemporaryUploadRepository) Close() {
defer t.gitRepo.Close()
if err := models.RemoveTemporaryPath(t.basePath); err != nil { if err := models.RemoveTemporaryPath(t.basePath); err != nil {
log.Error("Failed to remove temporary path %s: %v", t.basePath, err) log.Error("Failed to remove temporary path %s: %v", t.basePath, err)
} }

View File

@ -19,6 +19,7 @@ func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recurs
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
gitTree, err := gitRepo.GetTree(sha) gitTree, err := gitRepo.GetTree(sha)
if err != nil || gitTree == nil { if err != nil || gitTree == nil {
return nil, models.ErrSHANotFound{ return nil, models.ErrSHANotFound{

View File

@ -21,6 +21,8 @@ func TestGetTreeBySHA(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
sha := ctx.Repo.Repository.DefaultBranch sha := ctx.Repo.Repository.DefaultBranch
page := 1 page := 1
perPage := 10 perPage := 10

View File

@ -429,6 +429,7 @@ func PushUpdate(repo *models.Repository, branch string, opts models.PushUpdateOp
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %v", err) return fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
if err = repo.UpdateSize(); err != nil { if err = repo.UpdateSize(); err != nil {
log.Error("Failed to update size for repository: %v", err) log.Error("Failed to update size for repository: %v", err)

View File

@ -55,6 +55,7 @@ func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) {
func LoadRepoCommit(t *testing.T, ctx *context.Context) { func LoadRepoCommit(t *testing.T, ctx *context.Context) {
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath()) gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
branch, err := gitRepo.GetHEADBranch() branch, err := gitRepo.GetHEADBranch()
assert.NoError(t, err) assert.NoError(t, err)
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name) ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)

View File

@ -638,7 +638,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}, reqRepoReader(models.UnitTypeCode)) }, reqRepoReader(models.UnitTypeCode))
m.Group("/tags", func() { m.Group("/tags", func() {
m.Get("", repo.ListTags) m.Get("", repo.ListTags)
}, reqRepoReader(models.UnitTypeCode)) }, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
m.Group("/keys", func() { m.Group("/keys", func() {
m.Combo("").Get(repo.ListDeployKeys). m.Combo("").Get(repo.ListDeployKeys).
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)

View File

@ -51,6 +51,7 @@ func GetSingleCommit(ctx *context.APIContext) {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return
} }
defer gitRepo.Close()
commit, err := gitRepo.GetCommit(ctx.Params(":sha")) commit, err := gitRepo.GetCommit(ctx.Params(":sha"))
if err != nil { if err != nil {
ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err) ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err)
@ -113,6 +114,7 @@ func GetAllCommits(ctx *context.APIContext) {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return
} }
defer gitRepo.Close()
page := ctx.QueryInt("page") page := ctx.QueryInt("page")
if page <= 0 { if page <= 0 {

View File

@ -95,6 +95,7 @@ func GetArchive(ctx *context.APIContext) {
return return
} }
ctx.Repo.GitRepo = gitRepo ctx.Repo.GitRepo = gitRepo
defer gitRepo.Close()
repo.Download(ctx.Context) repo.Download(ctx.Context)
} }

View File

@ -76,6 +76,8 @@ func getGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, strin
if err != nil { if err != nil {
return nil, "OpenRepository", err return nil, "OpenRepository", err
} }
defer gitRepo.Close()
if len(filter) > 0 { if len(filter) > 0 {
filter = "refs/" + filter filter = "refs/" + filter
} }

View File

@ -194,6 +194,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
if ctx.Written() { if ctx.Written() {
return return
} }
defer headGitRepo.Close()
// Check if another PR exists with the same targets // Check if another PR exists with the same targets
existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch) existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch)
@ -687,6 +688,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's // user should have permission to read baseRepo's codes and pulls, NOT headRepo's
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User) permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -697,6 +699,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
baseRepo, baseRepo,
permBase) permBase)
} }
headGitRepo.Close()
ctx.NotFound("Can't read pulls or can't read UnitTypeCode") ctx.NotFound("Can't read pulls or can't read UnitTypeCode")
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -704,6 +707,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
// user should have permission to read headrepo's codes // user should have permission to read headrepo's codes
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User) permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -714,18 +718,21 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
headRepo, headRepo,
permHead) permHead)
} }
headGitRepo.Close()
ctx.NotFound("Can't read headRepo UnitTypeCode") ctx.NotFound("Can't read headRepo UnitTypeCode")
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
// Check if head branch is valid. // Check if head branch is valid.
if !headGitRepo.IsBranchExist(headBranch) { if !headGitRepo.IsBranchExist(headBranch) {
headGitRepo.Close()
ctx.NotFound() ctx.NotFound()
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch) compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.Error(500, "GetCompareInfo", err) ctx.Error(500, "GetCompareInfo", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }

View File

@ -33,7 +33,7 @@ func ListTags(ctx *context.APIContext) {
// responses: // responses:
// "200": // "200":
// "$ref": "#/responses/TagList" // "$ref": "#/responses/TagList"
tags, err := ctx.Repo.Repository.GetTags() tags, err := ctx.Repo.GitRepo.GetTagInfos()
if err != nil { if err != nil {
ctx.Error(500, "GetTags", err) ctx.Error(500, "GetTags", err)
return return

View File

@ -157,6 +157,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's // user should have permission to read baseRepo's codes and pulls, NOT headRepo's
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User) permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -167,6 +168,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
baseRepo, baseRepo,
permBase) permBase)
} }
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil) ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -174,6 +176,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
// user should have permission to read headrepo's codes // user should have permission to read headrepo's codes
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User) permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -184,6 +187,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
headRepo, headRepo,
permHead) permHead)
} }
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil) ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -199,6 +203,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
ctx.Data["HeadBranch"] = headBranch ctx.Data["HeadBranch"] = headBranch
headIsCommit = true headIsCommit = true
} else { } else {
headGitRepo.Close()
ctx.NotFound("IsRefExist", nil) ctx.NotFound("IsRefExist", nil)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -219,12 +224,14 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
baseRepo, baseRepo,
permBase) permBase)
} }
headGitRepo.Close()
ctx.NotFound("ParseCompareInfo", nil) ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch) compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
if err != nil { if err != nil {
headGitRepo.Close()
ctx.ServerError("GetCompareInfo", err) ctx.ServerError("GetCompareInfo", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
} }
@ -345,6 +352,7 @@ func CompareDiff(ctx *context.Context) {
if ctx.Written() { if ctx.Written() {
return return
} }
defer headGitRepo.Close()
nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch) nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch)
if ctx.Written() { if ctx.Written() {

View File

@ -48,6 +48,8 @@ func TestGetUniquePatchBranchName(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
expectedBranchName := "user2-patch-1" expectedBranchName := "user2-patch-1"
branchName := GetUniquePatchBranchName(ctx) branchName := GetUniquePatchBranchName(ctx)
assert.Equal(t, expectedBranchName, branchName) assert.Equal(t, expectedBranchName, branchName)
@ -61,9 +63,12 @@ func TestGetClosestParentWithFiles(t *testing.T) {
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
branch := repo.DefaultBranch branch := repo.DefaultBranch
gitRepo, _ := git.OpenRepository(repo.RepoPath()) gitRepo, _ := git.OpenRepository(repo.RepoPath())
defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit(branch) commit, _ := gitRepo.GetBranchCommit(branch)
expectedTreePath := "" expectedTreePath := ""

View File

@ -337,6 +337,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return nil return nil
} }
defer headGitRepo.Close()
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch) headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
@ -519,6 +520,7 @@ func ViewPullFiles(ctx *context.Context) {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return
} }
defer headGitRepo.Close()
headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch) headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
if err != nil { if err != nil {
@ -704,6 +706,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
if ctx.Written() { if ctx.Written() {
return return
} }
defer headGitRepo.Close()
labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, true) labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, true)
if ctx.Written() { if ctx.Written() {
@ -870,12 +873,14 @@ func CleanUpPullRequest(ctx *context.Context) {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err)
return return
} }
defer gitRepo.Close()
gitBaseRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) gitBaseRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
if err != nil { if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err)
return return
} }
defer gitBaseRepo.Close()
defer func() { defer func() {
ctx.JSON(200, map[string]interface{}{ ctx.JSON(200, map[string]interface{}{
@ -1004,6 +1009,7 @@ func DownloadPullPatch(ctx *context.Context) {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return
} }
defer headGitRepo.Close()
patch, err := headGitRepo.GetFormatPatch(pr.MergeBase, pr.HeadBranch) patch, err := headGitRepo.GetFormatPatch(pr.MergeBase, pr.HeadBranch)
if err != nil { if err != nil {

View File

@ -57,5 +57,6 @@ func TestNewReleasePost(t *testing.T) {
Title: testCase.Form.Title, Title: testCase.Form.Title,
Note: testCase.Form.Content, Note: testCase.Form.Content,
}, models.Cond("is_draft=?", len(testCase.Form.Draft) > 0)) }, models.Cond("is_draft=?", len(testCase.Form.Draft) > 0))
ctx.Repo.GitRepo.Close()
} }
} }

View File

@ -71,6 +71,11 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
// Check if repository name has been changed. // Check if repository name has been changed.
if repo.LowerName != strings.ToLower(newRepoName) { if repo.LowerName != strings.ToLower(newRepoName) {
isNameChanged = true isNameChanged = true
// Close the GitRepo if open
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}
if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil { if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
ctx.Data["Err_RepoName"] = true ctx.Data["Err_RepoName"] = true
switch { switch {
@ -378,6 +383,11 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
} }
oldOwnerID := ctx.Repo.Owner.ID oldOwnerID := ctx.Repo.Owner.ID
// Close the GitRepo if open
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}
if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil { if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil {
if models.IsErrRepoAlreadyExist(err) { if models.IsErrRepoAlreadyExist(err) {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)

View File

@ -146,6 +146,9 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
// Get page list. // Get page list.
entries, err := commit.ListEntries() entries, err := commit.ListEntries()
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("ListEntries", err) ctx.ServerError("ListEntries", err)
return nil, nil return nil, nil
} }
@ -159,6 +162,9 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
if models.IsErrWikiInvalidFileName(err) { if models.IsErrWikiInvalidFileName(err) {
continue continue
} }
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("WikiFilenameToName", err) ctx.ServerError("WikiFilenameToName", err)
return nil, nil return nil, nil
} else if wikiName == "_Sidebar" || wikiName == "_Footer" { } else if wikiName == "_Sidebar" || wikiName == "_Footer" {
@ -188,16 +194,25 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages") ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
} }
if entry == nil || ctx.Written() { if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil return nil, nil
} }
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar") sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil return nil, nil
} }
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer") footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil return nil, nil
} }
@ -218,6 +233,9 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
wikiRepo, commit, err := findWikiRepoCommit(ctx) wikiRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
if !git.IsErrNotExist(err) { if !git.IsErrNotExist(err) {
ctx.ServerError("GetBranchCommit", err) ctx.ServerError("GetBranchCommit", err)
} }
@ -241,6 +259,9 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages") ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
} }
if entry == nil || ctx.Written() { if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil return nil, nil
} }
@ -263,6 +284,9 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
// get Commit Count // get Commit Count
commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page) commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("CommitsByFileAndRangeNoFollow", err) ctx.ServerError("CommitsByFileAndRangeNoFollow", err)
return nil, nil return nil, nil
} }
@ -279,13 +303,21 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
} }
func renderEditPage(ctx *context.Context) { func renderEditPage(ctx *context.Context) {
_, commit, err := findWikiRepoCommit(ctx) wikiRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
if !git.IsErrNotExist(err) { if !git.IsErrNotExist(err) {
ctx.ServerError("GetBranchCommit", err) ctx.ServerError("GetBranchCommit", err)
} }
return return
} }
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
}
}()
// get requested pagename // get requested pagename
pageName := models.NormalizeWikiName(ctx.Params(":page")) pageName := models.NormalizeWikiName(ctx.Params(":page"))
@ -327,8 +359,16 @@ func Wiki(ctx *context.Context) {
wikiRepo, entry := renderViewPage(ctx) wikiRepo, entry := renderViewPage(ctx)
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return return
} }
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
}
}()
if entry == nil { if entry == nil {
ctx.Data["Title"] = ctx.Tr("repo.wiki") ctx.Data["Title"] = ctx.Tr("repo.wiki")
ctx.HTML(200, tplWikiStart) ctx.HTML(200, tplWikiStart)
@ -364,8 +404,16 @@ func WikiRevision(ctx *context.Context) {
wikiRepo, entry := renderRevisionPage(ctx) wikiRepo, entry := renderRevisionPage(ctx)
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return return
} }
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
}
}()
if entry == nil { if entry == nil {
ctx.Data["Title"] = ctx.Tr("repo.wiki") ctx.Data["Title"] = ctx.Tr("repo.wiki")
ctx.HTML(200, tplWikiStart) ctx.HTML(200, tplWikiStart)
@ -397,11 +445,18 @@ func WikiPages(ctx *context.Context) {
wikiRepo, commit, err := findWikiRepoCommit(ctx) wikiRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
return return
} }
entries, err := commit.ListEntries() entries, err := commit.ListEntries()
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("ListEntries", err) ctx.ServerError("ListEntries", err)
return return
} }
@ -412,6 +467,10 @@ func WikiPages(ctx *context.Context) {
} }
c, err := wikiRepo.GetCommitByPath(entry.Name()) c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil { if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("GetCommit", err) ctx.ServerError("GetCommit", err)
return return
} }
@ -420,6 +479,10 @@ func WikiPages(ctx *context.Context) {
if models.IsErrWikiInvalidFileName(err) { if models.IsErrWikiInvalidFileName(err) {
continue continue
} }
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("WikiFilenameToName", err) ctx.ServerError("WikiFilenameToName", err)
return return
} }
@ -431,6 +494,11 @@ func WikiPages(ctx *context.Context) {
} }
ctx.Data["Pages"] = pages ctx.Data["Pages"] = pages
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
}
}()
ctx.HTML(200, tplWikiPages) ctx.HTML(200, tplWikiPages)
} }

View File

@ -23,6 +23,7 @@ const message = "Wiki commit message for unit tests"
func wikiEntry(t *testing.T, repo *models.Repository, wikiName string) *git.TreeEntry { func wikiEntry(t *testing.T, repo *models.Repository, wikiName string) *git.TreeEntry {
wikiRepo, err := git.OpenRepository(repo.WikiPath()) wikiRepo, err := git.OpenRepository(repo.WikiPath())
assert.NoError(t, err) assert.NoError(t, err)
defer wikiRepo.Close()
commit, err := wikiRepo.GetBranchCommit("master") commit, err := wikiRepo.GetBranchCommit("master")
assert.NoError(t, err) assert.NoError(t, err)
entries, err := commit.ListEntries() entries, err := commit.ListEntries()

View File

@ -60,6 +60,7 @@ func CreateCodeComment(doer *models.User, repo *models.Repository, issue *models
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err) return nil, fmt.Errorf("OpenRepository: %v", err)
} }
defer gitRepo.Close()
// FIXME validate treePath // FIXME validate treePath
// Get latest commit referencing the commented line // Get latest commit referencing the commented line

View File

@ -678,6 +678,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer gitRepo.Close()
commit, err := gitRepo.GetCommit(afterCommitID) commit, err := gitRepo.GetCommit(afterCommitID)
if err != nil { if err != nil {
@ -750,6 +751,7 @@ func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiff
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %v", err) return fmt.Errorf("OpenRepository: %v", err)
} }
defer repo.Close()
commit, err := repo.GetCommit(endCommit) commit, err := repo.GetCommit(endCommit)
if err != nil { if err != nil {

View File

@ -197,8 +197,10 @@ func runSync(m *models.Mirror) ([]*mirrorSyncResult, bool) {
return nil, false return nil, false
} }
if err = models.SyncReleasesWithTags(m.Repo, gitRepo); err != nil { if err = models.SyncReleasesWithTags(m.Repo, gitRepo); err != nil {
gitRepo.Close()
log.Error("Failed to synchronize tags to releases for repository: %v", err) log.Error("Failed to synchronize tags to releases for repository: %v", err)
} }
gitRepo.Close()
if err := m.Repo.UpdateSize(); err != nil { if err := m.Repo.UpdateSize(); err != nil {
log.Error("Failed to update size for mirror repository: %v", err) log.Error("Failed to update size for mirror repository: %v", err)
@ -290,97 +292,103 @@ func Update() {
func SyncMirrors() { func SyncMirrors() {
// Start listening on new sync requests. // Start listening on new sync requests.
for repoID := range mirrorQueue.Queue() { for repoID := range mirrorQueue.Queue() {
log.Trace("SyncMirrors [repo_id: %v]", repoID) syncMirror(repoID)
mirrorQueue.Remove(repoID) }
}
m, err := models.GetMirrorByRepoID(com.StrTo(repoID).MustInt64()) func syncMirror(repoID string) {
log.Trace("SyncMirrors [repo_id: %v]", repoID)
mirrorQueue.Remove(repoID)
m, err := models.GetMirrorByRepoID(com.StrTo(repoID).MustInt64())
if err != nil {
log.Error("GetMirrorByRepoID [%s]: %v", repoID, err)
return
}
results, ok := runSync(m)
if !ok {
return
}
m.ScheduleNextUpdate()
if err = models.UpdateMirror(m); err != nil {
log.Error("UpdateMirror [%s]: %v", repoID, err)
return
}
var gitRepo *git.Repository
if len(results) == 0 {
log.Trace("SyncMirrors [repo_id: %d]: no commits fetched", m.RepoID)
} else {
gitRepo, err = git.OpenRepository(m.Repo.RepoPath())
if err != nil { if err != nil {
log.Error("GetMirrorByRepoID [%s]: %v", repoID, err) log.Error("OpenRepository [%d]: %v", m.RepoID, err)
return
}
defer gitRepo.Close()
}
for _, result := range results {
// Discard GitHub pull requests, i.e. refs/pull/*
if strings.HasPrefix(result.refName, "refs/pull/") {
continue continue
} }
results, ok := runSync(m) // Create reference
if !ok { if result.oldCommitID == gitShortEmptySha {
if err = models.MirrorSyncCreateAction(m.Repo, result.refName); err != nil {
log.Error("MirrorSyncCreateAction [repo_id: %d]: %v", m.RepoID, err)
}
continue continue
} }
m.ScheduleNextUpdate() // Delete reference
if err = models.UpdateMirror(m); err != nil { if result.newCommitID == gitShortEmptySha {
log.Error("UpdateMirror [%s]: %v", repoID, err) if err = models.MirrorSyncDeleteAction(m.Repo, result.refName); err != nil {
log.Error("MirrorSyncDeleteAction [repo_id: %d]: %v", m.RepoID, err)
}
continue continue
} }
var gitRepo *git.Repository // Push commits
if len(results) == 0 { oldCommitID, err := git.GetFullCommitID(gitRepo.Path, result.oldCommitID)
log.Trace("SyncMirrors [repo_id: %d]: no commits fetched", m.RepoID)
} else {
gitRepo, err = git.OpenRepository(m.Repo.RepoPath())
if err != nil {
log.Error("OpenRepository [%d]: %v", m.RepoID, err)
continue
}
}
for _, result := range results {
// Discard GitHub pull requests, i.e. refs/pull/*
if strings.HasPrefix(result.refName, "refs/pull/") {
continue
}
// Create reference
if result.oldCommitID == gitShortEmptySha {
if err = models.MirrorSyncCreateAction(m.Repo, result.refName); err != nil {
log.Error("MirrorSyncCreateAction [repo_id: %d]: %v", m.RepoID, err)
}
continue
}
// Delete reference
if result.newCommitID == gitShortEmptySha {
if err = models.MirrorSyncDeleteAction(m.Repo, result.refName); err != nil {
log.Error("MirrorSyncDeleteAction [repo_id: %d]: %v", m.RepoID, err)
}
continue
}
// Push commits
oldCommitID, err := git.GetFullCommitID(gitRepo.Path, result.oldCommitID)
if err != nil {
log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
continue
}
newCommitID, err := git.GetFullCommitID(gitRepo.Path, result.newCommitID)
if err != nil {
log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
continue
}
commits, err := gitRepo.CommitsBetweenIDs(newCommitID, oldCommitID)
if err != nil {
log.Error("CommitsBetweenIDs [repo_id: %d, new_commit_id: %s, old_commit_id: %s]: %v", m.RepoID, newCommitID, oldCommitID, err)
continue
}
if err = models.MirrorSyncPushAction(m.Repo, models.MirrorSyncPushActionOptions{
RefName: result.refName,
OldCommitID: oldCommitID,
NewCommitID: newCommitID,
Commits: models.ListToPushCommits(commits),
}); err != nil {
log.Error("MirrorSyncPushAction [repo_id: %d]: %v", m.RepoID, err)
continue
}
}
// Get latest commit date and update to current repository updated time
commitDate, err := git.GetLatestCommitTime(m.Repo.RepoPath())
if err != nil { if err != nil {
log.Error("GetLatestCommitDate [%d]: %v", m.RepoID, err) log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
continue continue
} }
newCommitID, err := git.GetFullCommitID(gitRepo.Path, result.newCommitID)
if err != nil {
log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
continue
}
commits, err := gitRepo.CommitsBetweenIDs(newCommitID, oldCommitID)
if err != nil {
log.Error("CommitsBetweenIDs [repo_id: %d, new_commit_id: %s, old_commit_id: %s]: %v", m.RepoID, newCommitID, oldCommitID, err)
continue
}
if err = models.MirrorSyncPushAction(m.Repo, models.MirrorSyncPushActionOptions{
RefName: result.refName,
OldCommitID: oldCommitID,
NewCommitID: newCommitID,
Commits: models.ListToPushCommits(commits),
}); err != nil {
log.Error("MirrorSyncPushAction [repo_id: %d]: %v", m.RepoID, err)
continue
}
}
if err = models.UpdateRepositoryUpdatedTime(m.RepoID, commitDate); err != nil { // Get latest commit date and update to current repository updated time
log.Error("Update repository 'updated_unix' [%d]: %v", m.RepoID, err) commitDate, err := git.GetLatestCommitTime(m.Repo.RepoPath())
continue if err != nil {
} log.Error("GetLatestCommitDate [%d]: %v", m.RepoID, err)
return
}
if err = models.UpdateRepositoryUpdatedTime(m.RepoID, commitDate); err != nil {
log.Error("Update repository 'updated_unix' [%d]: %v", m.RepoID, err)
return
} }
} }

View File

@ -51,6 +51,7 @@ func TestRelease_MirrorDelete(t *testing.T) {
gitRepo, err := git.OpenRepository(repoPath) gitRepo, err := git.OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
findOptions := models.FindReleasesOptions{IncludeDrafts: true, IncludeTags: true} findOptions := models.FindReleasesOptions{IncludeDrafts: true, IncludeTags: true}
initCount, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions) initCount, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions)

View File

@ -55,6 +55,7 @@ func IsPullCommitStatusPass(pr *models.PullRequest) (bool, error) {
if err != nil { if err != nil {
return false, errors.Wrap(err, "OpenRepository") return false, errors.Wrap(err, "OpenRepository")
} }
defer headGitRepo.Close()
if !headGitRepo.IsBranchExist(pr.HeadBranch) { if !headGitRepo.IsBranchExist(pr.HeadBranch) {
return false, errors.New("Head branch does not exist, can not merge") return false, errors.New("Head branch does not exist, can not merge")

View File

@ -27,6 +27,7 @@ func TestRelease_Create(t *testing.T) {
gitRepo, err := git.OpenRepository(repoPath) gitRepo, err := git.OpenRepository(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close()
assert.NoError(t, CreateRelease(gitRepo, &models.Release{ assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID, RepoID: repo.ID,