Browse Source

Use context parameter in models/git (#22367)

After #22362, we can feel free to use transactions without
`db.DefaultContext`.

And there are still lots of models using `db.DefaultContext`, I think we
should refactor them carefully and one by one.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
tags/v1.19.0-rc0
Jason Song 1 year ago
parent
commit
7adc2de464
No account linked to committer's email address
41 changed files with 179 additions and 176 deletions
  1. 26
    26
      models/git/branches.go
  2. 10
    10
      models/git/branches_test.go
  3. 16
    16
      models/git/commit_status.go
  4. 6
    6
      models/git/commit_status_test.go
  5. 17
    17
      models/git/lfs.go
  6. 10
    10
      models/git/lfs_lock.go
  7. 6
    6
      models/git/protected_tag.go
  8. 1
    1
      models/issues/comment.go
  9. 2
    2
      modules/context/repo.go
  10. 4
    4
      modules/repository/repo.go
  11. 2
    2
      routers/api/v1/repo/branch.go
  12. 1
    1
      routers/api/v1/repo/file.go
  13. 1
    1
      routers/api/v1/repo/status.go
  14. 1
    1
      routers/private/hook_pre_receive.go
  15. 3
    3
      routers/web/repo/branch.go
  16. 3
    3
      routers/web/repo/commit.go
  17. 1
    1
      routers/web/repo/compare.go
  18. 1
    1
      routers/web/repo/download.go
  19. 2
    2
      routers/web/repo/issue.go
  20. 11
    11
      routers/web/repo/lfs.go
  21. 1
    1
      routers/web/repo/pull.go
  22. 3
    3
      routers/web/repo/setting_protected_branch.go
  23. 3
    3
      routers/web/repo/tag.go
  24. 2
    2
      routers/web/repo/view.go
  25. 1
    1
      routers/web/repo/wiki.go
  26. 1
    1
      services/convert/convert.go
  27. 1
    1
      services/convert/status.go
  28. 4
    4
      services/lfs/locks.go
  29. 7
    7
      services/lfs/server.go
  30. 3
    2
      services/pull/lfs.go
  31. 1
    1
      services/pull/update.go
  32. 3
    3
      services/repository/branch.go
  33. 1
    1
      services/repository/files/commit.go
  34. 1
    1
      services/repository/files/patch.go
  35. 5
    4
      services/repository/files/update.go
  36. 4
    3
      services/repository/files/upload.go
  37. 1
    1
      services/repository/lfs.go
  38. 1
    1
      services/repository/push.go
  39. 8
    8
      tests/integration/api_repo_lfs_test.go
  40. 2
    2
      tests/integration/lfs_getobject_test.go
  41. 2
    2
      tests/integration/repo_tag_test.go

+ 26
- 26
models/git/branches.go View File

} }


// CanUserPush returns if some user could push to this protected branch // CanUserPush returns if some user could push to this protected branch
func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
func (protectBranch *ProtectedBranch) CanUserPush(ctx context.Context, userID int64) bool {
if !protectBranch.CanPush { if !protectBranch.CanPush {
return false return false
} }


if !protectBranch.EnableWhitelist { if !protectBranch.EnableWhitelist {
if user, err := user_model.GetUserByID(db.DefaultContext, userID); err != nil {
if user, err := user_model.GetUserByID(ctx, userID); err != nil {
log.Error("GetUserByID: %v", err) log.Error("GetUserByID: %v", err)
return false return false
} else if repo, err := repo_model.GetRepositoryByID(db.DefaultContext, protectBranch.RepoID); err != nil {
} else if repo, err := repo_model.GetRepositoryByID(ctx, protectBranch.RepoID); err != nil {
log.Error("repo_model.GetRepositoryByID: %v", err) log.Error("repo_model.GetRepositoryByID: %v", err)
return false return false
} else if writeAccess, err := access_model.HasAccessUnit(db.DefaultContext, user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil {
} else if writeAccess, err := access_model.HasAccessUnit(ctx, user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil {
log.Error("HasAccessUnit: %v", err) log.Error("HasAccessUnit: %v", err)
return false return false
} else { } else {
return false return false
} }


in, err := organization.IsUserInTeams(db.DefaultContext, userID, protectBranch.WhitelistTeamIDs)
in, err := organization.IsUserInTeams(ctx, userID, protectBranch.WhitelistTeamIDs)
if err != nil { if err != nil {
log.Error("IsUserInTeams: %v", err) log.Error("IsUserInTeams: %v", err)
return false return false
} }


// GetProtectedBranches get all protected branches // GetProtectedBranches get all protected branches
func GetProtectedBranches(repoID int64) ([]*ProtectedBranch, error) {
func GetProtectedBranches(ctx context.Context, repoID int64) ([]*ProtectedBranch, error) {
protectedBranches := make([]*ProtectedBranch, 0) protectedBranches := make([]*ProtectedBranch, 0)
return protectedBranches, db.GetEngine(db.DefaultContext).Find(&protectedBranches, &ProtectedBranch{RepoID: repoID})
return protectedBranches, db.GetEngine(ctx).Find(&protectedBranches, &ProtectedBranch{RepoID: repoID})
} }


// IsProtectedBranch checks if branch is protected // IsProtectedBranch checks if branch is protected
func IsProtectedBranch(repoID int64, branchName string) (bool, error) {
func IsProtectedBranch(ctx context.Context, repoID int64, branchName string) (bool, error) {
protectedBranch := &ProtectedBranch{ protectedBranch := &ProtectedBranch{
RepoID: repoID, RepoID: repoID,
BranchName: branchName, BranchName: branchName,
} }


has, err := db.GetEngine(db.DefaultContext).Exist(protectedBranch)
has, err := db.GetEngine(ctx).Exist(protectedBranch)
if err != nil { if err != nil {
return true, err return true, err
} }
} }


// DeleteProtectedBranch removes ProtectedBranch relation between the user and repository. // DeleteProtectedBranch removes ProtectedBranch relation between the user and repository.
func DeleteProtectedBranch(repoID, id int64) (err error) {
func DeleteProtectedBranch(ctx context.Context, repoID, id int64) (err error) {
protectedBranch := &ProtectedBranch{ protectedBranch := &ProtectedBranch{
RepoID: repoID, RepoID: repoID,
ID: id, ID: id,
} }


if affected, err := db.GetEngine(db.DefaultContext).Delete(protectedBranch); err != nil {
if affected, err := db.GetEngine(ctx).Delete(protectedBranch); err != nil {
return err return err
} else if affected != 1 { } else if affected != 1 {
return fmt.Errorf("delete protected branch ID(%v) failed", id) return fmt.Errorf("delete protected branch ID(%v) failed", id)
} }


// AddDeletedBranch adds a deleted branch to the database // AddDeletedBranch adds a deleted branch to the database
func AddDeletedBranch(repoID int64, branchName, commit string, deletedByID int64) error {
func AddDeletedBranch(ctx context.Context, repoID int64, branchName, commit string, deletedByID int64) error {
deletedBranch := &DeletedBranch{ deletedBranch := &DeletedBranch{
RepoID: repoID, RepoID: repoID,
Name: branchName, Name: branchName,
DeletedByID: deletedByID, DeletedByID: deletedByID,
} }


_, err := db.GetEngine(db.DefaultContext).Insert(deletedBranch)
_, err := db.GetEngine(ctx).Insert(deletedBranch)
return err return err
} }


// GetDeletedBranches returns all the deleted branches // GetDeletedBranches returns all the deleted branches
func GetDeletedBranches(repoID int64) ([]*DeletedBranch, error) {
func GetDeletedBranches(ctx context.Context, repoID int64) ([]*DeletedBranch, error) {
deletedBranches := make([]*DeletedBranch, 0) deletedBranches := make([]*DeletedBranch, 0)
return deletedBranches, db.GetEngine(db.DefaultContext).Where("repo_id = ?", repoID).Desc("deleted_unix").Find(&deletedBranches)
return deletedBranches, db.GetEngine(ctx).Where("repo_id = ?", repoID).Desc("deleted_unix").Find(&deletedBranches)
} }


// GetDeletedBranchByID get a deleted branch by its ID // GetDeletedBranchByID get a deleted branch by its ID
func GetDeletedBranchByID(repoID, id int64) (*DeletedBranch, error) {
func GetDeletedBranchByID(ctx context.Context, repoID, id int64) (*DeletedBranch, error) {
deletedBranch := &DeletedBranch{} deletedBranch := &DeletedBranch{}
has, err := db.GetEngine(db.DefaultContext).Where("repo_id = ?", repoID).And("id = ?", id).Get(deletedBranch)
has, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).And("id = ?", id).Get(deletedBranch)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }


// RemoveDeletedBranchByID removes a deleted branch from the database // RemoveDeletedBranchByID removes a deleted branch from the database
func RemoveDeletedBranchByID(repoID, id int64) (err error) {
func RemoveDeletedBranchByID(ctx context.Context, repoID, id int64) (err error) {
deletedBranch := &DeletedBranch{ deletedBranch := &DeletedBranch{
RepoID: repoID, RepoID: repoID,
ID: id, ID: id,
} }


if affected, err := db.GetEngine(db.DefaultContext).Delete(deletedBranch); err != nil {
if affected, err := db.GetEngine(ctx).Delete(deletedBranch); err != nil {
return err return err
} else if affected != 1 { } else if affected != 1 {
return fmt.Errorf("remove deleted branch ID(%v) failed", id) return fmt.Errorf("remove deleted branch ID(%v) failed", id)
} }


// RemoveDeletedBranchByName removes all deleted branches // RemoveDeletedBranchByName removes all deleted branches
func RemoveDeletedBranchByName(repoID int64, branch string) error {
_, err := db.GetEngine(db.DefaultContext).Where("repo_id=? AND name=?", repoID, branch).Delete(new(DeletedBranch))
func RemoveDeletedBranchByName(ctx context.Context, repoID int64, branch string) error {
_, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repoID, branch).Delete(new(DeletedBranch))
return err return err
} }


log.Trace("Doing: DeletedBranchesCleanup") log.Trace("Doing: DeletedBranchesCleanup")


deleteBefore := time.Now().Add(-olderThan) deleteBefore := time.Now().Add(-olderThan)
_, err := db.GetEngine(db.DefaultContext).Where("deleted_unix < ?", deleteBefore.Unix()).Delete(new(DeletedBranch))
_, err := db.GetEngine(ctx).Where("deleted_unix < ?", deleteBefore.Unix()).Delete(new(DeletedBranch))
if err != nil { if err != nil {
log.Error("DeletedBranchesCleanup: %v", err) log.Error("DeletedBranchesCleanup: %v", err)
} }
} }


// FindRenamedBranch check if a branch was renamed // FindRenamedBranch check if a branch was renamed
func FindRenamedBranch(repoID int64, from string) (branch *RenamedBranch, exist bool, err error) {
func FindRenamedBranch(ctx context.Context, repoID int64, from string) (branch *RenamedBranch, exist bool, err error) {
branch = &RenamedBranch{ branch = &RenamedBranch{
RepoID: repoID, RepoID: repoID,
From: from, From: from,
} }
exist, err = db.GetEngine(db.DefaultContext).Get(branch)
exist, err = db.GetEngine(ctx).Get(branch)


return branch, exist, err return branch, exist, err
} }


// RenameBranch rename a branch // RenameBranch rename a branch
func RenameBranch(repo *repo_model.Repository, from, to string, gitAction func(isDefault bool) error) (err error) {
ctx, committer, err := db.TxContext(db.DefaultContext)
func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to string, gitAction func(isDefault bool) error) (err error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }

+ 10
- 10
models/git/branches_test.go View File

repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})


assert.Error(t, git_model.AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
assert.NoError(t, git_model.AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1)))
assert.Error(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
assert.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, "test", "5655464564554545466464656", int64(1)))
} }


