mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-15 23:40:58 +02:00
fix(repo): /generate must sync the branch table for the new repo (#37693)
Two bugs in GenerateGitContent, the function behind
`POST /api/v1/repos/{owner}/{template}/generate`:
1. The new repository's refs were not written `branch` DB table
2. The function re-fetched the new repo row from the database
but reassigned its local pointer
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
5c887d68ca
commit
5b3575a8be
@ -152,6 +152,16 @@ func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Re
|
||||
return fmt.Errorf("createDelegateHooks: %w", err)
|
||||
}
|
||||
|
||||
repo.DefaultBranch = util.IfZero(opts.DefaultBranch, setting.Repository.DefaultBranch)
|
||||
repo.DefaultWikiBranch = setting.Repository.DefaultBranch
|
||||
if !opts.AutoInit {
|
||||
repo.IsEmpty = true
|
||||
}
|
||||
|
||||
if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "is_empty", "default_branch", "default_wiki_branch"); err != nil {
|
||||
return fmt.Errorf("updateRepository: %w", err)
|
||||
}
|
||||
|
||||
// Initialize repository according to user's choice.
|
||||
if opts.AutoInit {
|
||||
tmpDir, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("repos-" + repo.Name)
|
||||
@ -165,39 +175,22 @@ func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Re
|
||||
}
|
||||
|
||||
// Apply changes and commit.
|
||||
if err = initRepoCommit(ctx, tmpDir, repo, u, opts.DefaultBranch); err != nil {
|
||||
if err = initRepoCommit(ctx, tmpDir, repo, u); err != nil {
|
||||
return fmt.Errorf("initRepoCommit: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Re-fetch the repository from database before updating it (else it would
|
||||
// override changes that were done earlier with sql)
|
||||
if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
|
||||
return fmt.Errorf("setDefaultBranch: %w", err)
|
||||
}
|
||||
|
||||
// Re-fetch the repository from database before updating it (keep changes that were done earlier with SQL)
|
||||
if repo, err = repo_model.GetRepositoryByID(ctx, repo.ID); err != nil {
|
||||
return fmt.Errorf("getRepositoryByID: %w", err)
|
||||
}
|
||||
|
||||
if !opts.AutoInit {
|
||||
repo.IsEmpty = true
|
||||
}
|
||||
|
||||
repo.DefaultBranch = setting.Repository.DefaultBranch
|
||||
repo.DefaultWikiBranch = setting.Repository.DefaultBranch
|
||||
|
||||
if len(opts.DefaultBranch) > 0 {
|
||||
repo.DefaultBranch = opts.DefaultBranch
|
||||
if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
|
||||
return fmt.Errorf("setDefaultBranch: %w", err)
|
||||
}
|
||||
|
||||
if !repo.IsEmpty {
|
||||
if _, err := repo_module.SyncRepoBranches(ctx, repo.ID, u.ID); err != nil {
|
||||
return fmt.Errorf("SyncRepoBranches: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "is_empty", "default_branch", "default_wiki_branch"); err != nil {
|
||||
return fmt.Errorf("updateRepository: %w", err)
|
||||
if _, err := repo_module.SyncRepoBranches(ctx, repo.ID, u.ID); err != nil {
|
||||
return fmt.Errorf("SyncRepoBranches: %w", err)
|
||||
}
|
||||
|
||||
if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
|
||||
|
||||
@ -207,6 +207,9 @@ func processGiteaTemplateFile(ctx context.Context, tmpDir string, templateRepo,
|
||||
}
|
||||
|
||||
func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository, tmpDir string) error {
|
||||
// set default branch based on whether it's specified in the newly generated repo or not
|
||||
repo.DefaultBranch = util.IfZero(repo.DefaultBranch, util.IfZero(templateRepo.DefaultBranch, setting.Repository.DefaultBranch))
|
||||
|
||||
// Clone to temporary path and do the init commit.
|
||||
if err := gitrepo.CloneRepoToLocal(ctx, templateRepo, tmpDir, git.CloneRepoOptions{
|
||||
Depth: 1,
|
||||
@ -246,13 +249,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
|
||||
return fmt.Errorf("failed to add submodules: %v", err)
|
||||
}
|
||||
|
||||
// set default branch based on whether it's specified in the newly generated repo or not
|
||||
defaultBranch := repo.DefaultBranch
|
||||
if strings.TrimSpace(defaultBranch) == "" {
|
||||
defaultBranch = templateRepo.DefaultBranch
|
||||
}
|
||||
|
||||
return initRepoCommit(ctx, tmpDir, repo, repo.Owner, defaultBranch)
|
||||
return initRepoCommit(ctx, tmpDir, repo, repo.Owner)
|
||||
}
|
||||
|
||||
// GenerateGitContent generates git content from a template repository
|
||||
@ -266,17 +263,6 @@ func GenerateGitContent(ctx context.Context, templateRepo, generateRepo *repo_mo
|
||||
if err = generateRepoCommit(ctx, generateRepo, templateRepo, generateRepo, tmpDir); err != nil {
|
||||
return fmt.Errorf("generateRepoCommit: %w", err)
|
||||
}
|
||||
|
||||
// re-fetch repo
|
||||
if generateRepo, err = repo_model.GetRepositoryByID(ctx, generateRepo.ID); err != nil {
|
||||
return fmt.Errorf("getRepositoryByID: %w", err)
|
||||
}
|
||||
|
||||
// if there was no default branch supplied when generating the repo, use the default one from the template
|
||||
if strings.TrimSpace(generateRepo.DefaultBranch) == "" {
|
||||
generateRepo.DefaultBranch = templateRepo.DefaultBranch
|
||||
}
|
||||
|
||||
if err = gitrepo.SetDefaultBranch(ctx, generateRepo, generateRepo.DefaultBranch); err != nil {
|
||||
return fmt.Errorf("setDefaultBranch: %w", err)
|
||||
}
|
||||
@ -291,6 +277,10 @@ func GenerateGitContent(ctx context.Context, templateRepo, generateRepo *repo_mo
|
||||
if err := git_model.CopyLFS(ctx, generateRepo, templateRepo); err != nil {
|
||||
return fmt.Errorf("failed to copy LFS: %w", err)
|
||||
}
|
||||
|
||||
if _, err := repo_module.SyncRepoBranches(ctx, generateRepo.ID, 0); err != nil {
|
||||
return fmt.Errorf("SyncRepoBranches: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -16,12 +16,11 @@ import (
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
||||
)
|
||||
|
||||
// initRepoCommit temporarily changes with work directory.
|
||||
func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) {
|
||||
func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User) (err error) {
|
||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||
|
||||
sig := u.NewGitSig()
|
||||
@ -69,13 +68,9 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
|
||||
return fmt.Errorf("git commit: %w", err)
|
||||
}
|
||||
|
||||
if len(defaultBranch) == 0 {
|
||||
defaultBranch = setting.Repository.DefaultBranch
|
||||
}
|
||||
|
||||
if err := gitrepo.PushFromLocal(ctx, tmpPath, repo, git.PushOptions{
|
||||
LocalRefName: "HEAD",
|
||||
Branch: defaultBranch,
|
||||
Branch: repo.DefaultBranch,
|
||||
Env: repo_module.InternalPushingEnvironment(u, repo),
|
||||
}); err != nil {
|
||||
log.Error("Failed to push back to HEAD Error: %v", err)
|
||||
|
||||
@ -645,8 +645,7 @@ func TestAPIRejectTransfer(t *testing.T) {
|
||||
req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject", repo.OwnerName, repo.Name)).
|
||||
AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
apiRepo := new(api.Repository)
|
||||
DecodeJSON(t, resp, apiRepo)
|
||||
apiRepo := DecodeJSON(t, resp, &api.Repository{})
|
||||
assert.Equal(t, "user2", apiRepo.Owner.UserName)
|
||||
}
|
||||
|
||||
@ -659,6 +658,16 @@ func TestAPIGenerateRepo(t *testing.T) {
|
||||
|
||||
templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44})
|
||||
|
||||
assertGeneratedRepoIsUsable := func(t *testing.T, ownerName string, repo *api.Repository) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, repo.DefaultBranch)
|
||||
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/branches/%s", ownerName, repo.Name, repo.DefaultBranch).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
branch := DecodeJSON(t, resp, &api.Branch{})
|
||||
assert.Equal(t, repo.DefaultBranch, branch.Name)
|
||||
}
|
||||
|
||||
// user
|
||||
repo := new(api.Repository)
|
||||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate", templateRepo.OwnerName, templateRepo.Name), &api.GenerateRepoOption{
|
||||
@ -672,6 +681,7 @@ func TestAPIGenerateRepo(t *testing.T) {
|
||||
DecodeJSON(t, resp, repo)
|
||||
|
||||
assert.Equal(t, "new-repo", repo.Name)
|
||||
assertGeneratedRepoIsUsable(t, user.Name, repo)
|
||||
|
||||
// org
|
||||
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate", templateRepo.OwnerName, templateRepo.Name), &api.GenerateRepoOption{
|
||||
@ -685,6 +695,7 @@ func TestAPIGenerateRepo(t *testing.T) {
|
||||
DecodeJSON(t, resp, repo)
|
||||
|
||||
assert.Equal(t, "new-repo", repo.Name)
|
||||
assertGeneratedRepoIsUsable(t, "org3", repo)
|
||||
}
|
||||
|
||||
func TestAPIRepoGetReviewers(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user