mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Move some functions into services/repository (#17677)
This commit is contained in:
		| @@ -25,6 +25,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| 	auth_service "code.gitea.io/gitea/services/auth" | 	auth_service "code.gitea.io/gitea/services/auth" | ||||||
| 	"code.gitea.io/gitea/services/auth/source/oauth2" | 	"code.gitea.io/gitea/services/auth/source/oauth2" | ||||||
|  | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
|  |  | ||||||
| 	"github.com/urfave/cli" | 	"github.com/urfave/cli" | ||||||
| ) | ) | ||||||
| @@ -612,7 +613,7 @@ func runRegenerateHooks(_ *cli.Context) error { | |||||||
| 	if err := initDB(ctx); err != nil { | 	if err := initDB(ctx); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) | 	return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func runRegenerateKeys(_ *cli.Context) error { | func runRegenerateKeys(_ *cli.Context) error { | ||||||
|   | |||||||
| @@ -13,9 +13,9 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	repo_module "code.gitea.io/gitea/modules/repository" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| @@ -72,7 +72,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { | |||||||
|  |  | ||||||
| 	// Make a new branch in repo1 | 	// Make a new branch in repo1 | ||||||
| 	newBranch := "test_branch" | 	newBranch := "test_branch" | ||||||
| 	err := repo_module.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch) | 	err := repo_service.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	// Get the commit ID of the default branch | 	// Get the commit ID of the default branch | ||||||
| 	gitRepo, err := git.OpenRepository(repo1.RepoPath()) | 	gitRepo, err := git.OpenRepository(repo1.RepoPath()) | ||||||
|   | |||||||
| @@ -12,9 +12,9 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	repo_module "code.gitea.io/gitea/modules/repository" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| @@ -73,7 +73,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { | |||||||
|  |  | ||||||
| 	// Make a new branch in repo1 | 	// Make a new branch in repo1 | ||||||
| 	newBranch := "test_branch" | 	newBranch := "test_branch" | ||||||
| 	err := repo_module.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch) | 	err := repo_service.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	// Get the commit ID of the default branch | 	// Get the commit ID of the default branch | ||||||
| 	gitRepo, err := git.OpenRepository(repo1.RepoPath()) | 	gitRepo, err := git.OpenRepository(repo1.RepoPath()) | ||||||
|   | |||||||
| @@ -24,92 +24,3 @@ func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) { | |||||||
|  |  | ||||||
| 	return gitRepo.GetBranch(branch) | 	return gitRepo.GetBranch(branch) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetBranches returns branches from the repository, skipping skip initial branches and |  | ||||||
| // returning at most limit branches, or all branches if limit is 0. |  | ||||||
| func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int, error) { |  | ||||||
| 	return git.GetBranchesByPath(repo.RepoPath(), skip, limit) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // checkBranchName validates branch name with existing repository branches |  | ||||||
| func checkBranchName(repo *models.Repository, name string) error { |  | ||||||
| 	gitRepo, err := git.OpenRepository(repo.RepoPath()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer gitRepo.Close() |  | ||||||
|  |  | ||||||
| 	branches, _, err := GetBranches(repo, 0, 0) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, branch := range branches { |  | ||||||
| 		if branch.Name == name { |  | ||||||
| 			return models.ErrBranchAlreadyExists{ |  | ||||||
| 				BranchName: branch.Name, |  | ||||||
| 			} |  | ||||||
| 		} else if (len(branch.Name) < len(name) && branch.Name+"/" == name[0:len(branch.Name)+1]) || |  | ||||||
| 			(len(branch.Name) > len(name) && name+"/" == branch.Name[0:len(name)+1]) { |  | ||||||
| 			return models.ErrBranchNameConflict{ |  | ||||||
| 				BranchName: branch.Name, |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if _, err := gitRepo.GetTag(name); err == nil { |  | ||||||
| 		return models.ErrTagAlreadyExists{ |  | ||||||
| 			TagName: name, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CreateNewBranch creates a new repository branch |  | ||||||
| func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName, branchName string) (err error) { |  | ||||||
| 	// Check if branch name can be used |  | ||||||
| 	if err := checkBranchName(repo, branchName); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !git.IsBranchExist(repo.RepoPath(), oldBranchName) { |  | ||||||
| 		return models.ErrBranchDoesNotExist{ |  | ||||||
| 			BranchName: oldBranchName, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := git.Push(repo.RepoPath(), git.PushOptions{ |  | ||||||
| 		Remote: repo.RepoPath(), |  | ||||||
| 		Branch: fmt.Sprintf("%s:%s%s", oldBranchName, git.BranchPrefix, branchName), |  | ||||||
| 		Env:    models.PushingEnvironment(doer, repo), |  | ||||||
| 	}); err != nil { |  | ||||||
| 		if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		return fmt.Errorf("Push: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CreateNewBranchFromCommit creates a new repository branch |  | ||||||
| func CreateNewBranchFromCommit(doer *models.User, repo *models.Repository, commit, branchName string) (err error) { |  | ||||||
| 	// Check if branch name can be used |  | ||||||
| 	if err := checkBranchName(repo, branchName); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := git.Push(repo.RepoPath(), git.PushOptions{ |  | ||||||
| 		Remote: repo.RepoPath(), |  | ||||||
| 		Branch: fmt.Sprintf("%s:%s%s", commit, git.BranchPrefix, branchName), |  | ||||||
| 		Env:    models.PushingEnvironment(doer, repo), |  | ||||||
| 	}); err != nil { |  | ||||||
| 		if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		return fmt.Errorf("Push: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -5,19 +5,13 @@ | |||||||
| package repository | package repository | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" |  | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"xorm.io/builder" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func getHookTemplates() (hookNames, hookTpls, giteaHookTpls []string) { | func getHookTemplates() (hookNames, hookTpls, giteaHookTpls []string) { | ||||||
| @@ -240,38 +234,3 @@ func CheckDelegateHooks(repoPath string) ([]string, error) { | |||||||
| 	} | 	} | ||||||
| 	return results, nil | 	return results, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // SyncRepositoryHooks rewrites all repositories' pre-receive, update and post-receive hooks |  | ||||||
| // to make sure the binary and custom conf path are up-to-date. |  | ||||||
| func SyncRepositoryHooks(ctx context.Context) error { |  | ||||||
| 	log.Trace("Doing: SyncRepositoryHooks") |  | ||||||
|  |  | ||||||
| 	if err := db.Iterate( |  | ||||||
| 		db.DefaultContext, |  | ||||||
| 		new(models.Repository), |  | ||||||
| 		builder.Gt{"id": 0}, |  | ||||||
| 		func(idx int, bean interface{}) error { |  | ||||||
| 			repo := bean.(*models.Repository) |  | ||||||
| 			select { |  | ||||||
| 			case <-ctx.Done(): |  | ||||||
| 				return db.ErrCancelledf("before sync repository hooks for %s", repo.FullName()) |  | ||||||
| 			default: |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if err := createDelegateHooks(repo.RepoPath()); err != nil { |  | ||||||
| 				return fmt.Errorf("SyncRepositoryHook: %v", err) |  | ||||||
| 			} |  | ||||||
| 			if repo.HasWiki() { |  | ||||||
| 				if err := createDelegateHooks(repo.WikiPath()); err != nil { |  | ||||||
| 					return fmt.Errorf("SyncRepositoryHook: %v", err) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		}, |  | ||||||
| 	); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	log.Trace("Finished: SyncRepositoryHooks") |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,136 +0,0 @@ | |||||||
| // Copyright 2020 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 repository |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" |  | ||||||
| 	"code.gitea.io/gitea/modules/git" |  | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // PushUpdateAddDeleteTags updates a number of added and delete tags |  | ||||||
| func PushUpdateAddDeleteTags(repo *models.Repository, gitRepo *git.Repository, addTags, delTags []string) error { |  | ||||||
| 	return db.WithTx(func(ctx context.Context) error { |  | ||||||
| 		if err := models.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		return pushUpdateAddTags(ctx, repo, gitRepo, addTags) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // pushUpdateAddTags updates a number of add tags |  | ||||||
| func pushUpdateAddTags(ctx context.Context, repo *models.Repository, gitRepo *git.Repository, tags []string) error { |  | ||||||
| 	if len(tags) == 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	lowerTags := make([]string, 0, len(tags)) |  | ||||||
| 	for _, tag := range tags { |  | ||||||
| 		lowerTags = append(lowerTags, strings.ToLower(tag)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	releases, err := models.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("GetReleasesByRepoIDAndNames: %v", err) |  | ||||||
| 	} |  | ||||||
| 	relMap := make(map[string]*models.Release) |  | ||||||
| 	for _, rel := range releases { |  | ||||||
| 		relMap[rel.LowerTagName] = rel |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	newReleases := make([]*models.Release, 0, len(lowerTags)-len(relMap)) |  | ||||||
|  |  | ||||||
| 	emailToUser := make(map[string]*models.User) |  | ||||||
|  |  | ||||||
| 	for i, lowerTag := range lowerTags { |  | ||||||
| 		tag, err := gitRepo.GetTag(tags[i]) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return fmt.Errorf("GetTag: %v", err) |  | ||||||
| 		} |  | ||||||
| 		commit, err := tag.Commit() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return fmt.Errorf("Commit: %v", err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sig := tag.Tagger |  | ||||||
| 		if sig == nil { |  | ||||||
| 			sig = commit.Author |  | ||||||
| 		} |  | ||||||
| 		if sig == nil { |  | ||||||
| 			sig = commit.Committer |  | ||||||
| 		} |  | ||||||
| 		var author *models.User |  | ||||||
| 		var createdAt = time.Unix(1, 0) |  | ||||||
|  |  | ||||||
| 		if sig != nil { |  | ||||||
| 			var ok bool |  | ||||||
| 			author, ok = emailToUser[sig.Email] |  | ||||||
| 			if !ok { |  | ||||||
| 				author, err = models.GetUserByEmailContext(ctx, sig.Email) |  | ||||||
| 				if err != nil && !models.IsErrUserNotExist(err) { |  | ||||||
| 					return fmt.Errorf("GetUserByEmail: %v", err) |  | ||||||
| 				} |  | ||||||
| 				if author != nil { |  | ||||||
| 					emailToUser[sig.Email] = author |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			createdAt = sig.When |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		commitsCount, err := commit.CommitsCount() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return fmt.Errorf("CommitsCount: %v", err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		rel, has := relMap[lowerTag] |  | ||||||
|  |  | ||||||
| 		if !has { |  | ||||||
| 			rel = &models.Release{ |  | ||||||
| 				RepoID:       repo.ID, |  | ||||||
| 				Title:        "", |  | ||||||
| 				TagName:      tags[i], |  | ||||||
| 				LowerTagName: lowerTag, |  | ||||||
| 				Target:       "", |  | ||||||
| 				Sha1:         commit.ID.String(), |  | ||||||
| 				NumCommits:   commitsCount, |  | ||||||
| 				Note:         "", |  | ||||||
| 				IsDraft:      false, |  | ||||||
| 				IsPrerelease: false, |  | ||||||
| 				IsTag:        true, |  | ||||||
| 				CreatedUnix:  timeutil.TimeStamp(createdAt.Unix()), |  | ||||||
| 			} |  | ||||||
| 			if author != nil { |  | ||||||
| 				rel.PublisherID = author.ID |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			newReleases = append(newReleases, rel) |  | ||||||
| 		} else { |  | ||||||
| 			rel.Sha1 = commit.ID.String() |  | ||||||
| 			rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) |  | ||||||
| 			rel.NumCommits = commitsCount |  | ||||||
| 			rel.IsDraft = false |  | ||||||
| 			if rel.IsTag && author != nil { |  | ||||||
| 				rel.PublisherID = author.ID |  | ||||||
| 			} |  | ||||||
| 			if err = models.UpdateRelease(ctx, rel); err != nil { |  | ||||||
| 				return fmt.Errorf("Update: %v", err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(newReleases) > 0 { |  | ||||||
| 		if err = models.InsertReleasesContext(ctx, newReleases); err != nil { |  | ||||||
| 			return fmt.Errorf("Insert: %v", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| @@ -176,7 +176,7 @@ func CreateBranch(ctx *context.APIContext) { | |||||||
| 		opt.OldBranchName = ctx.Repo.Repository.DefaultBranch | 		opt.OldBranchName = ctx.Repo.Repository.DefaultBranch | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err := repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, opt.OldBranchName, opt.BranchName) | 	err := repo_service.CreateNewBranch(ctx.User, ctx.Repo.Repository, opt.OldBranchName, opt.BranchName) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrBranchDoesNotExist(err) { | 		if models.IsErrBranchDoesNotExist(err) { | ||||||
| @@ -257,7 +257,7 @@ func ListBranches(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	listOptions := utils.GetListOptions(ctx) | 	listOptions := utils.GetListOptions(ctx) | ||||||
| 	skip, _ := listOptions.GetStartEnd() | 	skip, _ := listOptions.GetStartEnd() | ||||||
| 	branches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize) | 	branches, totalNumOfBranches, err := repo_service.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetBranches", err) | 		ctx.Error(http.StatusInternalServerError, "GetBranches", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -25,7 +25,6 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/markup/external" | 	"code.gitea.io/gitea/modules/markup/external" | ||||||
| 	"code.gitea.io/gitea/modules/notification" | 	"code.gitea.io/gitea/modules/notification" | ||||||
| 	repo_module "code.gitea.io/gitea/modules/repository" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/ssh" | 	"code.gitea.io/gitea/modules/ssh" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| @@ -45,7 +44,7 @@ import ( | |||||||
| 	repo_migrations "code.gitea.io/gitea/services/migrations" | 	repo_migrations "code.gitea.io/gitea/services/migrations" | ||||||
| 	mirror_service "code.gitea.io/gitea/services/mirror" | 	mirror_service "code.gitea.io/gitea/services/mirror" | ||||||
| 	pull_service "code.gitea.io/gitea/services/pull" | 	pull_service "code.gitea.io/gitea/services/pull" | ||||||
| 	"code.gitea.io/gitea/services/repository" | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
| 	"code.gitea.io/gitea/services/webhook" | 	"code.gitea.io/gitea/services/webhook" | ||||||
|  |  | ||||||
| 	"gitea.com/go-chi/session" | 	"gitea.com/go-chi/session" | ||||||
| @@ -73,7 +72,7 @@ func mustInitCtx(ctx context.Context, fn func(ctx context.Context) error) { | |||||||
| func InitGitServices() { | func InitGitServices() { | ||||||
| 	setting.NewServices() | 	setting.NewServices() | ||||||
| 	mustInit(storage.Init) | 	mustInit(storage.Init) | ||||||
| 	mustInit(repository.NewContext) | 	mustInit(repo_service.NewContext) | ||||||
| } | } | ||||||
|  |  | ||||||
| func syncAppPathForGit(ctx context.Context) error { | func syncAppPathForGit(ctx context.Context) error { | ||||||
| @@ -85,7 +84,7 @@ func syncAppPathForGit(ctx context.Context) error { | |||||||
| 		log.Info("AppPath changed from '%s' to '%s'", runtimeState.LastAppPath, setting.AppPath) | 		log.Info("AppPath changed from '%s' to '%s'", runtimeState.LastAppPath, setting.AppPath) | ||||||
|  |  | ||||||
| 		log.Info("re-sync repository hooks ...") | 		log.Info("re-sync repository hooks ...") | ||||||
| 		mustInitCtx(ctx, repo_module.SyncRepositoryHooks) | 		mustInitCtx(ctx, repo_service.SyncRepositoryHooks) | ||||||
|  |  | ||||||
| 		log.Info("re-write ssh public keys ...") | 		log.Info("re-write ssh public keys ...") | ||||||
| 		mustInit(models.RewriteAllPublicKeys) | 		mustInit(models.RewriteAllPublicKeys) | ||||||
|   | |||||||
| @@ -171,7 +171,7 @@ func loadBranches(ctx *context.Context, skip, limit int) ([]*Branch, int) { | |||||||
| 		return nil, 0 | 		return nil, 0 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	rawBranches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, limit) | 	rawBranches, totalNumOfBranches, err := repo_service.GetBranches(ctx.Repo.Repository, skip, limit) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("GetBranches: %v", err) | 		log.Error("GetBranches: %v", err) | ||||||
| 		ctx.ServerError("GetBranches", err) | 		ctx.ServerError("GetBranches", err) | ||||||
| @@ -350,11 +350,11 @@ func CreateBranch(ctx *context.Context) { | |||||||
| 			err = release_service.CreateNewTag(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName, "") | 			err = release_service.CreateNewTag(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName, "") | ||||||
| 		} | 		} | ||||||
| 	} else if ctx.Repo.IsViewBranch { | 	} else if ctx.Repo.IsViewBranch { | ||||||
| 		err = repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName) | 		err = repo_service.CreateNewBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName) | ||||||
| 	} else if ctx.Repo.IsViewTag { | 	} else if ctx.Repo.IsViewTag { | ||||||
| 		err = repo_module.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName) | 		err = repo_service.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName) | ||||||
| 	} else { | 	} else { | ||||||
| 		err = repo_module.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName) | 		err = repo_service.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrTagAlreadyExists(err) { | 		if models.IsErrTagAlreadyExists(err) { | ||||||
|   | |||||||
| @@ -85,7 +85,7 @@ func registerRepositoryUpdateHook() { | |||||||
| 		RunAtStart: false, | 		RunAtStart: false, | ||||||
| 		Schedule:   "@every 72h", | 		Schedule:   "@every 72h", | ||||||
| 	}, func(ctx context.Context, _ *models.User, _ Config) error { | 	}, func(ctx context.Context, _ *models.User, _ Config) error { | ||||||
| 		return repo_module.SyncRepositoryHooks(ctx) | 		return repo_service.SyncRepositoryHooks(ctx) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -333,7 +333,7 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	log.Trace("SyncMirrors [repo: %-v]: invalidating mirror branch caches...", m.Repo) | 	log.Trace("SyncMirrors [repo: %-v]: invalidating mirror branch caches...", m.Repo) | ||||||
| 	branches, _, err := repo_module.GetBranches(m.Repo, 0, 0) | 	branches, _, err := git.GetBranchesByPath(m.Repo.RepoPath(), 0, 0) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("GetBranches: %v", err) | 		log.Error("GetBranches: %v", err) | ||||||
| 		return nil, false | 		return nil, false | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ package repository | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| @@ -15,6 +16,95 @@ import ( | |||||||
| 	pull_service "code.gitea.io/gitea/services/pull" | 	pull_service "code.gitea.io/gitea/services/pull" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // CreateNewBranch creates a new repository branch | ||||||
|  | func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName, branchName string) (err error) { | ||||||
|  | 	// Check if branch name can be used | ||||||
|  | 	if err := checkBranchName(repo, branchName); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !git.IsBranchExist(repo.RepoPath(), oldBranchName) { | ||||||
|  | 		return models.ErrBranchDoesNotExist{ | ||||||
|  | 			BranchName: oldBranchName, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := git.Push(repo.RepoPath(), git.PushOptions{ | ||||||
|  | 		Remote: repo.RepoPath(), | ||||||
|  | 		Branch: fmt.Sprintf("%s:%s%s", oldBranchName, git.BranchPrefix, branchName), | ||||||
|  | 		Env:    models.PushingEnvironment(doer, repo), | ||||||
|  | 	}); err != nil { | ||||||
|  | 		if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		return fmt.Errorf("Push: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBranches returns branches from the repository, skipping skip initial branches and | ||||||
|  | // returning at most limit branches, or all branches if limit is 0. | ||||||
|  | func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int, error) { | ||||||
|  | 	return git.GetBranchesByPath(repo.RepoPath(), skip, limit) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // checkBranchName validates branch name with existing repository branches | ||||||
|  | func checkBranchName(repo *models.Repository, name string) error { | ||||||
|  | 	gitRepo, err := git.OpenRepository(repo.RepoPath()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer gitRepo.Close() | ||||||
|  |  | ||||||
|  | 	branches, _, err := GetBranches(repo, 0, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, branch := range branches { | ||||||
|  | 		if branch.Name == name { | ||||||
|  | 			return models.ErrBranchAlreadyExists{ | ||||||
|  | 				BranchName: branch.Name, | ||||||
|  | 			} | ||||||
|  | 		} else if (len(branch.Name) < len(name) && branch.Name+"/" == name[0:len(branch.Name)+1]) || | ||||||
|  | 			(len(branch.Name) > len(name) && name+"/" == branch.Name[0:len(name)+1]) { | ||||||
|  | 			return models.ErrBranchNameConflict{ | ||||||
|  | 				BranchName: branch.Name, | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if _, err := gitRepo.GetTag(name); err == nil { | ||||||
|  | 		return models.ErrTagAlreadyExists{ | ||||||
|  | 			TagName: name, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CreateNewBranchFromCommit creates a new repository branch | ||||||
|  | func CreateNewBranchFromCommit(doer *models.User, repo *models.Repository, commit, branchName string) (err error) { | ||||||
|  | 	// Check if branch name can be used | ||||||
|  | 	if err := checkBranchName(repo, branchName); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := git.Push(repo.RepoPath(), git.PushOptions{ | ||||||
|  | 		Remote: repo.RepoPath(), | ||||||
|  | 		Branch: fmt.Sprintf("%s:%s%s", commit, git.BranchPrefix, branchName), | ||||||
|  | 		Env:    models.PushingEnvironment(doer, repo), | ||||||
|  | 	}); err != nil { | ||||||
|  | 		if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		return fmt.Errorf("Push: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // RenameBranch rename a branch | // RenameBranch rename a branch | ||||||
| func RenameBranch(repo *models.Repository, doer *models.User, gitRepo *git.Repository, from, to string) (string, error) { | func RenameBranch(repo *models.Repository, doer *models.User, gitRepo *git.Repository, from, to string) (string, error) { | ||||||
| 	if from == to { | 	if from == to { | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								services/repository/hooks.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								services/repository/hooks.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | // Copyright 2021 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 repository | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models" | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // SyncRepositoryHooks rewrites all repositories' pre-receive, update and post-receive hooks | ||||||
|  | // to make sure the binary and custom conf path are up-to-date. | ||||||
|  | func SyncRepositoryHooks(ctx context.Context) error { | ||||||
|  | 	log.Trace("Doing: SyncRepositoryHooks") | ||||||
|  |  | ||||||
|  | 	if err := db.Iterate( | ||||||
|  | 		db.DefaultContext, | ||||||
|  | 		new(models.Repository), | ||||||
|  | 		builder.Gt{"id": 0}, | ||||||
|  | 		func(idx int, bean interface{}) error { | ||||||
|  | 			repo := bean.(*models.Repository) | ||||||
|  | 			select { | ||||||
|  | 			case <-ctx.Done(): | ||||||
|  | 				return db.ErrCancelledf("before sync repository hooks for %s", repo.FullName()) | ||||||
|  | 			default: | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if err := repo_module.CreateDelegateHooks(repo.RepoPath()); err != nil { | ||||||
|  | 				return fmt.Errorf("SyncRepositoryHook: %v", err) | ||||||
|  | 			} | ||||||
|  | 			if repo.HasWiki() { | ||||||
|  | 				if err := repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { | ||||||
|  | 					return fmt.Errorf("SyncRepositoryHook: %v", err) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return nil | ||||||
|  | 		}, | ||||||
|  | 	); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	log.Trace("Finished: SyncRepositoryHooks") | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| @@ -5,8 +5,10 @@ | |||||||
| package repository | package repository | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| @@ -20,6 +22,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/repofiles" | 	"code.gitea.io/gitea/modules/repofiles" | ||||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	pull_service "code.gitea.io/gitea/services/pull" | 	pull_service "code.gitea.io/gitea/services/pull" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -210,7 +213,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				// Cache for big repository | 				// Cache for big repository | ||||||
| 				if err := repo_module.CacheRef(graceful.GetManager().HammerContext(), repo, gitRepo, opts.RefFullName); err != nil { | 				if err := CacheRef(graceful.GetManager().HammerContext(), repo, gitRepo, opts.RefFullName); err != nil { | ||||||
| 					log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) | 					log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| @@ -229,7 +232,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 			log.Trace("Non-tag and non-branch commits pushed.") | 			log.Trace("Non-tag and non-branch commits pushed.") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if err := repo_module.PushUpdateAddDeleteTags(repo, gitRepo, addTags, delTags); err != nil { | 	if err := PushUpdateAddDeleteTags(repo, gitRepo, addTags, delTags); err != nil { | ||||||
| 		return fmt.Errorf("PushUpdateAddDeleteTags: %v", err) | 		return fmt.Errorf("PushUpdateAddDeleteTags: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -240,3 +243,122 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // PushUpdateAddDeleteTags updates a number of added and delete tags | ||||||
|  | func PushUpdateAddDeleteTags(repo *models.Repository, gitRepo *git.Repository, addTags, delTags []string) error { | ||||||
|  | 	return db.WithTx(func(ctx context.Context) error { | ||||||
|  | 		if err := models.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		return pushUpdateAddTags(ctx, repo, gitRepo, addTags) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // pushUpdateAddTags updates a number of add tags | ||||||
|  | func pushUpdateAddTags(ctx context.Context, repo *models.Repository, gitRepo *git.Repository, tags []string) error { | ||||||
|  | 	if len(tags) == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	lowerTags := make([]string, 0, len(tags)) | ||||||
|  | 	for _, tag := range tags { | ||||||
|  | 		lowerTags = append(lowerTags, strings.ToLower(tag)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	releases, err := models.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("GetReleasesByRepoIDAndNames: %v", err) | ||||||
|  | 	} | ||||||
|  | 	relMap := make(map[string]*models.Release) | ||||||
|  | 	for _, rel := range releases { | ||||||
|  | 		relMap[rel.LowerTagName] = rel | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	newReleases := make([]*models.Release, 0, len(lowerTags)-len(relMap)) | ||||||
|  |  | ||||||
|  | 	emailToUser := make(map[string]*models.User) | ||||||
|  |  | ||||||
|  | 	for i, lowerTag := range lowerTags { | ||||||
|  | 		tag, err := gitRepo.GetTag(tags[i]) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("GetTag: %v", err) | ||||||
|  | 		} | ||||||
|  | 		commit, err := tag.Commit() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Commit: %v", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		sig := tag.Tagger | ||||||
|  | 		if sig == nil { | ||||||
|  | 			sig = commit.Author | ||||||
|  | 		} | ||||||
|  | 		if sig == nil { | ||||||
|  | 			sig = commit.Committer | ||||||
|  | 		} | ||||||
|  | 		var author *models.User | ||||||
|  | 		var createdAt = time.Unix(1, 0) | ||||||
|  |  | ||||||
|  | 		if sig != nil { | ||||||
|  | 			var ok bool | ||||||
|  | 			author, ok = emailToUser[sig.Email] | ||||||
|  | 			if !ok { | ||||||
|  | 				author, err = models.GetUserByEmailContext(ctx, sig.Email) | ||||||
|  | 				if err != nil && !models.IsErrUserNotExist(err) { | ||||||
|  | 					return fmt.Errorf("GetUserByEmail: %v", err) | ||||||
|  | 				} | ||||||
|  | 				if author != nil { | ||||||
|  | 					emailToUser[sig.Email] = author | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			createdAt = sig.When | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		commitsCount, err := commit.CommitsCount() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("CommitsCount: %v", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		rel, has := relMap[lowerTag] | ||||||
|  |  | ||||||
|  | 		if !has { | ||||||
|  | 			rel = &models.Release{ | ||||||
|  | 				RepoID:       repo.ID, | ||||||
|  | 				Title:        "", | ||||||
|  | 				TagName:      tags[i], | ||||||
|  | 				LowerTagName: lowerTag, | ||||||
|  | 				Target:       "", | ||||||
|  | 				Sha1:         commit.ID.String(), | ||||||
|  | 				NumCommits:   commitsCount, | ||||||
|  | 				Note:         "", | ||||||
|  | 				IsDraft:      false, | ||||||
|  | 				IsPrerelease: false, | ||||||
|  | 				IsTag:        true, | ||||||
|  | 				CreatedUnix:  timeutil.TimeStamp(createdAt.Unix()), | ||||||
|  | 			} | ||||||
|  | 			if author != nil { | ||||||
|  | 				rel.PublisherID = author.ID | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			newReleases = append(newReleases, rel) | ||||||
|  | 		} else { | ||||||
|  | 			rel.Sha1 = commit.ID.String() | ||||||
|  | 			rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) | ||||||
|  | 			rel.NumCommits = commitsCount | ||||||
|  | 			rel.IsDraft = false | ||||||
|  | 			if rel.IsTag && author != nil { | ||||||
|  | 				rel.PublisherID = author.ID | ||||||
|  | 			} | ||||||
|  | 			if err = models.UpdateRelease(ctx, rel); err != nil { | ||||||
|  | 				return fmt.Errorf("Update: %v", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(newReleases) > 0 { | ||||||
|  | 		if err = models.InsertReleasesContext(ctx, newReleases); err != nil { | ||||||
|  | 			return fmt.Errorf("Insert: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Lunny Xiao
					Lunny Xiao