func TestGetDeletedBranches(t *testing.T) { func TestGetDeletedBranches(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})


branches, err := git_model.GetDeletedBranches(repo.ID)
branches, err := git_model.GetDeletedBranches(db.DefaultContext, repo.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, branches, 2) assert.Len(t, branches, 2)
} }


firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})


err := git_model.RemoveDeletedBranchByID(repo.ID, 1)
err := git_model.RemoveDeletedBranchByID(db.DefaultContext, repo.ID, 1)
assert.NoError(t, err) assert.NoError(t, err)
unittest.AssertNotExistsBean(t, firstBranch) unittest.AssertNotExistsBean(t, firstBranch)
unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2}) unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2})
func getDeletedBranch(t *testing.T, branch *git_model.DeletedBranch) *git_model.DeletedBranch { func getDeletedBranch(t *testing.T, branch *git_model.DeletedBranch) *git_model.DeletedBranch {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})


deletedBranch, err := git_model.GetDeletedBranchByID(repo.ID, branch.ID)
deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo.ID, branch.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, branch.ID, deletedBranch.ID) assert.Equal(t, branch.ID, deletedBranch.ID)
assert.Equal(t, branch.Name, deletedBranch.Name) assert.Equal(t, branch.Name, deletedBranch.Name)


func TestFindRenamedBranch(t *testing.T) { func TestFindRenamedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
branch, exist, err := git_model.FindRenamedBranch(1, "dev")
branch, exist, err := git_model.FindRenamedBranch(db.DefaultContext, 1, "dev")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, exist) assert.Equal(t, true, exist)
assert.Equal(t, "master", branch.To) assert.Equal(t, "master", branch.To)


_, exist, err = git_model.FindRenamedBranch(1, "unknow")
_, exist, err = git_model.FindRenamedBranch(db.DefaultContext, 1, "unknow")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, false, exist) assert.Equal(t, false, exist)
} }
}, git_model.WhitelistOptions{})) }, git_model.WhitelistOptions{}))
assert.NoError(t, committer.Commit()) assert.NoError(t, committer.Commit())


assert.NoError(t, git_model.RenameBranch(repo1, "master", "main", func(isDefault bool) error {
assert.NoError(t, git_model.RenameBranch(db.DefaultContext, repo1, "master", "main", func(isDefault bool) error {
_isDefault = isDefault _isDefault = isDefault
return nil return nil
})) }))
// is actually on repo with ID 1. // is actually on repo with ID 1.
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})


deletedBranch, err := git_model.GetDeletedBranchByID(repo2.ID, 1)
deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo2.ID, 1)


// Expect no error, and the returned branch is nil. // Expect no error, and the returned branch is nil.
assert.NoError(t, err) assert.NoError(t, err)
// This should return the deletedBranch. // This should return the deletedBranch.
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})


deletedBranch, err = git_model.GetDeletedBranchByID(repo1.ID, 1)
deletedBranch, err = git_model.GetDeletedBranchByID(db.DefaultContext, repo1.ID, 1)


// Expect no error, and the returned branch to be not nil. // Expect no error, and the returned branch to be not nil.
assert.NoError(t, err) assert.NoError(t, err)

+ 16
- 16
models/git/commit_status.go View File

} }


// APIURL returns the absolute APIURL to this commit-status. // APIURL returns the absolute APIURL to this commit-status.
func (status *CommitStatus) APIURL() string {
_ = status.loadAttributes(db.DefaultContext)
func (status *CommitStatus) APIURL(ctx context.Context) string {
_ = status.loadAttributes(ctx)
return status.Repo.APIURL() + "/statuses/" + url.PathEscape(status.SHA) return status.Repo.APIURL() + "/statuses/" + url.PathEscape(status.SHA)
} }


} }


// GetCommitStatuses returns all statuses for a given commit. // GetCommitStatuses returns all statuses for a given commit.
func GetCommitStatuses(repo *repo_model.Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
func GetCommitStatuses(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
if opts.Page <= 0 { if opts.Page <= 0 {
opts.Page = 1 opts.Page = 1
} }
opts.Page = setting.ItemsPerPage opts.Page = setting.ItemsPerPage
} }


countSession := listCommitStatusesStatement(repo, sha, opts)
countSession := listCommitStatusesStatement(ctx, repo, sha, opts)
countSession = db.SetSessionPagination(countSession, opts) countSession = db.SetSessionPagination(countSession, opts)
maxResults, err := countSession.Count(new(CommitStatus)) maxResults, err := countSession.Count(new(CommitStatus))
if err != nil { if err != nil {
} }


statuses := make([]*CommitStatus, 0, opts.PageSize) statuses := make([]*CommitStatus, 0, opts.PageSize)
findSession := listCommitStatusesStatement(repo, sha, opts)
findSession := listCommitStatusesStatement(ctx, repo, sha, opts)
findSession = db.SetSessionPagination(findSession, opts) findSession = db.SetSessionPagination(findSession, opts)
sortCommitStatusesSession(findSession, opts.SortType) sortCommitStatusesSession(findSession, opts.SortType)
return statuses, maxResults, findSession.Find(&statuses) return statuses, maxResults, findSession.Find(&statuses)
} }


func listCommitStatusesStatement(repo *repo_model.Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
sess := db.GetEngine(db.DefaultContext).Where("repo_id = ?", repo.ID).And("sha = ?", sha)
func listCommitStatusesStatement(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
sess := db.GetEngine(ctx).Where("repo_id = ?", repo.ID).And("sha = ?", sha)
switch opts.State { switch opts.State {
case "pending", "success", "error", "failure", "warning": case "pending", "success", "error", "failure", "warning":
sess.And("state = ?", opts.State) sess.And("state = ?", opts.State)
} }


// FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts
func FindRepoRecentCommitStatusContexts(repoID int64, before time.Duration) ([]string, error) {
func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) {
start := timeutil.TimeStampNow().AddDuration(-before) start := timeutil.TimeStampNow().AddDuration(-before)
ids := make([]int64, 0, 10) ids := make([]int64, 0, 10)
if err := db.GetEngine(db.DefaultContext).Table("commit_status").
if err := db.GetEngine(ctx).Table("commit_status").
Where("repo_id = ?", repoID). Where("repo_id = ?", repoID).
And("updated_unix >= ?", start). And("updated_unix >= ?", start).
Select("max( id ) as id"). Select("max( id ) as id").
if len(ids) == 0 { if len(ids) == 0 {
return contexts, nil return contexts, nil
} }
return contexts, db.GetEngine(db.DefaultContext).Select("context").Table("commit_status").In("id", ids).Find(&contexts)
return contexts, db.GetEngine(ctx).Select("context").Table("commit_status").In("id", ids).Find(&contexts)
} }


// NewCommitStatusOptions holds options for creating a CommitStatus // NewCommitStatusOptions holds options for creating a CommitStatus
} }


