mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-28 22:37:54 -04:00 
			
		
		
		
	Extract `UpdateRepository` Follow up #34762 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
		
			
				
	
	
		
			147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2023 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package repository
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 
 | |
| 	"code.gitea.io/gitea/models/db"
 | |
| 	git_model "code.gitea.io/gitea/models/git"
 | |
| 	repo_model "code.gitea.io/gitea/models/repo"
 | |
| 	"code.gitea.io/gitea/modules/container"
 | |
| 	"code.gitea.io/gitea/modules/git"
 | |
| 	"code.gitea.io/gitea/modules/gitrepo"
 | |
| 	"code.gitea.io/gitea/modules/log"
 | |
| 	"code.gitea.io/gitea/modules/timeutil"
 | |
| )
 | |
| 
 | |
| // SyncRepoBranches synchronizes branch table with repository branches
 | |
| func SyncRepoBranches(ctx context.Context, repoID, doerID int64) (int64, error) {
 | |
| 	repo, err := repo_model.GetRepositoryByID(ctx, repoID)
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 
 | |
| 	log.Debug("SyncRepoBranches: in Repo[%d:%s]", repo.ID, repo.FullName())
 | |
| 
 | |
| 	gitRepo, err := gitrepo.OpenRepository(ctx, repo)
 | |
| 	if err != nil {
 | |
| 		log.Error("OpenRepository[%s]: %w", repo.FullName(), err)
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	defer gitRepo.Close()
 | |
| 
 | |
| 	return SyncRepoBranchesWithRepo(ctx, repo, gitRepo, doerID)
 | |
| }
 | |
| 
 | |
| func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, doerID int64) (int64, error) {
 | |
| 	objFmt, err := gitRepo.GetObjectFormat()
 | |
| 	if err != nil {
 | |
| 		return 0, fmt.Errorf("GetObjectFormat: %w", err)
 | |
| 	}
 | |
| 	if objFmt.Name() != repo.ObjectFormatName {
 | |
| 		repo.ObjectFormatName = objFmt.Name()
 | |
| 		if err = repo_model.UpdateRepositoryColsWithAutoTime(ctx, repo, "object_format_name"); err != nil {
 | |
| 			return 0, fmt.Errorf("UpdateRepositoryColsWithAutoTime: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	allBranches := container.Set[string]{}
 | |
| 	{
 | |
| 		branches, _, err := gitRepo.GetBranchNames(0, 0)
 | |
| 		if err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 		log.Trace("SyncRepoBranches[%s]: branches[%d]: %v", repo.FullName(), len(branches), branches)
 | |
| 		for _, branch := range branches {
 | |
| 			allBranches.Add(branch)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	dbBranches := make(map[string]*git_model.Branch)
 | |
| 	{
 | |
| 		branches, err := db.Find[git_model.Branch](ctx, git_model.FindBranchOptions{
 | |
| 			ListOptions: db.ListOptionsAll,
 | |
| 			RepoID:      repo.ID,
 | |
| 		})
 | |
| 		if err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 		for _, branch := range branches {
 | |
| 			dbBranches[branch.Name] = branch
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	var toAdd []*git_model.Branch
 | |
| 	var toUpdate []*git_model.Branch
 | |
| 	var toRemove []int64
 | |
| 	for branch := range allBranches {
 | |
| 		dbb := dbBranches[branch]
 | |
| 		commit, err := gitRepo.GetBranchCommit(branch)
 | |
| 		if err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 		if dbb == nil {
 | |
| 			toAdd = append(toAdd, &git_model.Branch{
 | |
| 				RepoID:        repo.ID,
 | |
| 				Name:          branch,
 | |
| 				CommitID:      commit.ID.String(),
 | |
| 				CommitMessage: commit.Summary(),
 | |
| 				PusherID:      doerID,
 | |
| 				CommitTime:    timeutil.TimeStamp(commit.Committer.When.Unix()),
 | |
| 			})
 | |
| 		} else if commit.ID.String() != dbb.CommitID {
 | |
| 			toUpdate = append(toUpdate, &git_model.Branch{
 | |
| 				ID:            dbb.ID,
 | |
| 				RepoID:        repo.ID,
 | |
| 				Name:          branch,
 | |
| 				CommitID:      commit.ID.String(),
 | |
| 				CommitMessage: commit.Summary(),
 | |
| 				PusherID:      doerID,
 | |
| 				CommitTime:    timeutil.TimeStamp(commit.Committer.When.Unix()),
 | |
| 			})
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for _, dbBranch := range dbBranches {
 | |
| 		if !allBranches.Contains(dbBranch.Name) && !dbBranch.IsDeleted {
 | |
| 			toRemove = append(toRemove, dbBranch.ID)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	log.Trace("SyncRepoBranches[%s]: toAdd: %v, toUpdate: %v, toRemove: %v", repo.FullName(), toAdd, toUpdate, toRemove)
 | |
| 
 | |
| 	if len(toAdd) == 0 && len(toRemove) == 0 && len(toUpdate) == 0 {
 | |
| 		return int64(len(allBranches)), nil
 | |
| 	}
 | |
| 
 | |
| 	if err := db.WithTx(ctx, func(ctx context.Context) error {
 | |
| 		if len(toAdd) > 0 {
 | |
| 			if err := git_model.AddBranches(ctx, toAdd); err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		for _, b := range toUpdate {
 | |
| 			if _, err := db.GetEngine(ctx).ID(b.ID).
 | |
| 				Cols("commit_id, commit_message, pusher_id, commit_time, is_deleted").
 | |
| 				Update(b); err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if len(toRemove) > 0 {
 | |
| 			if err := git_model.DeleteBranches(ctx, repo.ID, doerID, toRemove); err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return nil
 | |
| 	}); err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	return int64(len(allBranches)), nil
 | |
| }
 |