Option to set default branch at repository creation (#10803)
* Option to set default branch at repository creation * Handle template repos with non-default master branch * Add DefaultBranch handling on creation to API Fix #9542 Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
b1c331c845
commit
52cfd2743c
10 changed files with 57 additions and 33 deletions
|
@ -929,6 +929,7 @@ type CreateRepoOptions struct {
|
||||||
IssueLabels string
|
IssueLabels string
|
||||||
License string
|
License string
|
||||||
Readme string
|
Readme string
|
||||||
|
DefaultBranch string
|
||||||
IsPrivate bool
|
IsPrivate bool
|
||||||
IsMirror bool
|
IsMirror bool
|
||||||
AutoInit bool
|
AutoInit bool
|
||||||
|
|
|
@ -27,15 +27,16 @@ import (
|
||||||
|
|
||||||
// CreateRepoForm form for creating repository
|
// CreateRepoForm form for creating repository
|
||||||
type CreateRepoForm struct {
|
type CreateRepoForm struct {
|
||||||
UID int64 `binding:"Required"`
|
UID int64 `binding:"Required"`
|
||||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||||
Private bool
|
Private bool
|
||||||
Description string `binding:"MaxSize(255)"`
|
Description string `binding:"MaxSize(255)"`
|
||||||
AutoInit bool
|
DefaultBranch string `binding:"GitRefName;MaxSize(100)"`
|
||||||
Gitignores string
|
AutoInit bool
|
||||||
IssueLabels string
|
Gitignores string
|
||||||
License string
|
IssueLabels string
|
||||||
Readme string
|
License string
|
||||||
|
Readme string
|
||||||
|
|
||||||
RepoTemplate int64
|
RepoTemplate int64
|
||||||
GitContent bool
|
GitContent bool
|
||||||
|
|
|
@ -113,7 +113,8 @@ func generateRepoCommit(repo, templateRepo, generateRepo *models.Repository, tmp
|
||||||
// Clone to temporary path and do the init commit.
|
// Clone to temporary path and do the init commit.
|
||||||
templateRepoPath := templateRepo.RepoPath()
|
templateRepoPath := templateRepo.RepoPath()
|
||||||
if err := git.Clone(templateRepoPath, tmpDir, git.CloneRepoOptions{
|
if err := git.Clone(templateRepoPath, tmpDir, git.CloneRepoOptions{
|
||||||
Depth: 1,
|
Depth: 1,
|
||||||
|
Branch: templateRepo.DefaultBranch,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("git clone: %v", err)
|
return fmt.Errorf("git clone: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -180,7 +181,7 @@ func generateRepoCommit(repo, templateRepo, generateRepo *models.Repository, tmp
|
||||||
return fmt.Errorf("git remote add: %v", err)
|
return fmt.Errorf("git remote add: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return initRepoCommit(tmpDir, repo, repo.Owner)
|
return initRepoCommit(tmpDir, repo, repo.Owner, templateRepo.DefaultBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateGitContent(ctx models.DBContext, repo, templateRepo, generateRepo *models.Repository) (err error) {
|
func generateGitContent(ctx models.DBContext, repo, templateRepo, generateRepo *models.Repository) (err error) {
|
||||||
|
@ -204,7 +205,7 @@ func generateGitContent(ctx models.DBContext, repo, templateRepo, generateRepo *
|
||||||
return fmt.Errorf("getRepositoryByID: %v", err)
|
return fmt.Errorf("getRepositoryByID: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.DefaultBranch = "master"
|
repo.DefaultBranch = templateRepo.DefaultBranch
|
||||||
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
||||||
return fmt.Errorf("updateRepository: %v", err)
|
return fmt.Errorf("updateRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ func prepareRepoCommit(ctx models.DBContext, repo *models.Repository, tmpDir, re
|
||||||
}
|
}
|
||||||
|
|
||||||
// initRepoCommit temporarily changes with work directory.
|
// initRepoCommit temporarily changes with work directory.
|
||||||
func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User) (err error) {
|
func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User, defaultBranch string) (err error) {
|
||||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||||
|
|
||||||
sig := u.NewGitSig()
|
sig := u.NewGitSig()
|
||||||
|
@ -145,7 +145,11 @@ func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User) (er
|
||||||
return fmt.Errorf("git commit: %v", err)
|
return fmt.Errorf("git commit: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if stdout, err := git.NewCommand("push", "origin", "master").
|
if len(defaultBranch) == 0 {
|
||||||
|
defaultBranch = "master"
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout, err := git.NewCommand("push", "origin", "master:"+defaultBranch).
|
||||||
SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
|
SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
|
||||||
RunInDirWithEnv(tmpPath, models.InternalPushingEnvironment(u, repo)); err != nil {
|
RunInDirWithEnv(tmpPath, models.InternalPushingEnvironment(u, repo)); err != nil {
|
||||||
log.Error("Failed to push back to master: Stdout: %s\nError: %v", stdout, err)
|
log.Error("Failed to push back to master: Stdout: %s\nError: %v", stdout, err)
|
||||||
|
@ -190,7 +194,7 @@ func initRepository(ctx models.DBContext, repoPath string, u *models.User, repo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply changes and commit.
|
// Apply changes and commit.
|
||||||
if err = initRepoCommit(tmpDir, repo, u); err != nil {
|
if err = initRepoCommit(tmpDir, repo, u, opts.DefaultBranch); err != nil {
|
||||||
return fmt.Errorf("initRepoCommit: %v", err)
|
return fmt.Errorf("initRepoCommit: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +210,10 @@ func initRepository(ctx models.DBContext, repoPath string, u *models.User, repo
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.DefaultBranch = "master"
|
repo.DefaultBranch = "master"
|
||||||
|
if len(opts.DefaultBranch) > 0 {
|
||||||
|
repo.DefaultBranch = opts.DefaultBranch
|
||||||
|
}
|
||||||
|
|
||||||
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
||||||
return fmt.Errorf("updateRepository: %v", err)
|
return fmt.Errorf("updateRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,8 @@ type CreateRepoOption struct {
|
||||||
License string `json:"license"`
|
License string `json:"license"`
|
||||||
// Readme of the repository to create
|
// Readme of the repository to create
|
||||||
Readme string `json:"readme"`
|
Readme string `json:"readme"`
|
||||||
|
// DefaultBranch of the repository (used when initializes and in template)
|
||||||
|
DefaultBranch string `json:"default_branch" binding:"GitRefName;MaxSize(100)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditRepoOption options when editing a repository's properties
|
// EditRepoOption options when editing a repository's properties
|
||||||
|
|
|
@ -218,14 +218,15 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
|
||||||
opt.Readme = "Default"
|
opt.Readme = "Default"
|
||||||
}
|
}
|
||||||
repo, err := repo_service.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
|
repo, err := repo_service.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
|
||||||
Name: opt.Name,
|
Name: opt.Name,
|
||||||
Description: opt.Description,
|
Description: opt.Description,
|
||||||
IssueLabels: opt.IssueLabels,
|
IssueLabels: opt.IssueLabels,
|
||||||
Gitignores: opt.Gitignores,
|
Gitignores: opt.Gitignores,
|
||||||
License: opt.License,
|
License: opt.License,
|
||||||
Readme: opt.Readme,
|
Readme: opt.Readme,
|
||||||
IsPrivate: opt.Private,
|
IsPrivate: opt.Private,
|
||||||
AutoInit: opt.AutoInit,
|
AutoInit: opt.AutoInit,
|
||||||
|
DefaultBranch: opt.DefaultBranch,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrRepoAlreadyExist(err) {
|
if models.IsErrRepoAlreadyExist(err) {
|
||||||
|
|
|
@ -221,14 +221,15 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
repo, err = repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
repo, err = repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
||||||
Name: form.RepoName,
|
Name: form.RepoName,
|
||||||
Description: form.Description,
|
Description: form.Description,
|
||||||
Gitignores: form.Gitignores,
|
Gitignores: form.Gitignores,
|
||||||
IssueLabels: form.IssueLabels,
|
IssueLabels: form.IssueLabels,
|
||||||
License: form.License,
|
License: form.License,
|
||||||
Readme: form.Readme,
|
Readme: form.Readme,
|
||||||
IsPrivate: form.Private || setting.Repository.ForcePrivate,
|
IsPrivate: form.Private || setting.Repository.ForcePrivate,
|
||||||
AutoInit: form.AutoInit,
|
DefaultBranch: form.DefaultBranch,
|
||||||
|
AutoInit: form.AutoInit,
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
||||||
|
|
|
@ -162,6 +162,10 @@
|
||||||
<label>{{.i18n.Tr "repo.auto_init"}}</label>
|
<label>{{.i18n.Tr "repo.auto_init"}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label for="default_branch">{{.i18n.Tr "repo.default_branch"}}</label>
|
||||||
|
<input id="default_branch" name="default_branch" value="{{.default_branch}}" placeholder="master">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
|
@ -52,7 +52,7 @@ git init
|
||||||
git add README.md
|
git add README.md
|
||||||
git commit -m "first commit"
|
git commit -m "first commit"
|
||||||
git remote add origin <span class="clone-url">{{if $.DisableSSH}}{{$.CloneLink.HTTPS}}{{else}}{{$.CloneLink.SSH}}{{end}}</span>
|
git remote add origin <span class="clone-url">{{if $.DisableSSH}}{{$.CloneLink.HTTPS}}{{else}}{{$.CloneLink.SSH}}{{end}}</span>
|
||||||
git push -u origin master</code></pre>
|
git push -u origin {{if ne .Repository.DefaultBranch "master"}}master:{{.Repository.DefaultBranch}}{{else}}master{{end}}</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
|
@ -61,7 +61,7 @@ git push -u origin master</code></pre>
|
||||||
<h3>{{.i18n.Tr "repo.push_exist_repo"}}</h3>
|
<h3>{{.i18n.Tr "repo.push_exist_repo"}}</h3>
|
||||||
<div class="markdown">
|
<div class="markdown">
|
||||||
<pre><code>git remote add origin <span class="clone-url">{{if $.DisableSSH}}{{$.CloneLink.HTTPS}}{{else}}{{$.CloneLink.SSH}}{{end}}</span>
|
<pre><code>git remote add origin <span class="clone-url">{{if $.DisableSSH}}{{$.CloneLink.HTTPS}}{{else}}{{$.CloneLink.SSH}}{{end}}</span>
|
||||||
git push -u origin master</code></pre>
|
git push -u origin {{.Repository.DefaultBranch}}</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -10600,6 +10600,11 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "AutoInit"
|
"x-go-name": "AutoInit"
|
||||||
},
|
},
|
||||||
|
"default_branch": {
|
||||||
|
"description": "DefaultBranch of the repository (used when initializes and in template)",
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "DefaultBranch"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Description of the repository to create",
|
"description": "Description of the repository to create",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
Reference in a new issue