// NewCommitStatus save commit statuses into database // NewCommitStatus save commit statuses into database
func NewCommitStatus(opts NewCommitStatusOptions) error {
func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
if opts.Repo == nil { if opts.Repo == nil {
return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA) return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA)
} }
return fmt.Errorf("NewCommitStatus[%s, %s]: invalid sha: %w", repoPath, opts.SHA, err) return fmt.Errorf("NewCommitStatus[%s, %s]: invalid sha: %w", repoPath, opts.SHA, err)
} }


ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err) return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err)
} }
} }


// ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state // ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state
func ParseCommitsWithStatus(oldCommits []*asymkey_model.SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
func ParseCommitsWithStatus(ctx context.Context, oldCommits []*asymkey_model.SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
newCommits := make([]*SignCommitWithStatuses, 0, len(oldCommits)) newCommits := make([]*SignCommitWithStatuses, 0, len(oldCommits))


for _, c := range oldCommits { for _, c := range oldCommits {
commit := &SignCommitWithStatuses{ commit := &SignCommitWithStatuses{
SignCommit: c, SignCommit: c,
} }
statuses, _, err := GetLatestCommitStatus(db.DefaultContext, repo.ID, commit.ID.String(), db.ListOptions{})
statuses, _, err := GetLatestCommitStatus(ctx, repo.ID, commit.ID.String(), db.ListOptions{})
if err != nil { if err != nil {
log.Error("GetLatestCommitStatus: %v", err) log.Error("GetLatestCommitStatus: %v", err)
} else { } else {
} }


// ConvertFromGitCommit converts git commits into SignCommitWithStatuses // ConvertFromGitCommit converts git commits into SignCommitWithStatuses
func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
return ParseCommitsWithStatus(
func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
return ParseCommitsWithStatus(ctx,
asymkey_model.ParseCommitsWithSignature( asymkey_model.ParseCommitsWithSignature(
user_model.ValidateCommitsWithEmails(commits), user_model.ValidateCommitsWithEmails(commits),
repo.GetTrustModel(), repo.GetTrustModel(),

+ 6
- 6
models/git/commit_status_test.go View File



sha1 := "1234123412341234123412341234123412341234" sha1 := "1234123412341234123412341234123412341234"


statuses, maxResults, err := git_model.GetCommitStatuses(repo1, sha1, &git_model.CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
statuses, maxResults, err := git_model.GetCommitStatuses(db.DefaultContext, repo1, sha1, &git_model.CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int(maxResults), 5) assert.Equal(t, int(maxResults), 5)
assert.Len(t, statuses, 5) assert.Len(t, statuses, 5)


assert.Equal(t, "ci/awesomeness", statuses[0].Context) assert.Equal(t, "ci/awesomeness", statuses[0].Context)
assert.Equal(t, structs.CommitStatusPending, statuses[0].State) assert.Equal(t, structs.CommitStatusPending, statuses[0].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[0].APIURL())
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[0].APIURL(db.DefaultContext))


assert.Equal(t, "cov/awesomeness", statuses[1].Context) assert.Equal(t, "cov/awesomeness", statuses[1].Context)
assert.Equal(t, structs.CommitStatusWarning, statuses[1].State) assert.Equal(t, structs.CommitStatusWarning, statuses[1].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[1].APIURL())
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[1].APIURL(db.DefaultContext))


assert.Equal(t, "cov/awesomeness", statuses[2].Context) assert.Equal(t, "cov/awesomeness", statuses[2].Context)
assert.Equal(t, structs.CommitStatusSuccess, statuses[2].State) assert.Equal(t, structs.CommitStatusSuccess, statuses[2].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[2].APIURL())
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[2].APIURL(db.DefaultContext))


assert.Equal(t, "ci/awesomeness", statuses[3].Context) assert.Equal(t, "ci/awesomeness", statuses[3].Context)
assert.Equal(t, structs.CommitStatusFailure, statuses[3].State) assert.Equal(t, structs.CommitStatusFailure, statuses[3].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[3].APIURL())
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[3].APIURL(db.DefaultContext))


assert.Equal(t, "deploy/awesomeness", statuses[4].Context) assert.Equal(t, "deploy/awesomeness", statuses[4].Context)
assert.Equal(t, structs.CommitStatusError, statuses[4].State) assert.Equal(t, structs.CommitStatusError, statuses[4].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL())
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext))
} }

+ 17
- 17
models/git/lfs.go View File



// NewLFSMetaObject stores a given populated LFSMetaObject structure in the database // NewLFSMetaObject stores a given populated LFSMetaObject structure in the database
// if it is not already present. // if it is not already present.
func NewLFSMetaObject(m *LFSMetaObject) (*LFSMetaObject, error) {
func NewLFSMetaObject(ctx context.Context, m *LFSMetaObject) (*LFSMetaObject, error) {
var err error var err error


ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// GetLFSMetaObjectByOid selects a LFSMetaObject entry from database by its OID. // GetLFSMetaObjectByOid selects a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error. If the error is nil, // It may return ErrLFSObjectNotExist or a database error. If the error is nil,
// the returned pointer is a valid LFSMetaObject. // the returned pointer is a valid LFSMetaObject.
func GetLFSMetaObjectByOid(repoID int64, oid string) (*LFSMetaObject, error) {
func GetLFSMetaObjectByOid(ctx context.Context, repoID int64, oid string) (*LFSMetaObject, error) {
if len(oid) == 0 { if len(oid) == 0 {
return nil, ErrLFSObjectNotExist return nil, ErrLFSObjectNotExist
} }


m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID} m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID}
has, err := db.GetEngine(db.DefaultContext).Get(m)
has, err := db.GetEngine(ctx).Get(m)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {


// RemoveLFSMetaObjectByOid removes a LFSMetaObject entry from database by its OID. // RemoveLFSMetaObjectByOid removes a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error. // It may return ErrLFSObjectNotExist or a database error.
func RemoveLFSMetaObjectByOid(repoID int64, oid string) (int64, error) {
return RemoveLFSMetaObjectByOidFn(repoID, oid, nil)
func RemoveLFSMetaObjectByOid(ctx context.Context, repoID int64, oid string) (int64, error) {
return RemoveLFSMetaObjectByOidFn(ctx, repoID, oid, nil)
} }


// RemoveLFSMetaObjectByOidFn removes a LFSMetaObject entry from database by its OID. // RemoveLFSMetaObjectByOidFn removes a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error. It will run Fn with the current count within the transaction // It may return ErrLFSObjectNotExist or a database error. It will run Fn with the current count within the transaction
func RemoveLFSMetaObjectByOidFn(repoID int64, oid string, fn func(count int64) error) (int64, error) {
func RemoveLFSMetaObjectByOidFn(ctx context.Context, repoID int64, oid string, fn func(count int64) error) (int64, error) {
if len(oid) == 0 { if len(oid) == 0 {
return 0, ErrLFSObjectNotExist return 0, ErrLFSObjectNotExist
} }


ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
} }


// GetLFSMetaObjects returns all LFSMetaObjects associated with a repository // GetLFSMetaObjects returns all LFSMetaObjects associated with a repository
func GetLFSMetaObjects(repoID int64, page, pageSize int) ([]*LFSMetaObject, error) {
sess := db.GetEngine(db.DefaultContext)
func GetLFSMetaObjects(ctx context.Context, repoID int64, page, pageSize int) ([]*LFSMetaObject, error) {
sess := db.GetEngine(ctx)


if page >= 0 && pageSize > 0 { if page >= 0 && pageSize > 0 {
start := 0 start := 0
} }


// CountLFSMetaObjects returns a count of all LFSMetaObjects associated with a repository // CountLFSMetaObjects returns a count of all LFSMetaObjects associated with a repository
func CountLFSMetaObjects(repoID int64) (int64, error) {
return db.GetEngine(db.DefaultContext).Count(&LFSMetaObject{RepositoryID: repoID})
func CountLFSMetaObjects(ctx context.Context, repoID int64) (int64, error) {
return db.GetEngine(ctx).Count(&LFSMetaObject{RepositoryID: repoID})
} }


// LFSObjectAccessible checks if a provided Oid is accessible to the user // LFSObjectAccessible checks if a provided Oid is accessible to the user
func LFSObjectAccessible(user *user_model.User, oid string) (bool, error) {
func LFSObjectAccessible(ctx context.Context, user *user_model.User, oid string) (bool, error) {
if user.IsAdmin { if user.IsAdmin {
count, err := db.GetEngine(db.DefaultContext).Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
count, err := db.GetEngine(ctx).Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
return count > 0, err return count > 0, err
} }
cond := repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid) cond := repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)
count, err := db.GetEngine(db.DefaultContext).Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
count, err := db.GetEngine(ctx).Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
return count > 0, err return count > 0, err
} }


} }


// LFSAutoAssociate auto associates accessible LFSMetaObjects // LFSAutoAssociate auto associates accessible LFSMetaObjects
func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int64) error {
ctx, committer, err := db.TxContext(db.DefaultContext)
func LFSAutoAssociate(ctx context.Context, metas []*LFSMetaObject, user *user_model.User, repoID int64) error {
ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }

+ 10
- 10
models/git/lfs_lock.go View File

} }


