mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Add abstraction layer to check if the repository exists on disk (#33874)
Extract from #28966 This PR uses `gitrepo.IsRepositoryExist` instead of `util.IsExist` to detect whether the repository exist in disk. This will move `RepoPath` detail behind of package `gitrepo` to make it easier to do possible changes where storing the repositories. No code change
This commit is contained in:
		| @@ -69,3 +69,8 @@ func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Reposito | ||||
| 	ctx.SetContextValue(ck, gitRepo) | ||||
| 	return gitRepo, nil | ||||
| } | ||||
|  | ||||
| // IsRepositoryExist returns true if the repository directory exists in the disk | ||||
| func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) { | ||||
| 	return util.IsExist(repoPath(repo)) | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,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/label" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/options" | ||||
| @@ -120,25 +121,24 @@ func LoadRepoConfig() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func CheckInitRepository(ctx context.Context, owner, name, objectFormatName string) (err error) { | ||||
| func CheckInitRepository(ctx context.Context, repo *repo_model.Repository) (err error) { | ||||
| 	// Somehow the directory could exist. | ||||
| 	repoPath := repo_model.RepoPath(owner, name) | ||||
| 	isExist, err := util.IsExist(repoPath) | ||||
| 	isExist, err := gitrepo.IsRepositoryExist(ctx, repo) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if isExist { | ||||
| 		return repo_model.ErrRepoFilesAlreadyExist{ | ||||
| 			Uname: owner, | ||||
| 			Name:  name, | ||||
| 			Uname: repo.OwnerName, | ||||
| 			Name:  repo.Name, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Init git bare new repository. | ||||
| 	if err = git.InitRepository(ctx, repoPath, true, objectFormatName); err != nil { | ||||
| 	if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { | ||||
| 		return fmt.Errorf("git.InitRepository: %w", err) | ||||
| 	} else if err = CreateDelegateHooks(repoPath); err != nil { | ||||
| 	} else if err = CreateDelegateHooks(repo.RepoPath()); err != nil { | ||||
| 		return fmt.Errorf("createDelegateHooks: %w", err) | ||||
| 	} | ||||
| 	return nil | ||||
|   | ||||
| @@ -52,12 +52,10 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | ||||
| 		IsEmpty:                         !opts.AutoInit, | ||||
| 	} | ||||
|  | ||||
| 	repoPath := repo_model.RepoPath(u.Name, repo.Name) | ||||
|  | ||||
| 	if err := db.WithTx(ctx, func(ctx context.Context) error { | ||||
| 		isExist, err := util.IsExist(repoPath) | ||||
| 		isExist, err := gitrepo.IsRepositoryExist(ctx, repo) | ||||
| 		if err != nil { | ||||
| 			log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 			log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) | ||||
| 			return err | ||||
| 		} | ||||
| 		if !isExist { | ||||
| @@ -82,7 +80,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | ||||
| 	} | ||||
|  | ||||
| 	if err := func() error { | ||||
| 		if err := adoptRepository(ctx, repoPath, repo, opts.DefaultBranch); err != nil { | ||||
| 		if err := adoptRepository(ctx, repo, opts.DefaultBranch); err != nil { | ||||
| 			return fmt.Errorf("adoptRepository: %w", err) | ||||
| 		} | ||||
|  | ||||
| @@ -91,7 +89,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | ||||
| 		} | ||||
|  | ||||
| 		if stdout, _, err := git.NewCommand("update-server-info"). | ||||
| 			RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||
| 			RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil { | ||||
| 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||
| 			return fmt.Errorf("CreateRepository(git update-server-info): %w", err) | ||||
| 		} | ||||
| @@ -107,17 +105,17 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | ||||
| 	return repo, nil | ||||
| } | ||||
|  | ||||
| func adoptRepository(ctx context.Context, repoPath string, repo *repo_model.Repository, defaultBranch string) (err error) { | ||||
| 	isExist, err := util.IsExist(repoPath) | ||||
| func adoptRepository(ctx context.Context, repo *repo_model.Repository, defaultBranch string) (err error) { | ||||
| 	isExist, err := gitrepo.IsRepositoryExist(ctx, repo) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if !isExist { | ||||
| 		return fmt.Errorf("adoptRepository: path does not already exist: %s", repoPath) | ||||
| 		return fmt.Errorf("adoptRepository: path does not already exist: %s", repo.FullName()) | ||||
| 	} | ||||
|  | ||||
| 	if err := repo_module.CreateDelegateHooks(repoPath); err != nil { | ||||
| 	if err := repo_module.CreateDelegateHooks(repo.RepoPath()); err != nil { | ||||
| 		return fmt.Errorf("createDelegateHooks: %w", err) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -52,7 +52,7 @@ type CreateRepoOptions struct { | ||||
| 	ObjectFormatName string | ||||
| } | ||||
|  | ||||
| func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { | ||||
| func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir string, opts CreateRepoOptions) error { | ||||
| 	commitTimeStr := time.Now().Format(time.RFC3339) | ||||
| 	authorSig := repo.Owner.NewGitSig() | ||||
|  | ||||
| @@ -67,7 +67,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | ||||
| 	) | ||||
|  | ||||
| 	// Clone to temporary path and do the init commit. | ||||
| 	if stdout, _, err := git.NewCommand("clone").AddDynamicArguments(repoPath, tmpDir). | ||||
| 	if stdout, _, err := git.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir). | ||||
| 		RunStdString(ctx, &git.RunOpts{Dir: "", Env: env}); err != nil { | ||||
| 		log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err) | ||||
| 		return fmt.Errorf("git clone: %w", err) | ||||
| @@ -139,8 +139,8 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | ||||
| } | ||||
|  | ||||
| // InitRepository initializes README and .gitignore if needed. | ||||
| func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { | ||||
| 	if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name, opts.ObjectFormatName); err != nil { | ||||
| func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { | ||||
| 	if err = repo_module.CheckInitRepository(ctx, repo); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -148,7 +148,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re | ||||
| 	if opts.AutoInit { | ||||
| 		tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.RepoPath(), err) | ||||
| 			return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err) | ||||
| 		} | ||||
| 		defer func() { | ||||
| 			if err := util.RemoveAll(tmpDir); err != nil { | ||||
| @@ -156,7 +156,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re | ||||
| 			} | ||||
| 		}() | ||||
|  | ||||
| 		if err = prepareRepoCommit(ctx, repo, tmpDir, repoPath, opts); err != nil { | ||||
| 		if err = prepareRepoCommit(ctx, repo, tmpDir, opts); err != nil { | ||||
| 			return fmt.Errorf("prepareRepoCommit: %w", err) | ||||
| 		} | ||||
|  | ||||
| @@ -256,10 +256,9 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		repoPath := repo_model.RepoPath(u.Name, repo.Name) | ||||
| 		isExist, err := util.IsExist(repoPath) | ||||
| 		isExist, err := gitrepo.IsRepositoryExist(ctx, repo) | ||||
| 		if err != nil { | ||||
| 			log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 			log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) | ||||
| 			return err | ||||
| 		} | ||||
| 		if isExist { | ||||
| @@ -270,15 +269,15 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | ||||
| 			// | ||||
| 			// Previously Gitea would just delete and start afresh - this was naughty. | ||||
| 			// So we will now fail and delegate to other functionality to adopt or delete | ||||
| 			log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) | ||||
| 			log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName()) | ||||
| 			return repo_model.ErrRepoFilesAlreadyExist{ | ||||
| 				Uname: u.Name, | ||||
| 				Name:  repo.Name, | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err = initRepository(ctx, repoPath, doer, repo, opts); err != nil { | ||||
| 			if err2 := util.RemoveAll(repoPath); err2 != nil { | ||||
| 		if err = initRepository(ctx, doer, repo, opts); err != nil { | ||||
| 			if err2 := util.RemoveAll(repo.RepoPath()); err2 != nil { | ||||
| 				log.Error("initRepository: %v", err) | ||||
| 				return fmt.Errorf( | ||||
| 					"delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2) | ||||
| @@ -300,7 +299,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | ||||
| 		} | ||||
|  | ||||
| 		if stdout, _, err := git.NewCommand("update-server-info"). | ||||
| 			RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||
| 			RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil { | ||||
| 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||
| 			rollbackRepo = repo | ||||
| 			rollbackRepo.OwnerID = u.ID | ||||
| @@ -312,7 +311,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | ||||
| 		if len(opts.License) > 0 { | ||||
| 			licenses = append(licenses, opts.License) | ||||
|  | ||||
| 			stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||
| 			stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||
| 			if err != nil { | ||||
| 				log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||
| 				rollbackRepo = repo | ||||
| @@ -353,14 +352,13 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	repoPath := repo_model.RepoPath(u.Name, repo.Name) | ||||
| 	isExist, err := util.IsExist(repoPath) | ||||
| 	isExist, err := gitrepo.IsRepositoryExist(ctx, repo) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if !overwriteOrAdopt && isExist { | ||||
| 		log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) | ||||
| 		log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName()) | ||||
| 		return repo_model.ErrRepoFilesAlreadyExist{ | ||||
| 			Uname: u.Name, | ||||
| 			Name:  repo.Name, | ||||
|   | ||||
| @@ -110,15 +110,13 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		repoPath := repo_model.RepoPath(owner.Name, repo.Name) | ||||
|  | ||||
| 		if exists, _ := util.IsExist(repoPath); !exists { | ||||
| 		if exists, _ := gitrepo.IsRepositoryExist(ctx, repo); !exists { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// As the transaction will be failed and hence database changes will be destroyed we only need | ||||
| 		// to delete the related repository on the filesystem | ||||
| 		if errDelete := util.RemoveAll(repoPath); errDelete != nil { | ||||
| 		if errDelete := util.RemoveAll(repo.RepoPath()); errDelete != nil { | ||||
| 			log.Error("Failed to remove fork repo") | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -258,7 +258,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r | ||||
| func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository) (err error) { | ||||
| 	tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.RepoPath(), err) | ||||
| 		return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err) | ||||
| 	} | ||||
|  | ||||
| 	defer func() { | ||||
| @@ -350,10 +350,9 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	repoPath := generateRepo.RepoPath() | ||||
| 	isExist, err := util.IsExist(repoPath) | ||||
| 	isExist, err := gitrepo.IsRepositoryExist(ctx, generateRepo) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||
| 		log.Error("Unable to check if %s exists. Error: %v", generateRepo.FullName(), err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if isExist { | ||||
| @@ -363,7 +362,7 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err = repo_module.CheckInitRepository(ctx, owner.Name, generateRepo.Name, generateRepo.ObjectFormatName); err != nil { | ||||
| 	if err = repo_module.CheckInitRepository(ctx, generateRepo); err != nil { | ||||
| 		return generateRepo, err | ||||
| 	} | ||||
|  | ||||
| @@ -372,7 +371,7 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ | ||||
| 	} | ||||
|  | ||||
| 	if stdout, _, err := git.NewCommand("update-server-info"). | ||||
| 		RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||
| 		RunStdString(ctx, &git.RunOpts{Dir: generateRepo.RepoPath()}); err != nil { | ||||
| 		log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err) | ||||
| 		return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %w", err) | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user