Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Sync branches to DB immediately when handle git hook calling #29493

Merged
merged 12 commits into from
Mar 6, 2024
45 changes: 44 additions & 1 deletion routers/private/hook_post_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
repo_module "code.gitea.io/gitea/modules/repository"
Expand All @@ -27,14 +28,19 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {

// We don't rely on RepoAssignment here because:
// a) we don't need the git repo in this function
// OUT OF DATE: we do need the git repo to sync the branch to the db now.
// b) our update function will likely change the repository in the db so we will need to refresh it
// c) we don't always need the repo

ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")

// defer getting the repository at this point - as we should only retrieve it if we're going to call update
var repo *repo_model.Repository
var (
repo *repo_model.Repository
gitRepo *git.Repository
)
defer gitRepo.Close() // it's safe to call Close on a nil pointer

updates := make([]*repo_module.PushUpdateOptions, 0, len(opts.OldCommitIDs))
wasEmpty := false
Expand Down Expand Up @@ -87,6 +93,43 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
})
return
}

for _, update := range updates {
if !update.RefFullName.IsBranch() {
continue
}
if repo == nil {
repo = loadRepository(ctx, ownerName, repoName)
if ctx.Written() {
return
}
wasEmpty = repo.IsEmpty
}
if gitRepo == nil {
var err error
gitRepo, err = gitrepo.OpenRepository(ctx, repo)
if err != nil {
log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
Err: fmt.Sprintf("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
}
wolfogre marked this conversation as resolved.
Show resolved Hide resolved
commit, err := gitRepo.GetCommit(update.NewCommitID)
if err != nil {
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
Err: fmt.Sprintf("Failed to get commit %s in repository: %s/%s Error: %v", update.NewCommitID, ownerName, repoName, err),
})
return
}
wolfogre marked this conversation as resolved.
Show resolved Hide resolved
if err := repo_service.SyncBranchToDB(ctx, repo.ID, update.PusherID, update.RefFullName.BranchName(), commit); err != nil {
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
Err: fmt.Sprintf("Failed to sync branch to DB in repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
}
}

// Handle Push Options
Expand Down
4 changes: 2 additions & 2 deletions services/repository/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,12 @@ func checkBranchName(ctx context.Context, repo *repo_model.Repository, name stri
return err
}

// syncBranchToDB sync the branch information in the database. It will try to update the branch first,
// SyncBranchToDB sync the branch information in the database. It will try to update the branch first,
// if updated success with affect records > 0, then all are done. Because that means the branch has been in the database.
// If no record is affected, that means the branch does not exist in database. So there are two possibilities.
// One is this is a new branch, then we just need to insert the record. Another is the branches haven't been synced,
// then we need to sync all the branches into database.
func syncBranchToDB(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) error {
func SyncBranchToDB(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) error {
cnt, err := git_model.UpdateBranch(ctx, repoID, pusherID, branchName, commit)
if err != nil {
return fmt.Errorf("git_model.UpdateBranch %d:%s failed: %v", repoID, branchName, err)
Expand Down
4 changes: 0 additions & 4 deletions services/repository/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
}

if err = syncBranchToDB(ctx, repo.ID, opts.PusherID, branch, newCommit); err != nil {
return fmt.Errorf("git_model.UpdateBranch %s:%s failed: %v", repo.FullName(), branch, err)
}

notify_service.PushCommits(ctx, pusher, repo, opts, commits)

// Cache for big repository
Expand Down
Loading