// CreateLFSLock creates a new lock. // CreateLFSLock creates a new lock.
func CreateLFSLock(repo *repo_model.Repository, lock *LFSLock) (*LFSLock, error) {
dbCtx, committer, err := db.TxContext(db.DefaultContext)
func CreateLFSLock(ctx context.Context, repo *repo_model.Repository, lock *LFSLock) (*LFSLock, error) {
dbCtx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }


// GetLFSLockByRepoID returns a list of locks of repository. // GetLFSLockByRepoID returns a list of locks of repository.
func GetLFSLockByRepoID(repoID int64, page, pageSize int) ([]*LFSLock, error) {
e := db.GetEngine(db.DefaultContext)
func GetLFSLockByRepoID(ctx context.Context, repoID int64, page, pageSize int) ([]*LFSLock, error) {
e := db.GetEngine(ctx)
if page >= 0 && pageSize > 0 { if page >= 0 && pageSize > 0 {
start := 0 start := 0
if page > 0 { if page > 0 {
} }


// GetTreePathLock returns LSF lock for the treePath // GetTreePathLock returns LSF lock for the treePath
func GetTreePathLock(repoID int64, treePath string) (*LFSLock, error) {
func GetTreePathLock(ctx context.Context, repoID int64, treePath string) (*LFSLock, error) {
if !setting.LFS.StartServer { if !setting.LFS.StartServer {
return nil, nil return nil, nil
} }


locks, err := GetLFSLockByRepoID(repoID, 0, 0)
locks, err := GetLFSLockByRepoID(ctx, repoID, 0, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }


// CountLFSLockByRepoID returns a count of all LFSLocks associated with a repository. // CountLFSLockByRepoID returns a count of all LFSLocks associated with a repository.
func CountLFSLockByRepoID(repoID int64) (int64, error) {
return db.GetEngine(db.DefaultContext).Count(&LFSLock{RepoID: repoID})
func CountLFSLockByRepoID(ctx context.Context, repoID int64) (int64, error) {
return db.GetEngine(ctx).Count(&LFSLock{RepoID: repoID})
} }


// DeleteLFSLockByID deletes a lock by given ID. // DeleteLFSLockByID deletes a lock by given ID.
func DeleteLFSLockByID(id int64, repo *repo_model.Repository, u *user_model.User, force bool) (*LFSLock, error) {
dbCtx, committer, err := db.TxContext(db.DefaultContext)
func DeleteLFSLockByID(ctx context.Context, id int64, repo *repo_model.Repository, u *user_model.User, force bool) (*LFSLock, error) {
dbCtx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }

+ 6
- 6
models/git/protected_tag.go View File

} }


// InsertProtectedTag inserts a protected tag to database // InsertProtectedTag inserts a protected tag to database
func InsertProtectedTag(pt *ProtectedTag) error {
_, err := db.GetEngine(db.DefaultContext).Insert(pt)
func InsertProtectedTag(ctx context.Context, pt *ProtectedTag) error {
_, err := db.GetEngine(ctx).Insert(pt)
return err return err
} }


// UpdateProtectedTag updates the protected tag // UpdateProtectedTag updates the protected tag
func UpdateProtectedTag(pt *ProtectedTag) error {
_, err := db.GetEngine(db.DefaultContext).ID(pt.ID).AllCols().Update(pt)
func UpdateProtectedTag(ctx context.Context, pt *ProtectedTag) error {
_, err := db.GetEngine(ctx).ID(pt.ID).AllCols().Update(pt)
return err return err
} }


} }


// GetProtectedTagByID gets the protected tag with the specific id // GetProtectedTagByID gets the protected tag with the specific id
func GetProtectedTagByID(id int64) (*ProtectedTag, error) {
func GetProtectedTagByID(ctx context.Context, id int64) (*ProtectedTag, error) {
tag := new(ProtectedTag) tag := new(ProtectedTag)
has, err := db.GetEngine(db.DefaultContext).ID(id).Get(tag)
has, err := db.GetEngine(ctx).ID(id).Get(tag)
if err != nil { if err != nil {
return nil, err return nil, err
} }

+ 1
- 1
models/issues/comment.go View File

} }
defer closer.Close() defer closer.Close()


c.Commits = git_model.ConvertFromGitCommit(gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
c.Commits = git_model.ConvertFromGitCommit(ctx, gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
c.CommitsNum = int64(len(c.Commits)) c.CommitsNum = int64(len(c.Commits))
} }



+ 2
- 2
modules/context/repo.go View File

userCanPush := true userCanPush := true
requireSigned := false requireSigned := false
if protectedBranch != nil { if protectedBranch != nil {
userCanPush = protectedBranch.CanUserPush(doer.ID)
userCanPush = protectedBranch.CanUserPush(ctx, doer.ID)
requireSigned = protectedBranch.RequireSignedCommits requireSigned = protectedBranch.RequireSignedCommits
} }


if len(ref) == 0 { if len(ref) == 0 {
// maybe it's a renamed branch // maybe it's a renamed branch
return getRefNameFromPath(ctx, path, func(s string) bool { return getRefNameFromPath(ctx, path, func(s string) bool {
b, exist, err := git_model.FindRenamedBranch(ctx.Repo.Repository.ID, s)
b, exist, err := git_model.FindRenamedBranch(ctx, ctx.Repo.Repository.ID, s)
if err != nil { if err != nil {
log.Error("FindRenamedBranch", err) log.Error("FindRenamedBranch", err)
return false return false

+ 4
- 4
modules/repository/repo.go View File



defer content.Close() defer content.Close()


_, err := git_model.NewLFSMetaObject(&git_model.LFSMetaObject{Pointer: p, RepositoryID: repo.ID})
_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repo.ID})
if err != nil { if err != nil {
log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, p, err) log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, p, err)
return err return err


if err := contentStore.Put(p, content); err != nil { if err := contentStore.Put(p, content); err != nil {
log.Error("Repo[%-v]: Error storing content for LFS meta object %-v: %v", repo, p, err) log.Error("Repo[%-v]: Error storing content for LFS meta object %-v: %v", repo, p, err)
if _, err2 := git_model.RemoveLFSMetaObjectByOid(repo.ID, p.Oid); err2 != nil {
if _, err2 := git_model.RemoveLFSMetaObjectByOid(ctx, repo.ID, p.Oid); err2 != nil {
log.Error("Repo[%-v]: Error removing LFS meta object %-v: %v", repo, p, err2) log.Error("Repo[%-v]: Error removing LFS meta object %-v: %v", repo, p, err2)
} }
return err return err


var batch []lfs.Pointer var batch []lfs.Pointer
for pointerBlob := range pointerChan { for pointerBlob := range pointerChan {
meta, err := git_model.GetLFSMetaObjectByOid(repo.ID, pointerBlob.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repo.ID, pointerBlob.Oid)
if err != nil && err != git_model.ErrLFSObjectNotExist { if err != nil && err != git_model.ErrLFSObjectNotExist {
log.Error("Repo[%-v]: Error querying LFS meta object %-v: %v", repo, pointerBlob.Pointer, err) log.Error("Repo[%-v]: Error querying LFS meta object %-v: %v", repo, pointerBlob.Pointer, err)
return err return err


if exist { if exist {
log.Trace("Repo[%-v]: LFS object %-v already present; creating meta object", repo, pointerBlob.Pointer) log.Trace("Repo[%-v]: LFS object %-v already present; creating meta object", repo, pointerBlob.Pointer)
_, err := git_model.NewLFSMetaObject(&git_model.LFSMetaObject{Pointer: pointerBlob.Pointer, RepositoryID: repo.ID})
_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: pointerBlob.Pointer, RepositoryID: repo.ID})
if err != nil { if err != nil {
log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, pointerBlob.Pointer, err) log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, pointerBlob.Pointer, err)
return err return err

+ 2
- 2
routers/api/v1/repo/branch.go View File

// "$ref": "#/responses/BranchProtectionList" // "$ref": "#/responses/BranchProtectionList"


repo := ctx.Repo.Repository repo := ctx.Repo.Repository
bps, err := git_model.GetProtectedBranches(repo.ID)
bps, err := git_model.GetProtectedBranches(ctx, repo.ID)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "GetProtectedBranches", err) ctx.Error(http.StatusInternalServerError, "GetProtectedBranches", err)
return return
return return
} }


if err := git_model.DeleteProtectedBranch(ctx.Repo.Repository.ID, bp.ID); err != nil {
if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository.ID, bp.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteProtectedBranch", err) ctx.Error(http.StatusInternalServerError, "DeleteProtectedBranch", err)
return return
} }

+ 1
- 1
routers/api/v1/repo/file.go View File

} }


// Now check if there is a meta object for this pointer // Now check if there is a meta object for this pointer
meta, err := git_model.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(ctx, ctx.Repo.Repository.ID, pointer.Oid)


// If there isn't one just serve the data directly // If there isn't one just serve the data directly
if err == git_model.ErrLFSObjectNotExist { if err == git_model.ErrLFSObjectNotExist {

+ 1
- 1
routers/api/v1/repo/status.go View File



listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)


statuses, maxResults, err := git_model.GetCommitStatuses(repo, sha, &git_model.CommitStatusOptions{
statuses, maxResults, err := git_model.GetCommitStatuses(ctx, repo, sha, &git_model.CommitStatusOptions{
ListOptions: listOptions, ListOptions: listOptions,
SortType: ctx.FormTrim("sort"), SortType: ctx.FormTrim("sort"),
State: ctx.FormTrim("state"), State: ctx.FormTrim("state"),

+ 1
- 1
routers/private/hook_pre_receive.go View File

if ctx.opts.DeployKeyID != 0 { if ctx.opts.DeployKeyID != 0 {
canPush = !changedProtectedfiles && protectBranch.CanPush && (!protectBranch.EnableWhitelist || protectBranch.WhitelistDeployKeys) canPush = !changedProtectedfiles && protectBranch.CanPush && (!protectBranch.EnableWhitelist || protectBranch.WhitelistDeployKeys)
} else { } else {
canPush = !changedProtectedfiles && protectBranch.CanUserPush(ctx.opts.UserID)
canPush = !changedProtectedfiles && protectBranch.CanUserPush(ctx, ctx.opts.UserID)
} }


// 6. If we're not allowed to push directly // 6. If we're not allowed to push directly

+ 3
- 3
routers/web/repo/branch.go View File

branchID := ctx.FormInt64("branch_id") branchID := ctx.FormInt64("branch_id")
branchName := ctx.FormString("name") branchName := ctx.FormString("name")


deletedBranch, err := git_model.GetDeletedBranchByID(ctx.Repo.Repository.ID, branchID)
deletedBranch, err := git_model.GetDeletedBranchByID(ctx, ctx.Repo.Repository.ID, branchID)
if err != nil { if err != nil {
log.Error("GetDeletedBranchByID: %v", err) log.Error("GetDeletedBranchByID: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", branchName)) ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", branchName))
return nil, nil, 0 return nil, nil, 0
} }


protectedBranches, err := git_model.GetProtectedBranches(ctx.Repo.Repository.ID)
protectedBranches, err := git_model.GetProtectedBranches(ctx, ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.ServerError("GetProtectedBranches", err) ctx.ServerError("GetProtectedBranches", err)
return nil, nil, 0 return nil, nil, 0
func getDeletedBranches(ctx *context.Context) ([]*Branch, error) { func getDeletedBranches(ctx *context.Context) ([]*Branch, error) {
branches := []*Branch{} branches := []*Branch{}


deletedBranches, err := git_model.GetDeletedBranches(ctx.Repo.Repository.ID)
deletedBranches, err := git_model.GetDeletedBranches(ctx, ctx.Repo.Repository.ID)
if err != nil { if err != nil {
return branches, err return branches, err
} }

+ 3
- 3
routers/web/repo/commit.go View File

ctx.ServerError("CommitsByRange", err) ctx.ServerError("CommitsByRange", err)
return return
} }
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)


ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name
return return
} }
ctx.Data["CommitCount"] = len(commits) ctx.Data["CommitCount"] = len(commits)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)


ctx.Data["Keyword"] = query ctx.Data["Keyword"] = query
if all { if all {
ctx.ServerError("CommitsByFileAndRange", err) ctx.ServerError("CommitsByFileAndRange", err)
return return
} }
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)


ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name

+ 1
- 1
routers/web/repo/compare.go View File

return false return false
} }


commits := git_model.ConvertFromGitCommit(ci.CompareInfo.Commits, ci.HeadRepo)
commits := git_model.ConvertFromGitCommit(ctx, ci.CompareInfo.Commits, ci.HeadRepo)
ctx.Data["Commits"] = commits ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits) ctx.Data["CommitCount"] = len(commits)



+ 1
- 1
routers/web/repo/download.go View File



pointer, _ := lfs.ReadPointer(dataRc) pointer, _ := lfs.ReadPointer(dataRc)
if pointer.IsValid() { if pointer.IsValid() {
meta, _ := git_model.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
meta, _ := git_model.GetLFSMetaObjectByOid(ctx, ctx.Repo.Repository.ID, pointer.Oid)
if meta == nil { if meta == nil {
if err = dataRc.Close(); err != nil { if err = dataRc.Close(); err != nil {
log.Error("ServeBlobOrLFS: Close: %v", err) log.Error("ServeBlobOrLFS: Close: %v", err)

+ 2
- 2
routers/web/repo/issue.go View File

if perm.CanWrite(unit.TypeCode) { if perm.CanWrite(unit.TypeCode) {
// Check if branch is not protected // Check if branch is not protected
if pull.HeadBranch != pull.HeadRepo.DefaultBranch { if pull.HeadBranch != pull.HeadRepo.DefaultBranch {
if protected, err := git_model.IsProtectedBranch(pull.HeadRepo.ID, pull.HeadBranch); err != nil {
if protected, err := git_model.IsProtectedBranch(ctx, pull.HeadRepo.ID, pull.HeadBranch); err != nil {
log.Error("IsProtectedBranch: %v", err) log.Error("IsProtectedBranch: %v", err)
} else if !protected { } else if !protected {
canDelete = true canDelete = true
if pull.ProtectedBranch != nil { if pull.ProtectedBranch != nil {
var showMergeInstructions bool var showMergeInstructions bool
if ctx.Doer != nil { if ctx.Doer != nil {
showMergeInstructions = pull.ProtectedBranch.CanUserPush(ctx.Doer.ID)
showMergeInstructions = pull.ProtectedBranch.CanUserPush(ctx, ctx.Doer.ID)
} }
ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull) ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull)
ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull) ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull)

+ 11
- 11
routers/web/repo/lfs.go View File

if page <= 1 { if page <= 1 {
page = 1 page = 1
} }
total, err := git_model.CountLFSMetaObjects(ctx.Repo.Repository.ID)
total, err := git_model.CountLFSMetaObjects(ctx, ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.ServerError("LFSFiles", err) ctx.ServerError("LFSFiles", err)
return return
pager := context.NewPagination(int(total), setting.UI.ExplorePagingNum, page, 5) pager := context.NewPagination(int(total), setting.UI.ExplorePagingNum, page, 5)
ctx.Data["Title"] = ctx.Tr("repo.settings.lfs") ctx.Data["Title"] = ctx.Tr("repo.settings.lfs")
ctx.Data["PageIsSettingsLFS"] = true ctx.Data["PageIsSettingsLFS"] = true
lfsMetaObjects, err := git_model.GetLFSMetaObjects(ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum)
lfsMetaObjects, err := git_model.GetLFSMetaObjects(ctx, ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum)
if err != nil { if err != nil {
ctx.ServerError("LFSFiles", err) ctx.ServerError("LFSFiles", err)
return return
if page <= 1 { if page <= 1 {
page = 1 page = 1
} }
total, err := git_model.CountLFSLockByRepoID(ctx.Repo.Repository.ID)
total, err := git_model.CountLFSLockByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.ServerError("LFSLocks", err) ctx.ServerError("LFSLocks", err)
return return
pager := context.NewPagination(int(total), setting.UI.ExplorePagingNum, page, 5) pager := context.NewPagination(int(total), setting.UI.ExplorePagingNum, page, 5)
ctx.Data["Title"] = ctx.Tr("repo.settings.lfs_locks") ctx.Data["Title"] = ctx.Tr("repo.settings.lfs_locks")
ctx.Data["PageIsSettingsLFS"] = true ctx.Data["PageIsSettingsLFS"] = true
lfsLocks, err := git_model.GetLFSLockByRepoID(ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum)
lfsLocks, err := git_model.GetLFSLockByRepoID(ctx, ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum)
if err != nil { if err != nil {
ctx.ServerError("LFSLocks", err) ctx.ServerError("LFSLocks", err)
return return
return return
} }


_, err := git_model.CreateLFSLock(ctx.Repo.Repository, &git_model.LFSLock{
_, err := git_model.CreateLFSLock(ctx, ctx.Repo.Repository, &git_model.LFSLock{
Path: lockPath, Path: lockPath,
OwnerID: ctx.Doer.ID, OwnerID: ctx.Doer.ID,
}) })
ctx.NotFound("LFSUnlock", nil) ctx.NotFound("LFSUnlock", nil)
return return
} }
_, err := git_model.DeleteLFSLockByID(ctx.ParamsInt64("lid"), ctx.Repo.Repository, ctx.Doer, true)
_, err := git_model.DeleteLFSLockByID(ctx, ctx.ParamsInt64("lid"), ctx.Repo.Repository, ctx.Doer, true)
if err != nil { if err != nil {
ctx.ServerError("LFSUnlock", err) ctx.ServerError("LFSUnlock", err)
return return


ctx.Data["Title"] = oid ctx.Data["Title"] = oid
ctx.Data["PageIsSettingsLFS"] = true ctx.Data["PageIsSettingsLFS"] = true
meta, err := git_model.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, oid)
meta, err := git_model.GetLFSMetaObjectByOid(ctx, ctx.Repo.Repository.ID, oid)
if err != nil { if err != nil {
if err == git_model.ErrLFSObjectNotExist { if err == git_model.ErrLFSObjectNotExist {
ctx.NotFound("LFSFileGet", nil) ctx.NotFound("LFSFileGet", nil)
return return
} }


count, err := git_model.RemoveLFSMetaObjectByOid(ctx.Repo.Repository.ID, oid)
count, err := git_model.RemoveLFSMetaObjectByOid(ctx, ctx.Repo.Repository.ID, oid)
if err != nil { if err != nil {
ctx.ServerError("LFSDelete", err) ctx.ServerError("LFSDelete", err)
return return
Size: pointerBlob.Size, Size: pointerBlob.Size,
} }


if _, err := git_model.GetLFSMetaObjectByOid(repo.ID, pointerBlob.Oid); err != nil {
if _, err := git_model.GetLFSMetaObjectByOid(ctx, repo.ID, pointerBlob.Oid); err != nil {
if err != git_model.ErrLFSObjectNotExist { if err != git_model.ErrLFSObjectNotExist {
return err return err
} }
// Can we fix? // Can we fix?
// OK well that's "simple" // OK well that's "simple"
// - we need to check whether current user has access to a repo that has access to the file // - we need to check whether current user has access to a repo that has access to the file
result.Associatable, err = git_model.LFSObjectAccessible(ctx.Doer, pointerBlob.Oid)
result.Associatable, err = git_model.LFSObjectAccessible(ctx, ctx.Doer, pointerBlob.Oid)
if err != nil { if err != nil {
return err return err
} }
metas[i].Oid = oid[:idx] metas[i].Oid = oid[:idx]
// metas[i].RepositoryID = ctx.Repo.Repository.ID // metas[i].RepositoryID = ctx.Repo.Repository.ID
} }
if err := git_model.LFSAutoAssociate(metas, ctx.Doer, ctx.Repo.Repository.ID); err != nil {
if err := git_model.LFSAutoAssociate(ctx, metas, ctx.Doer, ctx.Repo.Repository.ID); err != nil {
ctx.ServerError("LFSAutoAssociate", err) ctx.ServerError("LFSAutoAssociate", err)
return return
} }

+ 1
- 1
routers/web/repo/pull.go View File

ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name


commits := git_model.ConvertFromGitCommit(prInfo.Commits, ctx.Repo.Repository)
commits := git_model.ConvertFromGitCommit(ctx, prInfo.Commits, ctx.Repo.Repository)
ctx.Data["Commits"] = commits ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits) ctx.Data["CommitCount"] = len(commits)



+ 3
- 3
routers/web/repo/setting_protected_branch.go View File

ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsBranches"] = true ctx.Data["PageIsSettingsBranches"] = true


protectedBranches, err := git_model.GetProtectedBranches(ctx.Repo.Repository.ID)
protectedBranches, err := git_model.GetProtectedBranches(ctx, ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.ServerError("GetProtectedBranches", err) ctx.ServerError("GetProtectedBranches", err)
return return
c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistUserIDs), ",") c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistUserIDs), ",")
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",") c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",")
c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistUserIDs), ",") c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistUserIDs), ",")
contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
for _, ctx := range protectBranch.StatusCheckContexts { for _, ctx := range protectBranch.StatusCheckContexts {
var found bool var found bool
for i := range contexts { for i := range contexts {
ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch))) ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch)))
} else { } else {
if protectBranch != nil { if protectBranch != nil {
if err := git_model.DeleteProtectedBranch(ctx.Repo.Repository.ID, protectBranch.ID); err != nil {
if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository.ID, protectBranch.ID); err != nil {
ctx.ServerError("DeleteProtectedBranch", err) ctx.ServerError("DeleteProtectedBranch", err)
return return
} }

+ 3
- 3
routers/web/repo/tag.go View File

pt.AllowlistTeamIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistTeams, ",")) pt.AllowlistTeamIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistTeams, ","))
} }


if err := git_model.InsertProtectedTag(pt); err != nil {
if err := git_model.InsertProtectedTag(ctx, pt); err != nil {
ctx.ServerError("InsertProtectedTag", err) ctx.ServerError("InsertProtectedTag", err)
return return
} }
pt.AllowlistUserIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistUsers, ",")) pt.AllowlistUserIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistUsers, ","))
pt.AllowlistTeamIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistTeams, ",")) pt.AllowlistTeamIDs, _ = base.StringsToInt64s(strings.Split(form.AllowlistTeams, ","))


if err := git_model.UpdateProtectedTag(pt); err != nil {
if err := git_model.UpdateProtectedTag(ctx, pt); err != nil {
ctx.ServerError("UpdateProtectedTag", err) ctx.ServerError("UpdateProtectedTag", err)
return return
} }
id = ctx.ParamsInt64(":id") id = ctx.ParamsInt64(":id")
} }


tag, err := git_model.GetProtectedTagByID(id)
tag, err := git_model.GetProtectedTagByID(ctx, id)
if err != nil { if err != nil {
ctx.ServerError("GetProtectedTagByID", err) ctx.ServerError("GetProtectedTagByID", err)
return nil return nil

+ 2
- 2
routers/web/repo/view.go View File

return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
} }


meta, err := git_model.GetLFSMetaObjectByOid(repoID, pointer.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, repoID, pointer.Oid)
if err != nil && err != git_model.ErrLFSObjectNotExist { // fallback to plain file if err != nil && err != git_model.ErrLFSObjectNotExist { // fallback to plain file
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
} }
} }


// Check LFS Lock // Check LFS Lock
lfsLock, err := git_model.GetTreePathLock(ctx.Repo.Repository.ID, ctx.Repo.TreePath)
lfsLock, err := git_model.GetTreePathLock(ctx, ctx.Repo.Repository.ID, ctx.Repo.TreePath)
ctx.Data["LFSLock"] = lfsLock ctx.Data["LFSLock"] = lfsLock
if err != nil { if err != nil {
ctx.ServerError("GetTreePathLock", err) ctx.ServerError("GetTreePathLock", err)

+ 1
- 1
routers/web/repo/wiki.go View File

ctx.ServerError("CommitsByFileAndRange", err) ctx.ServerError("CommitsByFileAndRange", err)
return nil, nil return nil, nil
} }
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository)


pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5) pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)

+ 1
- 1
services/convert/convert.go View File

if err != nil { if err != nil {
return nil, err return nil, err
} }
branch.UserCanPush = bp.CanUserPush(user.ID)
branch.UserCanPush = bp.CanUserPush(db.DefaultContext, user.ID)
branch.UserCanMerge = git_model.IsUserMergeWhitelisted(db.DefaultContext, bp, user.ID, permission) branch.UserCanMerge = git_model.IsUserMergeWhitelisted(db.DefaultContext, bp, user.ID, permission)
} }



+ 1
- 1
services/convert/status.go View File

TargetURL: status.TargetURL, TargetURL: status.TargetURL,
Description: status.Description, Description: status.Description,
ID: status.Index, ID: status.Index,
URL: status.APIURL(),
URL: status.APIURL(ctx),
Context: status.Context, Context: status.Context,
} }



+ 4
- 4
services/lfs/locks.go View File

} }


// If no query params path or id // If no query params path or id
lockList, err := git_model.GetLFSLockByRepoID(repository.ID, cursor, limit)
lockList, err := git_model.GetLFSLockByRepoID(ctx, repository.ID, cursor, limit)
if err != nil { if err != nil {
log.Error("Unable to list locks for repository ID[%d]: Error: %v", repository.ID, err) log.Error("Unable to list locks for repository ID[%d]: Error: %v", repository.ID, err)
ctx.JSON(http.StatusInternalServerError, api.LFSLockError{ ctx.JSON(http.StatusInternalServerError, api.LFSLockError{
return return
} }


lock, err := git_model.CreateLFSLock(repository, &git_model.LFSLock{
lock, err := git_model.CreateLFSLock(ctx, repository, &git_model.LFSLock{
Path: req.Path, Path: req.Path,
OwnerID: ctx.Doer.ID, OwnerID: ctx.Doer.ID,
}) })
} else if limit < 0 { } else if limit < 0 {
limit = 0 limit = 0
} }
lockList, err := git_model.GetLFSLockByRepoID(repository.ID, cursor, limit)
lockList, err := git_model.GetLFSLockByRepoID(ctx, repository.ID, cursor, limit)
if err != nil { if err != nil {
log.Error("Unable to list locks for repository ID[%d]: Error: %v", repository.ID, err) log.Error("Unable to list locks for repository ID[%d]: Error: %v", repository.ID, err)
ctx.JSON(http.StatusInternalServerError, api.LFSLockError{ ctx.JSON(http.StatusInternalServerError, api.LFSLockError{
return return
} }


lock, err := git_model.DeleteLFSLockByID(ctx.ParamsInt64("lid"), repository, ctx.Doer, req.Force)
lock, err := git_model.DeleteLFSLockByID(ctx, ctx.ParamsInt64("lid"), repository, ctx.Doer, req.Force)
if err != nil { if err != nil {
if git_model.IsErrLFSUnauthorizedAction(err) { if git_model.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs") ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")

+ 7
- 7
services/lfs/server.go View File

return return
} }


meta, err := git_model.GetLFSMetaObjectByOid(repository.ID, p.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repository.ID, p.Oid)
if err != nil && err != git_model.ErrLFSObjectNotExist { if err != nil && err != git_model.ErrLFSObjectNotExist {
log.Error("Unable to get LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err) log.Error("Unable to get LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err)
writeStatus(ctx, http.StatusInternalServerError) writeStatus(ctx, http.StatusInternalServerError)
} }


if exists && meta == nil { if exists && meta == nil {
accessible, err := git_model.LFSObjectAccessible(ctx.Doer, p.Oid)
accessible, err := git_model.LFSObjectAccessible(ctx, ctx.Doer, p.Oid)
if err != nil { if err != nil {
log.Error("Unable to check if LFS MetaObject [%s] is accessible. Error: %v", p.Oid, err) log.Error("Unable to check if LFS MetaObject [%s] is accessible. Error: %v", p.Oid, err)
writeStatus(ctx, http.StatusInternalServerError) writeStatus(ctx, http.StatusInternalServerError)
return return
} }
if accessible { if accessible {
_, err := git_model.NewLFSMetaObject(&git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID})
_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID})
if err != nil { if err != nil {
log.Error("Unable to create LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err) log.Error("Unable to create LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err)
writeStatus(ctx, http.StatusInternalServerError) writeStatus(ctx, http.StatusInternalServerError)


uploadOrVerify := func() error { uploadOrVerify := func() error {
if exists { if exists {
accessible, err := git_model.LFSObjectAccessible(ctx.Doer, p.Oid)
accessible, err := git_model.LFSObjectAccessible(ctx, ctx.Doer, p.Oid)
if err != nil { if err != nil {
log.Error("Unable to check if LFS MetaObject [%s] is accessible. Error: %v", p.Oid, err) log.Error("Unable to check if LFS MetaObject [%s] is accessible. Error: %v", p.Oid, err)
return err return err
log.Error("Error putting LFS MetaObject [%s] into content store. Error: %v", p.Oid, err) log.Error("Error putting LFS MetaObject [%s] into content store. Error: %v", p.Oid, err)
return err return err
} }
_, err := git_model.NewLFSMetaObject(&git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID})
_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID})
return err return err
} }


} else { } else {
writeStatus(ctx, http.StatusInternalServerError) writeStatus(ctx, http.StatusInternalServerError)
} }
if _, err = git_model.RemoveLFSMetaObjectByOid(repository.ID, p.Oid); err != nil {
if _, err = git_model.RemoveLFSMetaObjectByOid(ctx, repository.ID, p.Oid); err != nil {
log.Error("Error whilst removing metaobject for LFS OID[%s]: %v", p.Oid, err) log.Error("Error whilst removing metaobject for LFS OID[%s]: %v", p.Oid, err)
} }
return return
return nil return nil
} }


meta, err := git_model.GetLFSMetaObjectByOid(repository.ID, p.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repository.ID, p.Oid)
if err != nil { if err != nil {
log.Error("Unable to get LFS OID[%s] Error: %v", p.Oid, err) log.Error("Unable to get LFS OID[%s] Error: %v", p.Oid, err)
writeStatus(ctx, http.StatusNotFound) writeStatus(ctx, http.StatusNotFound)

+ 3
- 2
services/pull/lfs.go View File

"strconv" "strconv"
"sync" "sync"


"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/git/pipeline" "code.gitea.io/gitea/modules/git/pipeline"
} }


// Then we need to check that this pointer is in the db // Then we need to check that this pointer is in the db
if _, err := git_model.GetLFSMetaObjectByOid(pr.HeadRepo.ID, pointer.Oid); err != nil {
if _, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, pr.HeadRepo.ID, pointer.Oid); err != nil {
if err == git_model.ErrLFSObjectNotExist { if err == git_model.ErrLFSObjectNotExist {
log.Warn("During merge of: %d in %-v, there is a pointer to LFS Oid: %s which although present in the LFS store is not associated with the head repo %-v", pr.Index, pr.BaseRepo, pointer.Oid, pr.HeadRepo) log.Warn("During merge of: %d in %-v, there is a pointer to LFS Oid: %s which although present in the LFS store is not associated with the head repo %-v", pr.Index, pr.BaseRepo, pointer.Oid, pr.HeadRepo)
continue continue
// Therefore it should be associated with the base repo // Therefore it should be associated with the base repo
meta := &git_model.LFSMetaObject{Pointer: pointer} meta := &git_model.LFSMetaObject{Pointer: pointer}
meta.RepositoryID = pr.BaseRepoID meta.RepositoryID = pr.BaseRepoID
if _, err := git_model.NewLFSMetaObject(meta); err != nil {
if _, err := git_model.NewLFSMetaObject(db.DefaultContext, meta); err != nil {
_ = catFileBatchReader.CloseWithError(err) _ = catFileBatchReader.CloseWithError(err)
break break
} }

+ 1
- 1
services/pull/update.go View File

} }


// Update function need push permission // Update function need push permission
if pr.ProtectedBranch != nil && !pr.ProtectedBranch.CanUserPush(user.ID) {
if pr.ProtectedBranch != nil && !pr.ProtectedBranch.CanUserPush(ctx, user.ID) {
return false, false, nil return false, false, nil
} }



+ 3
- 3
services/repository/branch.go View File

return "from_not_exist", nil return "from_not_exist", nil
} }


if err := git_model.RenameBranch(repo, from, to, func(isDefault bool) error {
if err := git_model.RenameBranch(db.DefaultContext, repo, from, to, func(isDefault bool) error {
err2 := gitRepo.RenameBranch(from, to) err2 := gitRepo.RenameBranch(from, to)
if err2 != nil { if err2 != nil {
return err2 return err2
return ErrBranchIsDefault return ErrBranchIsDefault
} }


isProtected, err := git_model.IsProtectedBranch(repo.ID, branchName)
isProtected, err := git_model.IsProtectedBranch(db.DefaultContext, repo.ID, branchName)
if err != nil { if err != nil {
return err return err
} }
log.Error("Update: %v", err) log.Error("Update: %v", err)
} }


if err := git_model.AddDeletedBranch(repo.ID, branchName, commit.ID.String(), doer.ID); err != nil {
if err := git_model.AddDeletedBranch(db.DefaultContext, repo.ID, branchName, commit.ID.String(), doer.ID); err != nil {
log.Warn("AddDeletedBranch: %v", err) log.Warn("AddDeletedBranch: %v", err)
} }



+ 1
- 1
services/repository/files/commit.go View File

} }
gitRepo.Close() gitRepo.Close()


if err := git_model.NewCommitStatus(git_model.NewCommitStatusOptions{
if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
Repo: repo, Repo: repo,
Creator: creator, Creator: creator,
SHA: sha, SHA: sha,

+ 1
- 1
services/repository/files/patch.go View File

if err != nil { if err != nil {
return err return err
} }
if protectedBranch != nil && !protectedBranch.CanUserPush(doer.ID) {
if protectedBranch != nil && !protectedBranch.CanUserPush(ctx, doer.ID) {
return models.ErrUserCannotCommit{ return models.ErrUserCannotCommit{
UserName: doer.LowerName, UserName: doer.LowerName,
} }

+ 5
- 4
services/repository/files/update.go View File

"time" "time"


"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
if setting.LFS.StartServer { if setting.LFS.StartServer {
pointer, _ := lfs.ReadPointerFromBuffer(buf) pointer, _ := lfs.ReadPointerFromBuffer(buf)
if pointer.IsValid() { if pointer.IsValid() {
meta, err := git_model.GetLFSMetaObjectByOid(repo.ID, pointer.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, pointer.Oid)
if err != nil && err != git_model.ErrLFSObjectNotExist { if err != nil && err != git_model.ErrLFSObjectNotExist {
// return default // return default
return "UTF-8", false return "UTF-8", false


if lfsMetaObject != nil { if lfsMetaObject != nil {
// We have an LFS object - create it // We have an LFS object - create it
lfsMetaObject, err = git_model.NewLFSMetaObject(lfsMetaObject)
lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, lfsMetaObject)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
if !exist { if !exist {
if err := contentStore.Put(lfsMetaObject.Pointer, strings.NewReader(opts.Content)); err != nil { if err := contentStore.Put(lfsMetaObject.Pointer, strings.NewReader(opts.Content)); err != nil {
if _, err2 := git_model.RemoveLFSMetaObjectByOid(repo.ID, lfsMetaObject.Oid); err2 != nil {
if _, err2 := git_model.RemoveLFSMetaObjectByOid(ctx, repo.ID, lfsMetaObject.Oid); err2 != nil {
return nil, fmt.Errorf("Error whilst removing failed inserted LFS object %s: %v (Prev Error: %w)", lfsMetaObject.Oid, err2, err) return nil, fmt.Errorf("Error whilst removing failed inserted LFS object %s: %v (Prev Error: %w)", lfsMetaObject.Oid, err2, err)
} }
return nil, err return nil, err
if len(glob) != 0 { if len(glob) != 0 {
isUnprotectedFile = protectedBranch.IsUnprotectedFile(glob, treePath) isUnprotectedFile = protectedBranch.IsUnprotectedFile(glob, treePath)
} }
if !protectedBranch.CanUserPush(doer.ID) && !isUnprotectedFile {
if !protectedBranch.CanUserPush(ctx, doer.ID) && !isUnprotectedFile {
return models.ErrUserCannotCommit{ return models.ErrUserCannotCommit{
UserName: doer.LowerName, UserName: doer.LowerName,
} }

+ 4
- 3
services/repository/files/upload.go View File

"path" "path"
"strings" "strings"


"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
continue continue
} }
if !info.lfsMetaObject.Existing { if !info.lfsMetaObject.Existing {
if _, err := git_model.RemoveLFSMetaObjectByOid(t.repo.ID, info.lfsMetaObject.Oid); err != nil {
if _, err := git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, t.repo.ID, info.lfsMetaObject.Oid); err != nil {
original = fmt.Errorf("%w, %v", original, err) // We wrap the original error - as this is the underlying error that required the fallback original = fmt.Errorf("%w, %v", original, err) // We wrap the original error - as this is the underlying error that required the fallback
} }
} }
for i, upload := range uploads { for i, upload := range uploads {
// Check file is not lfs locked, will return nil if lock setting not enabled // Check file is not lfs locked, will return nil if lock setting not enabled
filepath := path.Join(opts.TreePath, upload.Name) filepath := path.Join(opts.TreePath, upload.Name)
lfsLock, err := git_model.GetTreePathLock(repo.ID, filepath)
lfsLock, err := git_model.GetTreePathLock(ctx, repo.ID, filepath)
if err != nil { if err != nil {
return err return err
} }
if infos[i].lfsMetaObject == nil { if infos[i].lfsMetaObject == nil {
continue continue
} }
infos[i].lfsMetaObject, err = git_model.NewLFSMetaObject(infos[i].lfsMetaObject)
infos[i].lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, infos[i].lfsMetaObject)
if err != nil { if err != nil {
// OK Now we need to cleanup // OK Now we need to cleanup
return cleanUpAfterFailure(&infos, t, err) return cleanUpAfterFailure(&infos, t, err)

+ 1
- 1
services/repository/lfs.go View File

return nil return nil
} }
// Non-existent pointer file // Non-existent pointer file
_, err = git_model.RemoveLFSMetaObjectByOidFn(repo.ID, metaObject.Oid, func(count int64) error {
_, err = git_model.RemoveLFSMetaObjectByOidFn(ctx, repo.ID, metaObject.Oid, func(count int64) error {
if count > 0 { if count > 0 {
return nil return nil
} }

+ 1
- 1
services/repository/push.go View File



notification.NotifyPushCommits(db.DefaultContext, pusher, repo, opts, commits) notification.NotifyPushCommits(db.DefaultContext, pusher, repo, opts, commits)


if err = git_model.RemoveDeletedBranchByName(repo.ID, branch); err != nil {
if err = git_model.RemoveDeletedBranchByName(ctx, repo.ID, branch); err != nil {
log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err) log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err)
} }



+ 8
- 8
tests/integration/api_repo_lfs_test.go View File



content := []byte("dummy1") content := []byte("dummy1")
oid := storeObjectInRepo(t, repo.ID, &content) oid := storeObjectInRepo(t, repo.ID, &content)
defer git_model.RemoveLFSMetaObjectByOid(repo.ID, oid)
defer git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, repo.ID, oid)


session := loginUser(t, "user2") session := loginUser(t, "user2")


content := []byte("dummy0") content := []byte("dummy0")
storeObjectInRepo(t, repo2.ID, &content) storeObjectInRepo(t, repo2.ID, &content)


meta, err := git_model.GetLFSMetaObjectByOid(repo.ID, p.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, p.Oid)
assert.Nil(t, meta) assert.Nil(t, meta)
assert.Equal(t, git_model.ErrLFSObjectNotExist, err) assert.Equal(t, git_model.ErrLFSObjectNotExist, err)


assert.Nil(t, br.Objects[0].Error) assert.Nil(t, br.Objects[0].Error)
assert.Empty(t, br.Objects[0].Actions) assert.Empty(t, br.Objects[0].Actions)


meta, err = git_model.GetLFSMetaObjectByOid(repo.ID, p.Oid)
meta, err = git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, p.Oid)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, meta) assert.NotNil(t, meta)




content := []byte("dummy3") content := []byte("dummy3")
oid := storeObjectInRepo(t, repo.ID, &content) oid := storeObjectInRepo(t, repo.ID, &content)
defer git_model.RemoveLFSMetaObjectByOid(repo.ID, oid)
defer git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, repo.ID, oid)


session := loginUser(t, "user2") session := loginUser(t, "user2")


err = contentStore.Put(p, bytes.NewReader([]byte("dummy5"))) err = contentStore.Put(p, bytes.NewReader([]byte("dummy5")))
assert.NoError(t, err) assert.NoError(t, err)


meta, err := git_model.GetLFSMetaObjectByOid(repo.ID, p.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, p.Oid)
assert.Nil(t, meta) assert.Nil(t, meta)
assert.Equal(t, git_model.ErrLFSObjectNotExist, err) assert.Equal(t, git_model.ErrLFSObjectNotExist, err)


req := newRequest(t, p, "dummy5") req := newRequest(t, p, "dummy5")


session.MakeRequest(t, req, http.StatusOK) session.MakeRequest(t, req, http.StatusOK)
meta, err = git_model.GetLFSMetaObjectByOid(repo.ID, p.Oid)
meta, err = git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, p.Oid)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, meta) assert.NotNil(t, meta)
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, exist) assert.True(t, exist)


meta, err := git_model.GetLFSMetaObjectByOid(repo.ID, p.Oid)
meta, err := git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, p.Oid)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, meta) assert.NotNil(t, meta)
}) })


content := []byte("dummy3") content := []byte("dummy3")
oid := storeObjectInRepo(t, repo.ID, &content) oid := storeObjectInRepo(t, repo.ID, &content)
defer git_model.RemoveLFSMetaObjectByOid(repo.ID, oid)
defer git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, repo.ID, oid)


session := loginUser(t, "user2") session := loginUser(t, "user2")



+ 2
- 2
tests/integration/lfs_getobject_test.go View File

pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) pointer, err := lfs.GeneratePointer(bytes.NewReader(*content))
assert.NoError(t, err) assert.NoError(t, err)


_, err = git_model.NewLFSMetaObject(&git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID})
_, err = git_model.NewLFSMetaObject(db.DefaultContext, &git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID})
assert.NoError(t, err) assert.NoError(t, err)
contentStore := lfs.NewContentStore() contentStore := lfs.NewContentStore()
exist, err := contentStore.Exists(pointer) exist, err := contentStore.Exists(pointer)
repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1") repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1")
assert.NoError(t, err) assert.NoError(t, err)
oid := storeObjectInRepo(t, repo.ID, content) oid := storeObjectInRepo(t, repo.ID, content)
defer git_model.RemoveLFSMetaObjectByOid(repo.ID, oid)
defer git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, repo.ID, oid)


session := loginUser(t, "user2") session := loginUser(t, "user2")



+ 2
- 2
tests/integration/repo_tag_test.go View File

err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "first tag") err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "first tag")
assert.NoError(t, err) assert.NoError(t, err)


err = git_model.InsertProtectedTag(&git_model.ProtectedTag{
err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{
RepoID: repo.ID, RepoID: repo.ID,
NamePattern: "v-*", NamePattern: "v-*",
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = git_model.InsertProtectedTag(&git_model.ProtectedTag{
err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{
RepoID: repo.ID, RepoID: repo.ID,
NamePattern: "v-1.1", NamePattern: "v-1.1",
AllowlistUserIDs: []int64{repo.OwnerID}, AllowlistUserIDs: []int64{repo.OwnerID},

Loading…
Cancel
Save