From 1f4555688b7118d409ec359ad70c871910f52821 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 28 Oct 2019 21:00:17 -0500 Subject: [PATCH 01/30] Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/migrations/migrations.go | 2 + models/migrations/v105.go | 19 ++++++ models/repo.go | 19 ++++++ modules/auth/repo_form.go | 1 + options/locale/locale_en-US.ini | 5 ++ routers/repo/pull.go | 87 ++++++++++++++++++++++++++++ routers/repo/setting.go | 1 + routers/routes/routes.go | 4 ++ templates/repo/header.tmpl | 1 + templates/repo/home.tmpl | 11 ++++ templates/repo/settings/options.tmpl | 7 +++ 11 files changed, 157 insertions(+) create mode 100644 models/migrations/v105.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index e214f16a2a1e1..b8c7993df5c9c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -264,6 +264,8 @@ var migrations = []Migration{ NewMigration("Add WhitelistDeployKeys to protected branch", addWhitelistDeployKeysToBranches), // v104 -> v105 NewMigration("remove unnecessary columns from label", removeLabelUneededCols), + // v105 -> v106 + NewMigration("Add template options to repository", addTemplateToRepo), } // Migrate database to current version diff --git a/models/migrations/v105.go b/models/migrations/v105.go new file mode 100644 index 0000000000000..3d6aeebaf0633 --- /dev/null +++ b/models/migrations/v105.go @@ -0,0 +1,19 @@ +// Copyright 2019 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 migrations + +import ( + "xorm.io/xorm" +) + +func addTemplateToRepo(x *xorm.Engine) error { + + type Repository struct { + IsTemplate bool `xorm:"INDEX NOT NULL DEFAULT false"` + TemplateID int64 `xorm:"INDEX"` + } + + return x.Sync2(new(Repository)) +} diff --git a/models/repo.go b/models/repo.go index ac3443f8953b4..fa9374c4aadec 100644 --- a/models/repo.go +++ b/models/repo.go @@ -178,6 +178,9 @@ type Repository struct { IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"` ForkID int64 `xorm:"INDEX"` BaseRepo *Repository `xorm:"-"` + IsTemplate bool `xorm:"INDEX NOT NULL DEFAULT false"` + TemplateID int64 `xorm:"INDEX"` + TemplateRepo *Repository `xorm:"-"` Size int64 `xorm:"NOT NULL DEFAULT 0"` IndexerStatus *RepoIndexerStatus `xorm:"-"` IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"` @@ -662,6 +665,22 @@ func (repo *Repository) getBaseRepo(e Engine) (err error) { return err } +// GetTemplateRepo populates repo.TemplateRepo for a template repository and +// returns an error on failure (NOTE: no error is returned for +// non-template repositories, and TemplateRepo will be left untouched) +func (repo *Repository) GetTemplateRepo() (err error) { + return repo.getTemplateRepo(x) +} + +func (repo *Repository) getTemplateRepo(e Engine) (err error) { + if !repo.IsTemplate { + return nil + } + + repo.TemplateRepo, err = getRepositoryByID(e, repo.TemplateID) + return err +} + func (repo *Repository) repoPath(e Engine) string { return RepoPath(repo.mustOwnerName(e), repo.Name) } diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 2280666114d52..7f7666d1f5d3c 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -107,6 +107,7 @@ type RepoSettingForm struct { MirrorUsername string MirrorPassword string Private bool + Template bool EnablePrune bool // Advanced settings diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4210ed1212a80..f936c2722c012 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -578,6 +578,9 @@ email_notifications.submit = Set Email Preference owner = Owner repo_name = Repository Name repo_name_helper = Good repository names use short, memorable and unique keywords. +template = Template +template_helper = Make repository a template +template_description = A repository template can be used to generate a repository with the same files as the template. visibility = Visibility visibility_description = Only the owner or the organization members if they have rights, will be able to see it. visibility_helper = Make Repository Private @@ -587,6 +590,8 @@ clone_helper = Need help cloning? Visit <a target="_blank" rel="noopener norefer fork_repo = Fork Repository fork_from = Fork From fork_visibility_helper = The visibility of a forked repository cannot be changed. +use_template = Use this template +generate_from = Generated from repo_desc = Description repo_lang = Language repo_gitignore_helper = Select .gitignore templates. diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 3defd04b1bd1b..a212c8af7cb24 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -229,6 +229,93 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) { ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) } +// TemplateGenerate render repository template generate page +func TemplateGenerate(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("template_generate") + + getForkRepository(ctx) + if ctx.Written() { + return + } + + ctx.HTML(200, tplFork) +} + +// TemplateGeneratePost response for generating a repository template +func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { + ctx.Data["Title"] = ctx.Tr("template_generate") + + ctxUser := checkContextUser(ctx, form.UID) + if ctx.Written() { + return + } + + forkRepo := getForkRepository(ctx) + if ctx.Written() { + return + } + + ctx.Data["ContextUser"] = ctxUser + + if ctx.HasError() { + ctx.HTML(200, tplFork) + return + } + + var err error + var traverseParentRepo = forkRepo + for { + if ctxUser.ID == traverseParentRepo.OwnerID { + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) + return + } + repo, has := models.HasForkedRepo(ctxUser.ID, traverseParentRepo.ID) + if has { + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) + return + } + if !traverseParentRepo.IsFork { + break + } + traverseParentRepo, err = models.GetRepositoryByID(traverseParentRepo.ForkID) + if err != nil { + ctx.ServerError("GetRepositoryByID", err) + return + } + } + + // Check ownership of organization. + if ctxUser.IsOrganization() { + isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) + if err != nil { + ctx.ServerError("IsOwnedBy", err) + return + } else if !isOwner { + ctx.Error(403) + return + } + } + + repo, err := repo_service.ForkRepository(ctx.User, ctxUser, forkRepo, form.RepoName, form.Description) + if err != nil { + ctx.Data["Err_RepoName"] = true + switch { + case models.IsErrRepoAlreadyExist(err): + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) + case models.IsErrNameReserved(err): + ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplFork, &form) + case models.IsErrNamePatternNotAllowed(err): + ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplFork, &form) + default: + ctx.ServerError("ForkPost", err) + } + return + } + + log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) +} + func checkPullInfo(ctx *context.Context) *models.Issue { issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 663394fe3db6d..f1d2cd64d05d3 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -100,6 +100,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { repo.LowerName = strings.ToLower(newRepoName) repo.Description = form.Description repo.Website = form.Website + repo.IsTemplate = form.Template // Visibility of forked repository is forced sync with base repository. if repo.IsFork { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 13a5bb27084d0..160c6a573bc1c 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -616,6 +616,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo("/:repoid").Get(repo.Fork). Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) + m.Group("/generate", func() { + m.Combo("/:repoid").Get(repo.TemplateGenerate). + Post(bindIgnErr(auth.CreateRepoForm{}), repo.TemplateGeneratePost) + }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) }, reqSignIn) // ***** Release Attachment Download without Signin diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 111609efefb6d..0a93bb56e6e3d 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -15,6 +15,7 @@ {{if .IsArchived}}<i class="archive icon archived-icon"></i>{{end}} {{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{MirrorAddress $.Mirror}}">{{MirrorAddress $.Mirror}}</a></div>{{end}} {{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{SubStr .BaseRepo.RelLink 1 -1}}</a></div>{{end}} + {{if .IsTemplate}}<div class="fork-flag">{{$.i18n.Tr "repo.generated_from"}} <a href="{{.TemplateRepo.Link}}">{{SubStr .TemplateRepo.RelLink 1 -1}}</a></div>{{end}} </div> {{if not .IsBeingCreated}} <div class="repo-buttons"> diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index b23e851139e38..d39e23488cc4b 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -94,6 +94,17 @@ </div> </div> + <div class="fitted item"> + {{if eq $n 0}} + {{if .Repository.IsTemplate}} + <div class="ui tiny blue buttons"> + <a href="{{AppSubUrl}}/repo/generate/{{.Repository.ID}}" class="ui button"> + {{.i18n.Tr "repo.use_template"}} + </a> + </div> + {{end}} + {{end}} + </div> <div class="fitted item"> <!-- Only show clone panel in repository home page --> diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index a93efb8d2584d..800e8e5f31655 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -15,6 +15,13 @@ <label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label> <input id="repo_name" name="repo_name" value="{{.Repository.Name}}" data-repo-name="{{.Repository.Name}}" autofocus required> </div> + <div class="inline field"> + <label>{{.i18n.Tr "repo.template"}}</label> + <div class="ui checkbox"> + <input name="template" type="checkbox" {{if .Repository.IsTemplate}}checked{{end}}> + <label>{{.i18n.Tr "repo.template_helper"}}</label> + </div> + </div> {{if not .Repository.IsFork}} <div class="inline field"> <label>{{.i18n.Tr "repo.visibility"}}</label> From 91034c9598da0fdded50847f7aeb19fec26b4ff4 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Tue, 29 Oct 2019 21:00:22 -0500 Subject: [PATCH 02/30] Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 150 +++++++++++++++++++++++++++++ modules/context/repo.go | 24 +++++ options/locale/locale_en-US.ini | 3 +- routers/repo/pull.go | 100 +++++++++++++------ services/repository/repository.go | 15 +++ templates/repo/pulls/generate.tmpl | 69 +++++++++++++ 6 files changed, 328 insertions(+), 33 deletions(-) create mode 100644 templates/repo/pulls/generate.tmpl diff --git a/models/repo.go b/models/repo.go index fa9374c4aadec..a88f95d16f2b9 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1341,6 +1341,54 @@ func prepareRepoCommit(e Engine, repo *Repository, tmpDir, repoPath string, opts return nil } +func generateRepoCommit(e Engine, repo, templateRepo *Repository, tmpDir string) error { + commitTimeStr := time.Now().Format(time.RFC3339) + authorSig := repo.Owner.NewGitSig() + + // Because this may call hooks we should pass in the environment + env := append(os.Environ(), + "GIT_AUTHOR_NAME="+authorSig.Name, + "GIT_AUTHOR_EMAIL="+authorSig.Email, + "GIT_AUTHOR_DATE="+commitTimeStr, + "GIT_COMMITTER_NAME="+authorSig.Name, + "GIT_COMMITTER_EMAIL="+authorSig.Email, + "GIT_COMMITTER_DATE="+commitTimeStr, + ) + + // Clone to temporary path and do the init commit. + templateRepoPath := templateRepo.repoPath(e) + _, stderr, err := process.GetManager().ExecDirEnv( + -1, "", + fmt.Sprintf("generateRepoCommit(git clone): %s", templateRepoPath), + env, + git.GitExecutable, "clone", "--depth 1", templateRepoPath, tmpDir, + ) + if err != nil { + return fmt.Errorf("git clone: %v - %s", err, stderr) + } + + if err := os.RemoveAll(path.Join(tmpDir, ".git")); err != nil { + return fmt.Errorf("remove git dir: %v", err) + } + + if err := git.InitRepository(tmpDir, false); err != nil { + return err + } + + repoPath := repo.repoPath(e) + _, stderr, err = process.GetManager().ExecDirEnv( + -1, "", + fmt.Sprintf("generateRepoCommit(git remote add): %s", repoPath), + env, + git.GitExecutable, "remote", "add", "origin", repoPath, + ) + if err != nil { + return fmt.Errorf("git remote add: %v - %s", err, stderr) + } + + return initRepoCommit(tmpDir, repo.Owner) +} + // InitRepository initializes README and .gitignore if needed. func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts CreateRepoOptions) (err error) { // Somehow the directory could exist. @@ -1394,6 +1442,46 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C return nil } +// generateRepository initializes repository from template +func generateRepository(e Engine, repoPath string, u *User, repo, templateRepo *Repository) (err error) { + // Somehow the directory could exist. + if com.IsExist(repoPath) { + return fmt.Errorf("generateRepository: path already exists: %s", repoPath) + } + + // Init git bare new repository. + if err = git.InitRepository(repoPath, true); err != nil { + return fmt.Errorf("InitRepository: %v", err) + } else if err = createDelegateHooks(repoPath); err != nil { + return fmt.Errorf("createDelegateHooks: %v", err) + } + + tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond())) + + if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil { + return fmt.Errorf("Failed to create dir %s: %v", tmpDir, err) + } + + defer os.RemoveAll(tmpDir) + + if err = generateRepoCommit(e, repo, templateRepo, tmpDir); err != nil { + return fmt.Errorf("generateRepoCommit: %v", err) + } + + // Re-fetch the repository from database before updating it (else it would + // override changes that were done earlier with sql) + if repo, err = getRepositoryByID(e, repo.ID); err != nil { + return fmt.Errorf("getRepositoryByID: %v", err) + } + + repo.DefaultBranch = "master" + if err = updateRepository(e, repo, false); err != nil { + return fmt.Errorf("updateRepository: %v", err) + } + + return nil +} + var ( reservedRepoNames = []string{".", ".."} reservedRepoPatterns = []string{"*.git", "*.wiki"} @@ -2630,6 +2718,68 @@ func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) ( return repo, sess2.Commit() } +// GenerateRepository generates a repository from a template +func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc string, private bool) (_ *Repository, err error) { + repo := &Repository{ + OwnerID: owner.ID, + Owner: owner, + Name: name, + LowerName: strings.ToLower(name), + Description: desc, + IsPrivate: private, + IsEmpty: templateRepo.IsEmpty, + IsTemplate: true, + TemplateID: templateRepo.ID, + } + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return nil, err + } + + if err = createRepository(sess, doer, owner, repo); err != nil { + return nil, err + } + + repoPath := RepoPath(owner.Name, repo.Name) + if err := generateRepository(sess, repoPath, owner, repo, templateRepo); err != nil { + return nil, err + } + + //Commit repo to get Fork ID + err = sess.Commit() + if err != nil { + return nil, err + } + + if err = repo.UpdateSize(); err != nil { + log.Error("Failed to update size for repository: %v", err) + } + + // Copy LFS meta objects in new session + sess2 := x.NewSession() + defer sess2.Close() + if err = sess2.Begin(); err != nil { + return repo, err + } + + var lfsObjects []*LFSMetaObject + if err = sess2.Where("repository_id=?", templateRepo.ID).Find(&lfsObjects); err != nil { + return repo, err + } + + for _, v := range lfsObjects { + v.ID = 0 + v.RepositoryID = repo.ID + if _, err = sess2.Insert(v); err != nil { + return repo, err + } + } + + return repo, sess2.Commit() +} + // GetForks returns all the forks of the repository func (repo *Repository) GetForks() ([]*Repository, error) { forks := make([]*Repository, 0, repo.NumForks) diff --git a/modules/context/repo.go b/modules/context/repo.go index 8a9c9e4b8cf70..12eed3fac7bef 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -189,6 +189,23 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) { } } +// RetrieveTemplateRepo retrieves used template repository +func RetrieveTemplateRepo(ctx *Context, repo *models.Repository) { + // Non-template repository will not return error in this method. + if err := repo.GetTemplateRepo(); err != nil { + if models.IsErrRepoNotExist(err) { + repo.IsTemplate = false + repo.TemplateID = 0 + return + } + ctx.ServerError("GetTemplateRepo", err) + return + } else if err = repo.TemplateRepo.GetOwner(); err != nil { + ctx.ServerError("TemplateRepo.GetOwner", err) + return + } +} + // ComposeGoGetImport returns go-get-import meta content. func ComposeGoGetImport(owner, repo string) string { /// setting.AppUrl is guaranteed to be parse as url @@ -414,6 +431,13 @@ func RepoAssignment() macaron.Handler { } } + if repo.IsTemplate { + RetrieveTemplateRepo(ctx, repo) + if ctx.Written() { + return + } + } + // Disable everything when the repo is being created if ctx.Repo.Repository.IsBeingCreated() { ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index f936c2722c012..c23850986cbe0 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -591,7 +591,8 @@ fork_repo = Fork Repository fork_from = Fork From fork_visibility_helper = The visibility of a forked repository cannot be changed. use_template = Use this template -generate_from = Generated from +generate_repo = Generate Repository +generate_from = Generate From repo_desc = Description repo_lang = Language repo_gitignore_helper = Select .gitignore templates. diff --git a/routers/repo/pull.go b/routers/repo/pull.go index a212c8af7cb24..dc5f0a89cadba 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -32,6 +32,7 @@ import ( const ( tplFork base.TplName = "repo/pulls/fork" + tplGenerate base.TplName = "repo/pulls/generate" tplCompareDiff base.TplName = "repo/diff/compare" tplPullCommits base.TplName = "repo/pulls/commits" tplPullFiles base.TplName = "repo/pulls/files" @@ -142,6 +143,63 @@ func getForkRepository(ctx *context.Context) *models.Repository { return forkRepo } +func getTemplateRepository(ctx *context.Context) *models.Repository { + templateRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid")) + if err != nil { + if models.IsErrRepoNotExist(err) { + ctx.NotFound("GetRepositoryByID", nil) + } else { + ctx.ServerError("GetRepositoryByID", err) + } + return nil + } + + perm, err := models.GetUserRepoPermission(templateRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil + } + + if templateRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { + if log.IsTrace() { + if templateRepo.IsEmpty { + log.Trace("Empty fork repository %-v", templateRepo) + } else { + log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+ + "User in forkRepo has Permissions: %-+v", + ctx.User, + models.UnitTypeCode, + ctx.Repo, + perm) + } + } + ctx.NotFound("getForkRepository", nil) + return nil + } + + ctx.Data["repo_name"] = templateRepo.Name + ctx.Data["description"] = templateRepo.Description + ctx.Data["IsPrivate"] = templateRepo.IsPrivate + + if err = templateRepo.GetOwner(); err != nil { + ctx.ServerError("GetOwner", err) + return nil + } + ctx.Data["GenerateFrom"] = templateRepo.Owner.Name + "/" + templateRepo.Name + ctx.Data["GenerateFromOwnerID"] = templateRepo.Owner.ID + + if err := ctx.User.GetOwnedOrganizations(); err != nil { + ctx.ServerError("GetOwnedOrganizations", err) + return nil + } + + ctx.Data["Orgs"] = ctx.User.OwnedOrgs + + ctx.Data["ContextUser"] = ctx.User + + return templateRepo +} + // Fork render repository fork page func Fork(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("new_fork") @@ -233,12 +291,12 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) { func TemplateGenerate(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("template_generate") - getForkRepository(ctx) + getTemplateRepository(ctx) if ctx.Written() { return } - ctx.HTML(200, tplFork) + ctx.HTML(200, tplGenerate) } // TemplateGeneratePost response for generating a repository template @@ -250,7 +308,7 @@ func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { return } - forkRepo := getForkRepository(ctx) + templateRepo := getTemplateRepository(ctx) if ctx.Written() { return } @@ -258,32 +316,10 @@ func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { ctx.Data["ContextUser"] = ctxUser if ctx.HasError() { - ctx.HTML(200, tplFork) + ctx.HTML(200, tplGenerate) return } - var err error - var traverseParentRepo = forkRepo - for { - if ctxUser.ID == traverseParentRepo.OwnerID { - ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) - return - } - repo, has := models.HasForkedRepo(ctxUser.ID, traverseParentRepo.ID) - if has { - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) - return - } - if !traverseParentRepo.IsFork { - break - } - traverseParentRepo, err = models.GetRepositoryByID(traverseParentRepo.ForkID) - if err != nil { - ctx.ServerError("GetRepositoryByID", err) - return - } - } - // Check ownership of organization. if ctxUser.IsOrganization() { isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) @@ -296,23 +332,23 @@ func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { } } - repo, err := repo_service.ForkRepository(ctx.User, ctxUser, forkRepo, form.RepoName, form.Description) + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, form.Private) if err != nil { ctx.Data["Err_RepoName"] = true switch { case models.IsErrRepoAlreadyExist(err): - ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplGenerate, &form) case models.IsErrNameReserved(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplFork, &form) + ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplGenerate, &form) case models.IsErrNamePatternNotAllowed(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplFork, &form) + ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplGenerate, &form) default: - ctx.ServerError("ForkPost", err) + ctx.ServerError("TemplateGeneratePost", err) } return } - log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name) + log.Trace("Repository generate[%d]: %s/%s", templateRepo.ID, ctxUser.Name, repo.Name) ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) } diff --git a/services/repository/repository.go b/services/repository/repository.go index 5135435c78161..7bbe0f92b16dc 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -44,6 +44,21 @@ func ForkRepository(doer, u *models.User, oldRepo *models.Repository, name, desc return repo, nil } +// GenerateRepository generates a repository from a template +func GenerateRepository(doer, u *models.User, oldRepo *models.Repository, name, desc string, private bool) (*models.Repository, error) { + repo, err := models.GenerateRepository(doer, u, oldRepo, name, desc, private) + if err != nil { + if repo != nil { + if errDelete := models.DeleteRepository(doer, u.ID, repo.ID); errDelete != nil { + log.Error("Rollback deleteRepository: %v", errDelete) + } + } + return nil, err + } + + return repo, nil +} + // DeleteRepository deletes a repository for a user or organization. func DeleteRepository(doer *models.User, repo *models.Repository) error { if err := models.DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil { diff --git a/templates/repo/pulls/generate.tmpl b/templates/repo/pulls/generate.tmpl new file mode 100644 index 0000000000000..5dedb44cd1292 --- /dev/null +++ b/templates/repo/pulls/generate.tmpl @@ -0,0 +1,69 @@ +{{template "base/head" .}} +<div class="repository new fork"> + <div class="ui middle very relaxed page grid"> + <div class="column"> + <form class="ui form" action="{{.Link}}" method="post"> + {{.CsrfTokenHtml}} + <h3 class="ui top attached header"> + {{.i18n.Tr "new_repo"}} + </h3> + <div class="ui attached segment"> + {{template "base/alert" .}} + <div class="inline required field {{if .Err_Owner}}error{{end}}"> + <label>{{.i18n.Tr "repo.owner"}}</label> + <div class="ui selection owner dropdown"> + <input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required> + <span class="text" title="{{.ContextUser.Name}}"> + <img class="ui mini image" src="{{.ContextUser.RelAvatarLink}}"> + {{.ContextUser.ShortName 20}} + </span> + <i class="dropdown icon"></i> + <div class="menu"> + <div class="item" data-value="{{.SignedUser.ID}}" title="{{.SignedUser.Name}}"> + <img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}"> + {{.SignedUser.ShortName 20}} + </div> + {{range .Orgs}} + <div class="item" data-value="{{.ID}}" title="{{.Name}}"> + <img class="ui mini image" src="{{.RelAvatarLink}}"> + {{.ShortName 20}} + </div> + {{end}} + </div> + </div> + </div> + + <div class="inline field"> + <label>{{.i18n.Tr "repo.generate_from"}}</label> + <a href="{{AppSubUrl}}/{{.GenerateFrom}}">{{.GenerateFrom}}</a> + </div> + <div class="inline required field {{if .Err_RepoName}}error{{end}}"> + <label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label> + <input id="repo_name" name="repo_name" value="{{.repo_name}}" required> + </div> + <div class="inline field"> + <label>{{.i18n.Tr "repo.visibility"}}</label> + <div class="ui read-only checkbox"> + <input type="checkbox" {{if .IsPrivate}}checked{{end}}> + <label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label> + </div> + <span class="help">{{.i18n.Tr "repo.fork_visibility_helper"}}</span> + </div> + <div class="inline field {{if .Err_Description}}error{{end}}"> + <label for="description">{{.i18n.Tr "repo.repo_desc"}}</label> + <textarea id="description" name="description">{{.description}}</textarea> + </div> + + <div class="inline field"> + <label></label> + <button class="ui green button"> + {{.i18n.Tr "repo.generate_repo"}} + </button> + <a class="ui button" href="{{AppSubUrl}}/{{.ForkFrom}}">{{.i18n.Tr "cancel"}}</a> + </div> + </div> + </form> + </div> + </div> +</div> +{{template "base/footer" .}} From 3c90feaf1132abadcf47238e2bdbe101f819cdde Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Tue, 29 Oct 2019 22:02:36 -0500 Subject: [PATCH 03/30] Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 12 ++++++++---- modules/context/repo.go | 3 +-- options/locale/locale_en-US.ini | 1 + routers/repo/pull.go | 6 ++++-- templates/repo/header.tmpl | 2 +- templates/repo/pulls/generate.tmpl | 13 +++++++++---- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/models/repo.go b/models/repo.go index a88f95d16f2b9..6426e1c94672f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -665,6 +665,11 @@ func (repo *Repository) getBaseRepo(e Engine) (err error) { return err } +// IsGenerated returns whether _this_ repository was generated from a template +func (repo *Repository) IsGenerated() bool { + return repo.TemplateID != 0 +} + // GetTemplateRepo populates repo.TemplateRepo for a template repository and // returns an error on failure (NOTE: no error is returned for // non-template repositories, and TemplateRepo will be left untouched) @@ -673,7 +678,7 @@ func (repo *Repository) GetTemplateRepo() (err error) { } func (repo *Repository) getTemplateRepo(e Engine) (err error) { - if !repo.IsTemplate { + if !repo.IsGenerated() { return nil } @@ -1361,7 +1366,7 @@ func generateRepoCommit(e Engine, repo, templateRepo *Repository, tmpDir string) -1, "", fmt.Sprintf("generateRepoCommit(git clone): %s", templateRepoPath), env, - git.GitExecutable, "clone", "--depth 1", templateRepoPath, tmpDir, + git.GitExecutable, "clone", "--depth", "1", templateRepoPath, tmpDir, ) if err != nil { return fmt.Errorf("git clone: %v - %s", err, stderr) @@ -1377,7 +1382,7 @@ func generateRepoCommit(e Engine, repo, templateRepo *Repository, tmpDir string) repoPath := repo.repoPath(e) _, stderr, err = process.GetManager().ExecDirEnv( - -1, "", + -1, tmpDir, fmt.Sprintf("generateRepoCommit(git remote add): %s", repoPath), env, git.GitExecutable, "remote", "add", "origin", repoPath, @@ -2728,7 +2733,6 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc Description: desc, IsPrivate: private, IsEmpty: templateRepo.IsEmpty, - IsTemplate: true, TemplateID: templateRepo.ID, } diff --git a/modules/context/repo.go b/modules/context/repo.go index 12eed3fac7bef..494461fac59b2 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -194,7 +194,6 @@ func RetrieveTemplateRepo(ctx *Context, repo *models.Repository) { // Non-template repository will not return error in this method. if err := repo.GetTemplateRepo(); err != nil { if models.IsErrRepoNotExist(err) { - repo.IsTemplate = false repo.TemplateID = 0 return } @@ -431,7 +430,7 @@ func RepoAssignment() macaron.Handler { } } - if repo.IsTemplate { + if repo.IsGenerated() { RetrieveTemplateRepo(ctx, repo) if ctx.Written() { return diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index c23850986cbe0..a40e50ece281b 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -654,6 +654,7 @@ migrate.migrating_failed = Migrating from <b>%s</b> failed. mirror_from = mirror of forked_from = forked from +generated_from = generated from fork_from_self = You cannot fork a repository you own. fork_guest_user = Sign in to fork this repository. copy_link = Copy diff --git a/routers/repo/pull.go b/routers/repo/pull.go index dc5f0a89cadba..6e12f5f5eb91a 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -179,7 +179,8 @@ func getTemplateRepository(ctx *context.Context) *models.Repository { ctx.Data["repo_name"] = templateRepo.Name ctx.Data["description"] = templateRepo.Description - ctx.Data["IsPrivate"] = templateRepo.IsPrivate + ctx.Data["private"] = templateRepo.IsPrivate + ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate if err = templateRepo.GetOwner(); err != nil { ctx.ServerError("GetOwner", err) @@ -332,7 +333,8 @@ func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { } } - repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, form.Private) + private := form.Private || setting.Repository.ForcePrivate + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, private) if err != nil { ctx.Data["Err_RepoName"] = true switch { diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 0a93bb56e6e3d..dc4543b61e49b 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -15,7 +15,7 @@ {{if .IsArchived}}<i class="archive icon archived-icon"></i>{{end}} {{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{MirrorAddress $.Mirror}}">{{MirrorAddress $.Mirror}}</a></div>{{end}} {{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{SubStr .BaseRepo.RelLink 1 -1}}</a></div>{{end}} - {{if .IsTemplate}}<div class="fork-flag">{{$.i18n.Tr "repo.generated_from"}} <a href="{{.TemplateRepo.Link}}">{{SubStr .TemplateRepo.RelLink 1 -1}}</a></div>{{end}} + {{if .IsGenerated}}<div class="fork-flag">{{$.i18n.Tr "repo.generated_from"}} <a href="{{.TemplateRepo.Link}}">{{SubStr .TemplateRepo.RelLink 1 -1}}</a></div>{{end}} </div> {{if not .IsBeingCreated}} <div class="repo-buttons"> diff --git a/templates/repo/pulls/generate.tmpl b/templates/repo/pulls/generate.tmpl index 5dedb44cd1292..0c422e15d0f48 100644 --- a/templates/repo/pulls/generate.tmpl +++ b/templates/repo/pulls/generate.tmpl @@ -43,11 +43,16 @@ </div> <div class="inline field"> <label>{{.i18n.Tr "repo.visibility"}}</label> - <div class="ui read-only checkbox"> - <input type="checkbox" {{if .IsPrivate}}checked{{end}}> - <label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label> + <div class="ui checkbox"> + {{if .IsForcedPrivate}} + <input name="private" type="checkbox" checked readonly> + <label>{{.i18n.Tr "repo.visibility_helper_forced" | Safe}}</label> + {{else}} + <input name="private" type="checkbox" {{if .private}}checked{{end}}> + <label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label> + {{end}} </div> - <span class="help">{{.i18n.Tr "repo.fork_visibility_helper"}}</span> + <span class="help">{{.i18n.Tr "repo.visibility_description"}}</span> </div> <div class="inline field {{if .Err_Description}}error{{end}}"> <label for="description">{{.i18n.Tr "repo.repo_desc"}}</label> From f58ee2425a8f9c88b94d6c41f7bd444b144f2346 Mon Sep 17 00:00:00 2001 From: John Olheiser <42128690+jolheiser@users.noreply.github.com> Date: Wed, 30 Oct 2019 13:16:32 -0500 Subject: [PATCH 04/30] Fix tabs vs spaces --- templates/repo/home.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index d39e23488cc4b..5812a4f5ba361 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -95,7 +95,7 @@ </div> <div class="fitted item"> - {{if eq $n 0}} + {{if eq $n 0}} {{if .Repository.IsTemplate}} <div class="ui tiny blue buttons"> <a href="{{AppSubUrl}}/repo/generate/{{.Repository.ID}}" class="ui button"> From 8859b38917dfd19e6a2019e9bc1a36a593492681 Mon Sep 17 00:00:00 2001 From: John Olheiser <42128690+jolheiser@users.noreply.github.com> Date: Wed, 30 Oct 2019 13:18:11 -0500 Subject: [PATCH 05/30] Tabs vs Spaces --- templates/repo/settings/options.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 800e8e5f31655..7ded98206cb38 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -18,7 +18,7 @@ <div class="inline field"> <label>{{.i18n.Tr "repo.template"}}</label> <div class="ui checkbox"> - <input name="template" type="checkbox" {{if .Repository.IsTemplate}}checked{{end}}> + <input name="template" type="checkbox" {{if .Repository.IsTemplate}}checked{{end}}> <label>{{.i18n.Tr "repo.template_helper"}}</label> </div> </div> From 5802f966863259cf63353b031855721f6ba743b5 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Wed, 30 Oct 2019 21:18:09 -0500 Subject: [PATCH 06/30] Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/repo_generate_test.go | 66 +++++++++++++++++++ models/fixtures/repository.yml | 26 ++++++++ models/fixtures/user.yml | 17 ++++- models/repo.go | 101 ++++++++++++----------------- models/repo_list.go | 7 ++ models/repo_list_test.go | 6 ++ modules/structs/repo.go | 2 + routers/api/v1/repo/repo.go | 9 +++ 8 files changed, 175 insertions(+), 59 deletions(-) create mode 100644 integrations/repo_generate_test.go diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go new file mode 100644 index 0000000000000..44f91d8bbe0ae --- /dev/null +++ b/integrations/repo_generate_test.go @@ -0,0 +1,66 @@ +// Copyright 2019 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 integrations + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "code.gitea.io/gitea/models" + + "github.com/stretchr/testify/assert" +) + +func testRepoGenerate(t *testing.T, session *TestSession, ownerName, repoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder { + forkOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: generateOwnerName}).(*models.User) + + // Step0: check the existence of the to-fork repo + req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) + resp := session.MakeRequest(t, req, http.StatusNotFound) + + // Step1: go to the main page of repo + req = NewRequestf(t, "GET", "/%s/%s", ownerName, repoName) + resp = session.MakeRequest(t, req, http.StatusOK) + + // Step2: click the fork button + htmlDoc := NewHTMLParser(t, resp.Body) + link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/generate/\"]").Attr("href") + assert.True(t, exists, "The template has changed") + req = NewRequest(t, "GET", link) + resp = session.MakeRequest(t, req, http.StatusOK) + + // Step3: fill the form of the generate + htmlDoc = NewHTMLParser(t, resp.Body) + link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/generate/\"]").Attr("action") + assert.True(t, exists, "The template has changed") + _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value") + assert.True(t, exists, fmt.Sprintf("Generate owner '%s' is not present in select box", generateOwnerName)) + req = NewRequestWithValues(t, "POST", link, map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "uid": fmt.Sprintf("%d", forkOwner.ID), + "repo_name": generateRepoName, + }) + resp = session.MakeRequest(t, req, http.StatusFound) + + // Step4: check the existence of the forked repo + req = NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) + resp = session.MakeRequest(t, req, http.StatusOK) + + return resp +} + +func TestRepoGenerate(t *testing.T) { + prepareTestEnv(t) + session := loginUser(t, "user1") + testRepoGenerate(t, session, "user2", "repo1", "user1", "generated1") +} + +func TestRepoGenerateToOrg(t *testing.T) { + prepareTestEnv(t) + session := loginUser(t, "user2") + testRepoGenerate(t, session, "user2", "repo1", "user3", "generated2") +} diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index cf7d24c6cdb3c..e5c1d08cb5952 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -561,3 +561,29 @@ num_issues: 0 is_mirror: false status: 0 + +- + id: 44 + owner_id: 27 + lower_name: template1 + name: template1 + is_private: true + is_template: true + num_stars: 0 + num_forks: 0 + num_issues: 0 + is_mirror: false + status: 0 + +- + id: 45 + owner_id: 27 + lower_name: template2 + name: template2 + is_private: false + is_template: true + num_stars: 0 + num_forks: 0 + num_issues: 0 + is_mirror: false + status: 0 diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index a204241f9c790..b899fe8d03ee1 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -427,4 +427,19 @@ num_repos: 1 num_members: 0 num_teams: 1 - repo_admin_change_team_access: true \ No newline at end of file + repo_admin_change_team_access: true + +- + id: 27 + lower_name: user27 + name: user27 + full_name: "User27" + email: user27@example.com + passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password + type: 0 # individual + salt: ZogKvWdyEx + is_admin: false + avatar: avatar27 + avatar_email: user27@example.com + num_repos: 2 + is_active: true diff --git a/models/repo.go b/models/repo.go index 6426e1c94672f..865787a6ba7db 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1394,8 +1394,7 @@ func generateRepoCommit(e Engine, repo, templateRepo *Repository, tmpDir string) return initRepoCommit(tmpDir, repo.Owner) } -// InitRepository initializes README and .gitignore if needed. -func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts CreateRepoOptions) (err error) { +func checkInitRepository(repoPath string) (err error) { // Somehow the directory could exist. if com.IsExist(repoPath) { return fmt.Errorf("initRepository: path already exists: %s", repoPath) @@ -1407,6 +1406,14 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C } else if err = createDelegateHooks(repoPath); err != nil { return fmt.Errorf("createDelegateHooks: %v", err) } + return nil +} + +// InitRepository initializes README and .gitignore if needed. +func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts CreateRepoOptions) (err error) { + if err = checkInitRepository(repoPath); err != nil { + return err + } tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond())) @@ -1449,16 +1456,8 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C // generateRepository initializes repository from template func generateRepository(e Engine, repoPath string, u *User, repo, templateRepo *Repository) (err error) { - // Somehow the directory could exist. - if com.IsExist(repoPath) { - return fmt.Errorf("generateRepository: path already exists: %s", repoPath) - } - - // Init git bare new repository. - if err = git.InitRepository(repoPath, true); err != nil { - return fmt.Errorf("InitRepository: %v", err) - } else if err = createDelegateHooks(repoPath); err != nil { - return fmt.Errorf("createDelegateHooks: %v", err) + if err = checkInitRepository(repoPath); err != nil { + return err } tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond())) @@ -1467,14 +1466,17 @@ func generateRepository(e Engine, repoPath string, u *User, repo, templateRepo * return fmt.Errorf("Failed to create dir %s: %v", tmpDir, err) } - defer os.RemoveAll(tmpDir) + defer func() { + if err := os.RemoveAll(tmpDir); err != nil { + log.Error("RemoveAll: %v", err) + } + }() if err = generateRepoCommit(e, repo, templateRepo, tmpDir); err != nil { return fmt.Errorf("generateRepoCommit: %v", err) } - // Re-fetch the repository from database before updating it (else it would - // override changes that were done earlier with sql) + // re-fetch repo if repo, err = getRepositoryByID(e, repo.ID); err != nil { return fmt.Errorf("getRepositoryByID: %v", err) } @@ -2630,6 +2632,29 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) { return repo, has } +func copyLFS(newRepo, oldRepo *Repository) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + var lfsObjects []*LFSMetaObject + if err := sess.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil { + return err + } + + for _, v := range lfsObjects { + v.ID = 0 + v.RepositoryID = newRepo.ID + if _, err := sess.Insert(v); err != nil { + return err + } + } + + return sess.Commit() +} + // ForkRepository forks a repository func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) { forkedRepo, err := oldRepo.GetUserFork(owner.ID) @@ -2700,27 +2725,7 @@ func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) ( log.Error("Failed to update size for repository: %v", err) } - // Copy LFS meta objects in new session - sess2 := x.NewSession() - defer sess2.Close() - if err = sess2.Begin(); err != nil { - return repo, err - } - - var lfsObjects []*LFSMetaObject - if err = sess2.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil { - return repo, err - } - - for _, v := range lfsObjects { - v.ID = 0 - v.RepositoryID = repo.ID - if _, err = sess2.Insert(v); err != nil { - return repo, err - } - } - - return repo, sess2.Commit() + return repo, copyLFS(repo, oldRepo) } // GenerateRepository generates a repository from a template @@ -2751,7 +2756,7 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc return nil, err } - //Commit repo to get Fork ID + //Commit repo to get generated repo ID err = sess.Commit() if err != nil { return nil, err @@ -2761,27 +2766,7 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc log.Error("Failed to update size for repository: %v", err) } - // Copy LFS meta objects in new session - sess2 := x.NewSession() - defer sess2.Close() - if err = sess2.Begin(); err != nil { - return repo, err - } - - var lfsObjects []*LFSMetaObject - if err = sess2.Where("repository_id=?", templateRepo.ID).Find(&lfsObjects); err != nil { - return repo, err - } - - for _, v := range lfsObjects { - v.ID = 0 - v.RepositoryID = repo.ID - if _, err = sess2.Insert(v); err != nil { - return repo, err - } - } - - return repo, sess2.Commit() + return repo, copyLFS(repo, templateRepo) } // GetForks returns all the forks of the repository diff --git a/models/repo_list.go b/models/repo_list.go index c823647eba098..7daf07b4c01cd 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -117,6 +117,7 @@ type SearchRepoOptions struct { OwnerID int64 OrderBy SearchOrderBy Private bool // Include private repositories in results + Template bool // Include template repositories in results StarredByID int64 Page int IsProfile bool @@ -190,6 +191,12 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { cond = cond.And(accessCond) } + if opts.Template { + cond = cond.And(builder.Eq{"is_template": true}) + } else { + cond = cond.And(builder.Eq{"is_template": false}) + } + // Restrict to starred repositories if opts.StarredByID > 0 { cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.StarredByID}))) diff --git a/models/repo_list_test.go b/models/repo_list_test.go index e3a7acd4a4019..ee3ad1a72e5e8 100644 --- a/models/repo_list_test.go +++ b/models/repo_list_test.go @@ -188,6 +188,12 @@ func TestSearchRepository(t *testing.T) { {name: "AllPublic/PublicRepositoriesOfOrganization", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse}, count: 22}, + {name: "Template/Private", + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 26, Private: true, Template: true}, + count: 2}, + {name: "Template/Public", + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 26, Template: true}, + count: 1}, } for _, testCase := range testCases { diff --git a/modules/structs/repo.go b/modules/structs/repo.go index be6a3d4b43e4f..47f3fd43c3ec5 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -125,6 +125,8 @@ type EditRepoOption struct { // Note: you will get a 422 error if the organization restricts changing repository visibility to organization // owners and a non-owner tries to change the value of private. Private *bool `json:"private,omitempty"` + // either `true` to make this repository a template or `false` to make it a normal repository + Template *bool `json:"template,omitempty"` // either `true` to enable issues for this repository or `false` to disable them. HasIssues *bool `json:"has_issues,omitempty"` // set this structure to configure internal issue tracker (requires has_issues) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 422bb0ac3a2ef..1ba3f2816ea58 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -78,6 +78,10 @@ func Search(ctx *context.APIContext) { // in: query // description: include private repositories this user has access to (defaults to true) // type: boolean + // - name: template + // in: query + // description: include template repositories this user has access to (defaults to true) + // type: boolean // - name: page // in: query // description: page number of results to return (1-based) @@ -119,6 +123,7 @@ func Search(ctx *context.APIContext) { TopicOnly: ctx.QueryBool("topic"), Collaborate: util.OptionalBoolNone, Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), + Template: ctx.Query("template") == "" || ctx.QueryBool("template"), UserIsAdmin: ctx.IsUserSiteAdmin(), UserID: ctx.Data["SignedUserID"].(int64), StarredByID: ctx.QueryInt64("starredBy"), @@ -641,6 +646,10 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err repo.IsPrivate = *opts.Private } + if opts.Template != nil { + repo.IsTemplate = *opts.Template + } + if err := models.UpdateRepository(repo, visibilityChanged); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateRepository", err) return err From 8e43600f8c4ca319b4f3b1f513601240bc7fe18b Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 14:42:04 -0500 Subject: [PATCH 07/30] Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> --- .../user2/template1.git/HEAD | 1 + .../user2/template1.git/config | 6 + .../user2/template1.git/description | 1 + .../template1.git/hooks/applypatch-msg.sample | 15 ++ .../template1.git/hooks/commit-msg.sample | 24 +++ .../hooks/fsmonitor-watchman.sample | 114 ++++++++++++ .../user2/template1.git/hooks/post-receive | 15 ++ .../template1.git/hooks/post-receive.d/gitea | 2 + .../template1.git/hooks/post-update.sample | 8 + .../template1.git/hooks/pre-applypatch.sample | 14 ++ .../template1.git/hooks/pre-commit.sample | 49 +++++ .../user2/template1.git/hooks/pre-push.sample | 53 ++++++ .../template1.git/hooks/pre-rebase.sample | 169 ++++++++++++++++++ .../user2/template1.git/hooks/pre-receive | 15 ++ .../template1.git/hooks/pre-receive.d/gitea | 2 + .../template1.git/hooks/pre-receive.sample | 24 +++ .../hooks/prepare-commit-msg.sample | 42 +++++ .../user2/template1.git/hooks/update | 14 ++ .../user2/template1.git/hooks/update.d/gitea | 2 + .../user2/template1.git/hooks/update.sample | 128 +++++++++++++ .../user2/template1.git/info/exclude | 6 + .../user2/template1.git/info/refs | 1 + .../4d/31f3a12656368a8d9180f431d40d0fc408be2d | Bin 0 -> 29 bytes .../51/f84af231345367fd5d61ceb89efb3b6d757061 | Bin 0 -> 121 bytes .../f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f | Bin 0 -> 54 bytes .../user2/template1.git/objects/info/packs | 1 + .../user2/template1.git/refs/heads/master | 1 + .../user2/template2.git/HEAD | 1 + .../user2/template2.git/config | 6 + .../user2/template2.git/description | 1 + .../template2.git/hooks/applypatch-msg.sample | 15 ++ .../template2.git/hooks/commit-msg.sample | 24 +++ .../hooks/fsmonitor-watchman.sample | 114 ++++++++++++ .../user2/template2.git/hooks/post-receive | 15 ++ .../template2.git/hooks/post-receive.d/gitea | 2 + .../template2.git/hooks/post-update.sample | 8 + .../template2.git/hooks/pre-applypatch.sample | 14 ++ .../template2.git/hooks/pre-commit.sample | 49 +++++ .../user2/template2.git/hooks/pre-push.sample | 53 ++++++ .../template2.git/hooks/pre-rebase.sample | 169 ++++++++++++++++++ .../user2/template2.git/hooks/pre-receive | 15 ++ .../template2.git/hooks/pre-receive.d/gitea | 2 + .../template2.git/hooks/pre-receive.sample | 24 +++ .../hooks/prepare-commit-msg.sample | 42 +++++ .../user2/template2.git/hooks/update | 14 ++ .../user2/template2.git/hooks/update.d/gitea | 2 + .../user2/template2.git/hooks/update.sample | 128 +++++++++++++ .../user2/template2.git/info/exclude | 6 + .../user2/template2.git/info/refs | 1 + .../27/e8b0a83a263464323e3915db96600da0cc3259 | Bin 0 -> 156 bytes .../2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 | Bin 0 -> 53 bytes .../34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 | Bin 0 -> 29 bytes .../3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b | Bin 0 -> 54 bytes .../54/102ea58e2c6feb79f7968c71d0cce02746aed2 | Bin 0 -> 33 bytes .../7d/37c46be5f8a70d256011307c2cc4ffec692d59 | Bin 0 -> 122 bytes .../c2/99269b0f493968749529f19c1dc03bc9ac7c76 | Bin 0 -> 85 bytes .../user2/template2.git/objects/info/packs | 1 + .../user2/template2.git/refs/heads/master | 1 + integrations/integration_test.go | 7 +- integrations/repo_generate_test.go | 16 +- models/fixtures/repo_unit.yml | 14 ++ models/fixtures/repository.yml | 6 +- templates/swagger/v1_json.tmpl | 11 ++ 63 files changed, 1456 insertions(+), 12 deletions(-) create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/HEAD create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/config create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/description create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/info/exclude create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/info/refs create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs create mode 100644 integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/HEAD create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/config create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/description create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/info/exclude create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/info/refs create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs create mode 100644 integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/HEAD b/integrations/gitea-repositories-meta/user2/template1.git/HEAD new file mode 100644 index 0000000000000..cb089cd89a7d7 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/config b/integrations/gitea-repositories-meta/user2/template1.git/config new file mode 100644 index 0000000000000..64280b806c976 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = true + symlinks = false + ignorecase = true diff --git a/integrations/gitea-repositories-meta/user2/template1.git/description b/integrations/gitea-repositories-meta/user2/template1.git/description new file mode 100644 index 0000000000000..498b267a8c781 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample new file mode 100644 index 0000000000000..a5d7b84a67345 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample new file mode 100644 index 0000000000000..b58d1184a9d43 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample new file mode 100644 index 0000000000000..e673bb3980f3c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 1) and a time in nanoseconds +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $time) = @ARGV; + +# Check the hook interface version + +if ($version == 1) { + # convert nanoseconds to seconds + $time = int $time / 1000000000; +} else { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree; +if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $git_work_tree = Win32::GetCwd(); + $git_work_tree =~ tr/\\/\//; +} else { + require Cwd; + $git_work_tree = Cwd::cwd(); +} + +my $retry = 1; + +launch_watchman(); + +sub launch_watchman { + + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $time but were not transient (ie created after + # $time but no longer exist). + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + # + # The category of transient files that we want to ignore will have a + # creation clock (cclock) newer than $time_t value and will also not + # currently exist. + + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $time, + "fields": ["name"], + "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] + }] + END + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; <CHLD_OUT>}; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + my $json_pkg; + eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; + } or do { + require JSON::PP; + $json_pkg = "JSON::PP"; + }; + + my $o = $json_pkg->new->utf8->decode($response); + + if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { + print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; + $retry--; + qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + print "/\0"; + eval { launch_watchman() }; + exit 0; + } + + die "Watchman: $o->{error}.\n" . + "Falling back to scanning...\n" if $o->{error}; + + binmode STDOUT, ":utf8"; + local $, = "\0"; + print @{$o->{files}}; +} diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea new file mode 100644 index 0000000000000..82c9c1c9990e4 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample new file mode 100644 index 0000000000000..ec17ec1939b7c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample new file mode 100644 index 0000000000000..4142082bcb939 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample new file mode 100644 index 0000000000000..6a756416384c2 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample new file mode 100644 index 0000000000000..6187dbf4390fc --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# <local ref> <local sha1> <remote ref> <remote sha1> +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo >&2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample new file mode 100644 index 0000000000000..6cbef5c370d8c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea new file mode 100644 index 0000000000000..1ee0ad752188b --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample new file mode 100644 index 0000000000000..a1fd29ec14823 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample new file mode 100644 index 0000000000000..10fa14c5ab013 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update new file mode 100644 index 0000000000000..2918ffb7eb683 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +"${hook}" $1 $2 $3 +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea new file mode 100644 index 0000000000000..ba0376924b868 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample new file mode 100644 index 0000000000000..80ba94135cc37 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 <ref> <oldrev> <newrev>)" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 <ref> <oldrev> <newrev>" >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/info/exclude b/integrations/gitea-repositories-meta/user2/template1.git/info/exclude new file mode 100644 index 0000000000000..a5196d1be8fb5 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/integrations/gitea-repositories-meta/user2/template1.git/info/refs b/integrations/gitea-repositories-meta/user2/template1.git/info/refs new file mode 100644 index 0000000000000..d0df30ce66c1d --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/info/refs @@ -0,0 +1 @@ +51f84af231345367fd5d61ceb89efb3b6d757061 refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d b/integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d new file mode 100644 index 0000000000000000000000000000000000000000..d2f4c1d04ed06ac5c7caf9aca1f44840f06a5f81 GIT binary patch literal 29 kcmb<m^geacKghr&Eg($8^Q`U(PaRLwCy$sIT(#IZ0HNIp)Bpeg literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 b/integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 new file mode 100644 index 0000000000000000000000000000000000000000..aa34a8a767133313f4f9383bb5e1ebe52705de98 GIT binary patch literal 121 zcmV-<0EYi~0hP@?4#F@DKw;*b!WRJ9&R++FSUE;WZHPo$DRJ+QfD^F1?bEB<vNQuq z{$O1MlqZo|{H!@q&^ah!CG@D|RqlZ%QD2j~vfFd(un*}BXOm%k{j{x*lZ^{d%p5~T b&Tzzt=<4@m@{e)1wOK1K_+j@3R{S*{g26ky literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f b/integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f new file mode 100644 index 0000000000000000000000000000000000000000..0699bff833bc1e0a42bfdff36ad7fef2f93505c6 GIT binary patch literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O=0jg{Jc;t%&e<-V#621E4=(i MIQHoR04~iA?=E#0MF0Q* literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs b/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs @@ -0,0 +1 @@ + diff --git a/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master b/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master new file mode 100644 index 0000000000000..ed21b66d23fe2 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master @@ -0,0 +1 @@ +51f84af231345367fd5d61ceb89efb3b6d757061 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/HEAD b/integrations/gitea-repositories-meta/user2/template2.git/HEAD new file mode 100644 index 0000000000000..cb089cd89a7d7 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template2.git/config b/integrations/gitea-repositories-meta/user2/template2.git/config new file mode 100644 index 0000000000000..64280b806c976 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = true + symlinks = false + ignorecase = true diff --git a/integrations/gitea-repositories-meta/user2/template2.git/description b/integrations/gitea-repositories-meta/user2/template2.git/description new file mode 100644 index 0000000000000..498b267a8c781 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample new file mode 100644 index 0000000000000..a5d7b84a67345 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample new file mode 100644 index 0000000000000..b58d1184a9d43 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample new file mode 100644 index 0000000000000..e673bb3980f3c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 1) and a time in nanoseconds +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $time) = @ARGV; + +# Check the hook interface version + +if ($version == 1) { + # convert nanoseconds to seconds + $time = int $time / 1000000000; +} else { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree; +if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $git_work_tree = Win32::GetCwd(); + $git_work_tree =~ tr/\\/\//; +} else { + require Cwd; + $git_work_tree = Cwd::cwd(); +} + +my $retry = 1; + +launch_watchman(); + +sub launch_watchman { + + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $time but were not transient (ie created after + # $time but no longer exist). + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + # + # The category of transient files that we want to ignore will have a + # creation clock (cclock) newer than $time_t value and will also not + # currently exist. + + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $time, + "fields": ["name"], + "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] + }] + END + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; <CHLD_OUT>}; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + my $json_pkg; + eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; + } or do { + require JSON::PP; + $json_pkg = "JSON::PP"; + }; + + my $o = $json_pkg->new->utf8->decode($response); + + if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { + print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; + $retry--; + qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + print "/\0"; + eval { launch_watchman() }; + exit 0; + } + + die "Watchman: $o->{error}.\n" . + "Falling back to scanning...\n" if $o->{error}; + + binmode STDOUT, ":utf8"; + local $, = "\0"; + print @{$o->{files}}; +} diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea new file mode 100644 index 0000000000000..82c9c1c9990e4 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample new file mode 100644 index 0000000000000..ec17ec1939b7c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample new file mode 100644 index 0000000000000..4142082bcb939 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample new file mode 100644 index 0000000000000..6a756416384c2 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample new file mode 100644 index 0000000000000..6187dbf4390fc --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# <local ref> <local sha1> <remote ref> <remote sha1> +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo >&2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample new file mode 100644 index 0000000000000..6cbef5c370d8c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea new file mode 100644 index 0000000000000..1ee0ad752188b --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample new file mode 100644 index 0000000000000..a1fd29ec14823 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample new file mode 100644 index 0000000000000..10fa14c5ab013 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update new file mode 100644 index 0000000000000..2918ffb7eb683 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +"${hook}" $1 $2 $3 +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea new file mode 100644 index 0000000000000..ba0376924b868 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample new file mode 100644 index 0000000000000..80ba94135cc37 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 <ref> <oldrev> <newrev>)" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 <ref> <oldrev> <newrev>" >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/info/exclude b/integrations/gitea-repositories-meta/user2/template2.git/info/exclude new file mode 100644 index 0000000000000..a5196d1be8fb5 --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/integrations/gitea-repositories-meta/user2/template2.git/info/refs b/integrations/gitea-repositories-meta/user2/template2.git/info/refs new file mode 100644 index 0000000000000..5923346315b9a --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/info/refs @@ -0,0 +1 @@ +27e8b0a83a263464323e3915db96600da0cc3259 refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 b/integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 new file mode 100644 index 0000000000000000000000000000000000000000..d32c7922b90210821b040c3f6a7cc76fb7efd725 GIT binary patch literal 156 zcmV;N0Av4n0hNw94#F@H0IB^7cc}>Ljjxpuf~PoZ8&V`e&PL+-DExqCx)}|x^E`=0 z<4@8`(TqgsX@qKNARmJzhg1!*$qd8DlsItk>YZ9yM29>Cwtg(G#uOl<^I*&XfsxtP zTG$h2M=I^|TASXt(okQeY=ZZL)AH<PyJ_PBIvYJieFg`h_;)7dA4ffM*4>f49O&gE Ko%#ZVTSDzjh)b3L literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 b/integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 new file mode 100644 index 0000000000000000000000000000000000000000..ec4a20d868038edfec512aedfce1f55050bfa0a4 GIT binary patch literal 53 zcmV-50LuS(0V^p=O;s>9V=y!@Ff%bxC`m0Y(JQGaVF(e>TiU0S|GM(~w4TBXXCA1# Lt-AyOK-m$F<Rldz literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 b/integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 new file mode 100644 index 0000000000000000000000000000000000000000..c7f5a6208ac3a9ab45cb8e3675ef280ca94f5d1d GIT binary patch literal 29 kcmb<m^geacKghr&Eg($8^Q`U(PaRLwM~|2oTy@zv0io9k)&Kwi literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b b/integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b new file mode 100644 index 0000000000000000000000000000000000000000..634e054ba2a917e7293d30087ad9858b012e7d2b GIT binary patch literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O<^!8?)Cknu<e)r{|`=zm*zz- MI9k3P06;<!VK@mETmS$7 literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 b/integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 new file mode 100644 index 0000000000000000000000000000000000000000..8d53da3cec261a07f798dff066c6d64d62d5e679 GIT binary patch literal 33 pcmb<m^geacKgeK93dhM4I$;cpTv{hxxzjY~$fOWkh6-VhmjL!)4vGK( literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 b/integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 new file mode 100644 index 0000000000000000000000000000000000000000..a3f4aa22bb303a78cd21adb4db039ffba1835a73 GIT binary patch literal 122 zcmV-=0EPc}0hP^54#FT5Mq$US;%-30<yD#(<J4sU{wRrU6S&>KQCHyP%)XqmElU&P zU=Pv(vbnmsa1Oaz21=@T0}X`Pq^Wq002k-7O1nI_PWwPNbQTOT*H7E}ILWvW`^k70 ceVpm2z1FIHPlA7px~)xGdeIN7H<Cd$n^0~%C;$Ke literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 b/integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 new file mode 100644 index 0000000000000000000000000000000000000000..dafe273a1d5d977b6e8e659359c4c8e7c2a02131 GIT binary patch literal 85 zcmV-b0IL6Z0V^p=O;s?nU@$Z=Ff%bx2y%6F@paY9O<^!8?)Cknu<e)r{|`=zm*zz- rI9k5l!~h5sN>YnU81%P(nf++t<(12nxf6E(oov(F$}|}OA6y>|PWvaH literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs b/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs @@ -0,0 +1 @@ + diff --git a/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master b/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master new file mode 100644 index 0000000000000..690e09de22e6b --- /dev/null +++ b/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master @@ -0,0 +1 @@ +27e8b0a83a263464323e3915db96600da0cc3259 diff --git a/integrations/integration_test.go b/integrations/integration_test.go index 897315f2aefd8..8d7f47dcfbd95 100644 --- a/integrations/integration_test.go +++ b/integrations/integration_test.go @@ -18,6 +18,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" "testing" @@ -102,7 +103,11 @@ func initIntegrationTest() { fmt.Println("Environment variable $GITEA_ROOT not set") os.Exit(1) } - setting.AppPath = path.Join(giteaRoot, "gitea") + giteaBinary := "gitea" + if runtime.GOOS == "windows" { + giteaBinary += ".exe" + } + setting.AppPath = path.Join(giteaRoot, giteaBinary) if _, err := os.Stat(setting.AppPath); err != nil { fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath) os.Exit(1) diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index 44f91d8bbe0ae..b0c963e3df33c 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -15,18 +15,18 @@ import ( "github.com/stretchr/testify/assert" ) -func testRepoGenerate(t *testing.T, session *TestSession, ownerName, repoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder { +func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, templateRepoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder { forkOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: generateOwnerName}).(*models.User) - // Step0: check the existence of the to-fork repo + // Step0: check the existence of the generated repo req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) resp := session.MakeRequest(t, req, http.StatusNotFound) - // Step1: go to the main page of repo - req = NewRequestf(t, "GET", "/%s/%s", ownerName, repoName) + // Step1: go to the main page of template repo + req = NewRequestf(t, "GET", "/%s/%s", templateOwnerName, templateRepoName) resp = session.MakeRequest(t, req, http.StatusOK) - // Step2: click the fork button + // Step2: click the "Use this template" button htmlDoc := NewHTMLParser(t, resp.Body) link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/generate/\"]").Attr("href") assert.True(t, exists, "The template has changed") @@ -46,7 +46,7 @@ func testRepoGenerate(t *testing.T, session *TestSession, ownerName, repoName, g }) resp = session.MakeRequest(t, req, http.StatusFound) - // Step4: check the existence of the forked repo + // Step4: check the existence of the generated repo req = NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) resp = session.MakeRequest(t, req, http.StatusOK) @@ -56,11 +56,11 @@ func testRepoGenerate(t *testing.T, session *TestSession, ownerName, repoName, g func TestRepoGenerate(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user1") - testRepoGenerate(t, session, "user2", "repo1", "user1", "generated1") + testRepoGenerate(t, session, "user2", "template1", "user1", "generated1") } func TestRepoGenerateToOrg(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user2") - testRepoGenerate(t, session, "user2", "repo1", "user3", "generated2") + testRepoGenerate(t, session, "user2", "template2", "user3", "generated2") } diff --git a/models/fixtures/repo_unit.yml b/models/fixtures/repo_unit.yml index 014e5155baff9..28c606da43787 100644 --- a/models/fixtures/repo_unit.yml +++ b/models/fixtures/repo_unit.yml @@ -438,3 +438,17 @@ type: 3 config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMerge\":true,\"AllowSquash\":true}" created_unix: 946684810 + +- + id: 64 + repo_id: 44 + type: 1 + config: "{}" + created_unix: 946684810 + +- + id: 65 + repo_id: 45 + type: 1 + config: "{}" + created_unix: 946684810 diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index e5c1d08cb5952..32f34b8671a23 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -564,10 +564,10 @@ - id: 44 - owner_id: 27 + owner_id: 2 lower_name: template1 name: template1 - is_private: true + is_private: false is_template: true num_stars: 0 num_forks: 0 @@ -577,7 +577,7 @@ - id: 45 - owner_id: 27 + owner_id: 2 lower_name: template2 name: template2 is_private: false diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 5be36d23be94c..6894e0e410236 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1189,6 +1189,12 @@ "name": "private", "in": "query" }, + { + "type": "boolean", + "description": "include template repositories this user has access to (defaults to true)", + "name": "template", + "in": "query" + }, { "type": "integer", "description": "page number of results to return (1-based)", @@ -8565,6 +8571,11 @@ "type": "boolean", "x-go-name": "Private" }, + "template": { + "description": "either `true` to make this repository a template or `false` to make it a normal repository", + "type": "boolean", + "x-go-name": "Template" + }, "website": { "description": "a URL with more information about the repository.", "type": "string", From bb56344ba57c4bf0b4a0bb53dc3710d927fb5c0b Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 14:50:39 -0500 Subject: [PATCH 08/30] Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/repo.go b/models/repo.go index 865787a6ba7db..40fdcea039e0c 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1455,7 +1455,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C } // generateRepository initializes repository from template -func generateRepository(e Engine, repoPath string, u *User, repo, templateRepo *Repository) (err error) { +func generateRepository(e Engine, repoPath string, repo, templateRepo *Repository) (err error) { if err = checkInitRepository(repoPath); err != nil { return err } @@ -2752,7 +2752,7 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc } repoPath := RepoPath(owner.Name, repo.Name) - if err := generateRepository(sess, repoPath, owner, repo, templateRepo); err != nil { + if err := generateRepository(sess, repoPath, repo, templateRepo); err != nil { return nil, err } From 53ea33ab132fc263adc47774e6c9efd0f1c63e4f Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 14:59:53 -0500 Subject: [PATCH 09/30] Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> --- .../user2/template1.git/HEAD | 1 - .../user2/template1.git/config | 6 - .../user2/template1.git/description | 1 - .../template1.git/hooks/applypatch-msg.sample | 15 -- .../template1.git/hooks/commit-msg.sample | 24 --- .../hooks/fsmonitor-watchman.sample | 114 ------------ .../user2/template1.git/hooks/post-receive | 15 -- .../template1.git/hooks/post-receive.d/gitea | 2 - .../template1.git/hooks/post-update.sample | 8 - .../template1.git/hooks/pre-applypatch.sample | 14 -- .../template1.git/hooks/pre-commit.sample | 49 ----- .../user2/template1.git/hooks/pre-push.sample | 53 ------ .../template1.git/hooks/pre-rebase.sample | 169 ------------------ .../user2/template1.git/hooks/pre-receive | 15 -- .../template1.git/hooks/pre-receive.d/gitea | 2 - .../template1.git/hooks/pre-receive.sample | 24 --- .../hooks/prepare-commit-msg.sample | 42 ----- .../user2/template1.git/hooks/update | 14 -- .../user2/template1.git/hooks/update.d/gitea | 2 - .../user2/template1.git/hooks/update.sample | 128 ------------- .../user2/template1.git/info/exclude | 6 - .../user2/template1.git/info/refs | 1 - .../4d/31f3a12656368a8d9180f431d40d0fc408be2d | Bin 29 -> 0 bytes .../51/f84af231345367fd5d61ceb89efb3b6d757061 | Bin 121 -> 0 bytes .../f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f | Bin 54 -> 0 bytes .../user2/template1.git/objects/info/packs | 1 - .../user2/template1.git/refs/heads/master | 1 - .../user2/template2.git/HEAD | 1 - .../user2/template2.git/config | 6 - .../user2/template2.git/description | 1 - .../template2.git/hooks/applypatch-msg.sample | 15 -- .../template2.git/hooks/commit-msg.sample | 24 --- .../hooks/fsmonitor-watchman.sample | 114 ------------ .../user2/template2.git/hooks/post-receive | 15 -- .../template2.git/hooks/post-receive.d/gitea | 2 - .../template2.git/hooks/post-update.sample | 8 - .../template2.git/hooks/pre-applypatch.sample | 14 -- .../template2.git/hooks/pre-commit.sample | 49 ----- .../user2/template2.git/hooks/pre-push.sample | 53 ------ .../template2.git/hooks/pre-rebase.sample | 169 ------------------ .../user2/template2.git/hooks/pre-receive | 15 -- .../template2.git/hooks/pre-receive.d/gitea | 2 - .../template2.git/hooks/pre-receive.sample | 24 --- .../hooks/prepare-commit-msg.sample | 42 ----- .../user2/template2.git/hooks/update | 14 -- .../user2/template2.git/hooks/update.d/gitea | 2 - .../user2/template2.git/hooks/update.sample | 128 ------------- .../user2/template2.git/info/exclude | 6 - .../user2/template2.git/info/refs | 1 - .../27/e8b0a83a263464323e3915db96600da0cc3259 | Bin 156 -> 0 bytes .../2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 | Bin 53 -> 0 bytes .../34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 | Bin 29 -> 0 bytes .../3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b | Bin 54 -> 0 bytes .../54/102ea58e2c6feb79f7968c71d0cce02746aed2 | Bin 33 -> 0 bytes .../7d/37c46be5f8a70d256011307c2cc4ffec692d59 | Bin 122 -> 0 bytes .../c2/99269b0f493968749529f19c1dc03bc9ac7c76 | Bin 85 -> 0 bytes .../user2/template2.git/objects/info/packs | 1 - .../user2/template2.git/refs/heads/master | 1 - integrations/repo_generate_test.go | 4 +- models/fixtures/repository.yml | 1 + models/fixtures/user.yml | 15 -- 61 files changed, 3 insertions(+), 1431 deletions(-) delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/HEAD delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/config delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/description delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/info/exclude delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/info/refs delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs delete mode 100644 integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/HEAD delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/config delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/description delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/info/exclude delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/info/refs delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs delete mode 100644 integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/HEAD b/integrations/gitea-repositories-meta/user2/template1.git/HEAD deleted file mode 100644 index cb089cd89a7d7..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/config b/integrations/gitea-repositories-meta/user2/template1.git/config deleted file mode 100644 index 64280b806c976..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/config +++ /dev/null @@ -1,6 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = false - bare = true - symlinks = false - ignorecase = true diff --git a/integrations/gitea-repositories-meta/user2/template1.git/description b/integrations/gitea-repositories-meta/user2/template1.git/description deleted file mode 100644 index 498b267a8c781..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample deleted file mode 100644 index a5d7b84a67345..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -commitmsg="$(git rev-parse --git-path hooks/commit-msg)" -test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} -: diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample deleted file mode 100644 index b58d1184a9d43..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample deleted file mode 100644 index e673bb3980f3c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/fsmonitor-watchman.sample +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use IPC::Open2; - -# An example hook script to integrate Watchman -# (https://facebook.github.io/watchman/) with git to speed up detecting -# new and modified files. -# -# The hook is passed a version (currently 1) and a time in nanoseconds -# formatted as a string and outputs to stdout all files that have been -# modified since the given time. Paths must be relative to the root of -# the working tree and separated by a single NUL. -# -# To enable this hook, rename this file to "query-watchman" and set -# 'git config core.fsmonitor .git/hooks/query-watchman' -# -my ($version, $time) = @ARGV; - -# Check the hook interface version - -if ($version == 1) { - # convert nanoseconds to seconds - $time = int $time / 1000000000; -} else { - die "Unsupported query-fsmonitor hook version '$version'.\n" . - "Falling back to scanning...\n"; -} - -my $git_work_tree; -if ($^O =~ 'msys' || $^O =~ 'cygwin') { - $git_work_tree = Win32::GetCwd(); - $git_work_tree =~ tr/\\/\//; -} else { - require Cwd; - $git_work_tree = Cwd::cwd(); -} - -my $retry = 1; - -launch_watchman(); - -sub launch_watchman { - - my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') - or die "open2() failed: $!\n" . - "Falling back to scanning...\n"; - - # In the query expression below we're asking for names of files that - # changed since $time but were not transient (ie created after - # $time but no longer exist). - # - # To accomplish this, we're using the "since" generator to use the - # recency index to select candidate nodes and "fields" to limit the - # output to file names only. Then we're using the "expression" term to - # further constrain the results. - # - # The category of transient files that we want to ignore will have a - # creation clock (cclock) newer than $time_t value and will also not - # currently exist. - - my $query = <<" END"; - ["query", "$git_work_tree", { - "since": $time, - "fields": ["name"], - "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] - }] - END - - print CHLD_IN $query; - close CHLD_IN; - my $response = do {local $/; <CHLD_OUT>}; - - die "Watchman: command returned no output.\n" . - "Falling back to scanning...\n" if $response eq ""; - die "Watchman: command returned invalid output: $response\n" . - "Falling back to scanning...\n" unless $response =~ /^\{/; - - my $json_pkg; - eval { - require JSON::XS; - $json_pkg = "JSON::XS"; - 1; - } or do { - require JSON::PP; - $json_pkg = "JSON::PP"; - }; - - my $o = $json_pkg->new->utf8->decode($response); - - if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { - print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; - $retry--; - qx/watchman watch "$git_work_tree"/; - die "Failed to make watchman watch '$git_work_tree'.\n" . - "Falling back to scanning...\n" if $? != 0; - - # Watchman will always return all files on the first query so - # return the fast "everything is dirty" flag to git and do the - # Watchman query just to get it over with now so we won't pay - # the cost in git to look up each individual file. - print "/\0"; - eval { launch_watchman() }; - exit 0; - } - - die "Watchman: $o->{error}.\n" . - "Falling back to scanning...\n" if $o->{error}; - - binmode STDOUT, ":utf8"; - local $, = "\0"; - print @{$o->{files}}; -} diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive deleted file mode 100644 index 1733c16a3757c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -data=$(cat) -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -echo "${data}" | "${hook}" -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea deleted file mode 100644 index 82c9c1c9990e4..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-receive.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample deleted file mode 100644 index ec17ec1939b7c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample deleted file mode 100644 index 4142082bcb939..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -precommit="$(git rev-parse --git-path hooks/pre-commit)" -test -x "$precommit" && exec "$precommit" ${1+"$@"} -: diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample deleted file mode 100644 index 6a756416384c2..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-commit.sample +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=$(git hash-object -t tree /dev/null) -fi - -# If you want to allow non-ASCII filenames set this variable to true. -allownonascii=$(git config --bool hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ASCII filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - cat <<\EOF -Error: Attempt to add a non-ASCII file name. - -This can cause problems if you want to work with people on other platforms. - -To be portable it is advisable to rename the file. - -If you know what you are doing you can disable this check using: - - git config hooks.allownonascii true -EOF - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample deleted file mode 100644 index 6187dbf4390fc..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-push.sample +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# An example hook script to verify what is about to be pushed. Called by "git -# push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# <local ref> <local sha1> <remote ref> <remote sha1> -# -# This sample shows how to prevent push of commits where the log message starts -# with "WIP" (work in progress). - -remote="$1" -url="$2" - -z40=0000000000000000000000000000000000000000 - -while read local_ref local_sha remote_ref remote_sha -do - if [ "$local_sha" = $z40 ] - then - # Handle delete - : - else - if [ "$remote_sha" = $z40 ] - then - # New branch, examine all commits - range="$local_sha" - else - # Update to existing branch, examine new commits - range="$remote_sha..$local_sha" - fi - - # Check for WIP commit - commit=`git rev-list -n 1 --grep '^WIP' "$range"` - if [ -n "$commit" ] - then - echo >&2 "Found WIP commit in $local_ref, not pushing" - exit 1 - fi - fi -done - -exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample deleted file mode 100644 index 6cbef5c370d8c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up to date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive deleted file mode 100644 index 1733c16a3757c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -data=$(cat) -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -echo "${data}" | "${hook}" -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea deleted file mode 100644 index 1ee0ad752188b..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample deleted file mode 100644 index a1fd29ec14823..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/pre-receive.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to make use of push options. -# The example simply echoes all push options that start with 'echoback=' -# and rejects all pushes when the "reject" push option is used. -# -# To enable this hook, rename this file to "pre-receive". - -if test -n "$GIT_PUSH_OPTION_COUNT" -then - i=0 - while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" - do - eval "value=\$GIT_PUSH_OPTION_$i" - case "$value" in - echoback=*) - echo "echo from the pre-receive-hook: ${value#*=}" >&2 - ;; - reject) - exit 1 - esac - i=$((i + 1)) - done -fi diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample deleted file mode 100644 index 10fa14c5ab013..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first one removes the -# "# Please enter the commit message..." help message. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -COMMIT_MSG_FILE=$1 -COMMIT_SOURCE=$2 -SHA1=$3 - -/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" - -# case "$COMMIT_SOURCE,$SHA1" in -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; -# *) ;; -# esac - -# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" -# if test -z "$COMMIT_SOURCE" -# then -# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" -# fi diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update deleted file mode 100644 index 2918ffb7eb683..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -"${hook}" $1 $2 $3 -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea deleted file mode 100644 index ba0376924b868..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample b/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample deleted file mode 100644 index 80ba94135cc37..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to block unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 <ref> <oldrev> <newrev>)" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "usage: $0 <ref> <oldrev> <newrev>" >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template1.git/info/exclude b/integrations/gitea-repositories-meta/user2/template1.git/info/exclude deleted file mode 100644 index a5196d1be8fb5..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/integrations/gitea-repositories-meta/user2/template1.git/info/refs b/integrations/gitea-repositories-meta/user2/template1.git/info/refs deleted file mode 100644 index d0df30ce66c1d..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/info/refs +++ /dev/null @@ -1 +0,0 @@ -51f84af231345367fd5d61ceb89efb3b6d757061 refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d b/integrations/gitea-repositories-meta/user2/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d deleted file mode 100644 index d2f4c1d04ed06ac5c7caf9aca1f44840f06a5f81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 kcmb<m^geacKghr&Eg($8^Q`U(PaRLwCy$sIT(#IZ0HNIp)Bpeg diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 b/integrations/gitea-repositories-meta/user2/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 deleted file mode 100644 index aa34a8a767133313f4f9383bb5e1ebe52705de98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmV-<0EYi~0hP@?4#F@DKw;*b!WRJ9&R++FSUE;WZHPo$DRJ+QfD^F1?bEB<vNQuq z{$O1MlqZo|{H!@q&^ah!CG@D|RqlZ%QD2j~vfFd(un*}BXOm%k{j{x*lZ^{d%p5~T b&Tzzt=<4@m@{e)1wOK1K_+j@3R{S*{g26ky diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f b/integrations/gitea-repositories-meta/user2/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f deleted file mode 100644 index 0699bff833bc1e0a42bfdff36ad7fef2f93505c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O=0jg{Jc;t%&e<-V#621E4=(i MIQHoR04~iA?=E#0MF0Q* diff --git a/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs b/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs deleted file mode 100644 index 8b137891791fe..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/objects/info/packs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master b/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master deleted file mode 100644 index ed21b66d23fe2..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template1.git/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -51f84af231345367fd5d61ceb89efb3b6d757061 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/HEAD b/integrations/gitea-repositories-meta/user2/template2.git/HEAD deleted file mode 100644 index cb089cd89a7d7..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template2.git/config b/integrations/gitea-repositories-meta/user2/template2.git/config deleted file mode 100644 index 64280b806c976..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/config +++ /dev/null @@ -1,6 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = false - bare = true - symlinks = false - ignorecase = true diff --git a/integrations/gitea-repositories-meta/user2/template2.git/description b/integrations/gitea-repositories-meta/user2/template2.git/description deleted file mode 100644 index 498b267a8c781..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample deleted file mode 100644 index a5d7b84a67345..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -commitmsg="$(git rev-parse --git-path hooks/commit-msg)" -test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} -: diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample deleted file mode 100644 index b58d1184a9d43..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample deleted file mode 100644 index e673bb3980f3c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/fsmonitor-watchman.sample +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use IPC::Open2; - -# An example hook script to integrate Watchman -# (https://facebook.github.io/watchman/) with git to speed up detecting -# new and modified files. -# -# The hook is passed a version (currently 1) and a time in nanoseconds -# formatted as a string and outputs to stdout all files that have been -# modified since the given time. Paths must be relative to the root of -# the working tree and separated by a single NUL. -# -# To enable this hook, rename this file to "query-watchman" and set -# 'git config core.fsmonitor .git/hooks/query-watchman' -# -my ($version, $time) = @ARGV; - -# Check the hook interface version - -if ($version == 1) { - # convert nanoseconds to seconds - $time = int $time / 1000000000; -} else { - die "Unsupported query-fsmonitor hook version '$version'.\n" . - "Falling back to scanning...\n"; -} - -my $git_work_tree; -if ($^O =~ 'msys' || $^O =~ 'cygwin') { - $git_work_tree = Win32::GetCwd(); - $git_work_tree =~ tr/\\/\//; -} else { - require Cwd; - $git_work_tree = Cwd::cwd(); -} - -my $retry = 1; - -launch_watchman(); - -sub launch_watchman { - - my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') - or die "open2() failed: $!\n" . - "Falling back to scanning...\n"; - - # In the query expression below we're asking for names of files that - # changed since $time but were not transient (ie created after - # $time but no longer exist). - # - # To accomplish this, we're using the "since" generator to use the - # recency index to select candidate nodes and "fields" to limit the - # output to file names only. Then we're using the "expression" term to - # further constrain the results. - # - # The category of transient files that we want to ignore will have a - # creation clock (cclock) newer than $time_t value and will also not - # currently exist. - - my $query = <<" END"; - ["query", "$git_work_tree", { - "since": $time, - "fields": ["name"], - "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] - }] - END - - print CHLD_IN $query; - close CHLD_IN; - my $response = do {local $/; <CHLD_OUT>}; - - die "Watchman: command returned no output.\n" . - "Falling back to scanning...\n" if $response eq ""; - die "Watchman: command returned invalid output: $response\n" . - "Falling back to scanning...\n" unless $response =~ /^\{/; - - my $json_pkg; - eval { - require JSON::XS; - $json_pkg = "JSON::XS"; - 1; - } or do { - require JSON::PP; - $json_pkg = "JSON::PP"; - }; - - my $o = $json_pkg->new->utf8->decode($response); - - if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { - print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; - $retry--; - qx/watchman watch "$git_work_tree"/; - die "Failed to make watchman watch '$git_work_tree'.\n" . - "Falling back to scanning...\n" if $? != 0; - - # Watchman will always return all files on the first query so - # return the fast "everything is dirty" flag to git and do the - # Watchman query just to get it over with now so we won't pay - # the cost in git to look up each individual file. - print "/\0"; - eval { launch_watchman() }; - exit 0; - } - - die "Watchman: $o->{error}.\n" . - "Falling back to scanning...\n" if $o->{error}; - - binmode STDOUT, ":utf8"; - local $, = "\0"; - print @{$o->{files}}; -} diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive deleted file mode 100644 index 1733c16a3757c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -data=$(cat) -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -echo "${data}" | "${hook}" -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea deleted file mode 100644 index 82c9c1c9990e4..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-receive.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample deleted file mode 100644 index ec17ec1939b7c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample deleted file mode 100644 index 4142082bcb939..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -precommit="$(git rev-parse --git-path hooks/pre-commit)" -test -x "$precommit" && exec "$precommit" ${1+"$@"} -: diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample deleted file mode 100644 index 6a756416384c2..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-commit.sample +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=$(git hash-object -t tree /dev/null) -fi - -# If you want to allow non-ASCII filenames set this variable to true. -allownonascii=$(git config --bool hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ASCII filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - cat <<\EOF -Error: Attempt to add a non-ASCII file name. - -This can cause problems if you want to work with people on other platforms. - -To be portable it is advisable to rename the file. - -If you know what you are doing you can disable this check using: - - git config hooks.allownonascii true -EOF - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample deleted file mode 100644 index 6187dbf4390fc..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-push.sample +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# An example hook script to verify what is about to be pushed. Called by "git -# push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# <local ref> <local sha1> <remote ref> <remote sha1> -# -# This sample shows how to prevent push of commits where the log message starts -# with "WIP" (work in progress). - -remote="$1" -url="$2" - -z40=0000000000000000000000000000000000000000 - -while read local_ref local_sha remote_ref remote_sha -do - if [ "$local_sha" = $z40 ] - then - # Handle delete - : - else - if [ "$remote_sha" = $z40 ] - then - # New branch, examine all commits - range="$local_sha" - else - # Update to existing branch, examine new commits - range="$remote_sha..$local_sha" - fi - - # Check for WIP commit - commit=`git rev-list -n 1 --grep '^WIP' "$range"` - if [ -n "$commit" ] - then - echo >&2 "Found WIP commit in $local_ref, not pushing" - exit 1 - fi - fi -done - -exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample deleted file mode 100644 index 6cbef5c370d8c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up to date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive deleted file mode 100644 index 1733c16a3757c..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -data=$(cat) -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -echo "${data}" | "${hook}" -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea deleted file mode 100644 index 1ee0ad752188b..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample deleted file mode 100644 index a1fd29ec14823..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/pre-receive.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to make use of push options. -# The example simply echoes all push options that start with 'echoback=' -# and rejects all pushes when the "reject" push option is used. -# -# To enable this hook, rename this file to "pre-receive". - -if test -n "$GIT_PUSH_OPTION_COUNT" -then - i=0 - while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" - do - eval "value=\$GIT_PUSH_OPTION_$i" - case "$value" in - echoback=*) - echo "echo from the pre-receive-hook: ${value#*=}" >&2 - ;; - reject) - exit 1 - esac - i=$((i + 1)) - done -fi diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample deleted file mode 100644 index 10fa14c5ab013..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first one removes the -# "# Please enter the commit message..." help message. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -COMMIT_MSG_FILE=$1 -COMMIT_SOURCE=$2 -SHA1=$3 - -/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" - -# case "$COMMIT_SOURCE,$SHA1" in -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; -# *) ;; -# esac - -# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" -# if test -z "$COMMIT_SOURCE" -# then -# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" -# fi diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update deleted file mode 100644 index 2918ffb7eb683..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -exitcodes="" -hookname=$(basename $0) -GIT_DIR=${GIT_DIR:-$(dirname $0)} - -for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do -test -x "${hook}" || continue -"${hook}" $1 $2 $3 -exitcodes="${exitcodes} $?" -done - -for i in ${exitcodes}; do -[ ${i} -eq 0 ] || exit ${i} -done diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea deleted file mode 100644 index ba0376924b868..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.d/gitea +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample b/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample deleted file mode 100644 index 80ba94135cc37..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to block unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 <ref> <oldrev> <newrev>)" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "usage: $0 <ref> <oldrev> <newrev>" >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/info/exclude b/integrations/gitea-repositories-meta/user2/template2.git/info/exclude deleted file mode 100644 index a5196d1be8fb5..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/integrations/gitea-repositories-meta/user2/template2.git/info/refs b/integrations/gitea-repositories-meta/user2/template2.git/info/refs deleted file mode 100644 index 5923346315b9a..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/info/refs +++ /dev/null @@ -1 +0,0 @@ -27e8b0a83a263464323e3915db96600da0cc3259 refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 b/integrations/gitea-repositories-meta/user2/template2.git/objects/27/e8b0a83a263464323e3915db96600da0cc3259 deleted file mode 100644 index d32c7922b90210821b040c3f6a7cc76fb7efd725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmV;N0Av4n0hNw94#F@H0IB^7cc}>Ljjxpuf~PoZ8&V`e&PL+-DExqCx)}|x^E`=0 z<4@8`(TqgsX@qKNARmJzhg1!*$qd8DlsItk>YZ9yM29>Cwtg(G#uOl<^I*&XfsxtP zTG$h2M=I^|TASXt(okQeY=ZZL)AH<PyJ_PBIvYJieFg`h_;)7dA4ffM*4>f49O&gE Ko%#ZVTSDzjh)b3L diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 b/integrations/gitea-repositories-meta/user2/template2.git/objects/2f/b5f49be2a1d3a9a6230b60bbfd933c8d850293 deleted file mode 100644 index ec4a20d868038edfec512aedfce1f55050bfa0a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmV-50LuS(0V^p=O;s>9V=y!@Ff%bxC`m0Y(JQGaVF(e>TiU0S|GM(~w4TBXXCA1# Lt-AyOK-m$F<Rldz diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 b/integrations/gitea-repositories-meta/user2/template2.git/objects/34/738d4dfc20b6fa2ffff04221d29e59a0c577b7 deleted file mode 100644 index c7f5a6208ac3a9ab45cb8e3675ef280ca94f5d1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 kcmb<m^geacKghr&Eg($8^Q`U(PaRLwM~|2oTy@zv0io9k)&Kwi diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b b/integrations/gitea-repositories-meta/user2/template2.git/objects/3b/f49c1b6bf31eecafd2e0ee692a7c518ee1c44b deleted file mode 100644 index 634e054ba2a917e7293d30087ad9858b012e7d2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O<^!8?)Cknu<e)r{|`=zm*zz- MI9k3P06;<!VK@mETmS$7 diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 b/integrations/gitea-repositories-meta/user2/template2.git/objects/54/102ea58e2c6feb79f7968c71d0cce02746aed2 deleted file mode 100644 index 8d53da3cec261a07f798dff066c6d64d62d5e679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33 pcmb<m^geacKgeK93dhM4I$;cpTv{hxxzjY~$fOWkh6-VhmjL!)4vGK( diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 b/integrations/gitea-repositories-meta/user2/template2.git/objects/7d/37c46be5f8a70d256011307c2cc4ffec692d59 deleted file mode 100644 index a3f4aa22bb303a78cd21adb4db039ffba1835a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122 zcmV-=0EPc}0hP^54#FT5Mq$US;%-30<yD#(<J4sU{wRrU6S&>KQCHyP%)XqmElU&P zU=Pv(vbnmsa1Oaz21=@T0}X`Pq^Wq002k-7O1nI_PWwPNbQTOT*H7E}ILWvW`^k70 ceVpm2z1FIHPlA7px~)xGdeIN7H<Cd$n^0~%C;$Ke diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 b/integrations/gitea-repositories-meta/user2/template2.git/objects/c2/99269b0f493968749529f19c1dc03bc9ac7c76 deleted file mode 100644 index dafe273a1d5d977b6e8e659359c4c8e7c2a02131..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmV-b0IL6Z0V^p=O;s?nU@$Z=Ff%bx2y%6F@paY9O<^!8?)Cknu<e)r{|`=zm*zz- rI9k5l!~h5sN>YnU81%P(nf++t<(12nxf6E(oov(F$}|}OA6y>|PWvaH diff --git a/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs b/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs deleted file mode 100644 index 8b137891791fe..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/objects/info/packs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master b/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master deleted file mode 100644 index 690e09de22e6b..0000000000000 --- a/integrations/gitea-repositories-meta/user2/template2.git/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -27e8b0a83a263464323e3915db96600da0cc3259 diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index b0c963e3df33c..9c2d927e804fc 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -56,11 +56,11 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, tem func TestRepoGenerate(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user1") - testRepoGenerate(t, session, "user2", "template1", "user1", "generated1") + testRepoGenerate(t, session, "user2", "repo1", "user1", "generated1") } func TestRepoGenerateToOrg(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user2") - testRepoGenerate(t, session, "user2", "template2", "user3", "generated2") + testRepoGenerate(t, session, "user2", "repo1", "user3", "generated2") } diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 32f34b8671a23..d698ecd5301bd 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -4,6 +4,7 @@ lower_name: repo1 name: repo1 is_private: false + is_template: true num_issues: 2 num_closed_issues: 1 num_pulls: 2 diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index b899fe8d03ee1..083043cb2f810 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -428,18 +428,3 @@ num_members: 0 num_teams: 1 repo_admin_change_team_access: true - -- - id: 27 - lower_name: user27 - name: user27 - full_name: "User27" - email: user27@example.com - passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password - type: 0 # individual - salt: ZogKvWdyEx - is_admin: false - avatar: avatar27 - avatar_email: user27@example.com - num_repos: 2 - is_active: true From ca2970ef397730f9ea372512c50895e6bba3a019 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 15:10:50 -0500 Subject: [PATCH 10/30] Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 4 +- models/repo_list_test.go | 6 -- modules/context/repo.go | 4 +- routers/repo/generate.go | 145 +++++++++++++++++++++++++++++++++++++++ routers/repo/pull.go | 125 --------------------------------- 5 files changed, 149 insertions(+), 135 deletions(-) create mode 100644 routers/repo/generate.go diff --git a/models/repo.go b/models/repo.go index 40fdcea039e0c..38bef066e8f11 100644 --- a/models/repo.go +++ b/models/repo.go @@ -670,9 +670,9 @@ func (repo *Repository) IsGenerated() bool { return repo.TemplateID != 0 } -// GetTemplateRepo populates repo.TemplateRepo for a template repository and +// GetTemplateRepo populates repo.TemplateRepo for a generated repository and // returns an error on failure (NOTE: no error is returned for -// non-template repositories, and TemplateRepo will be left untouched) +// non-generated repositories, and TemplateRepo will be left untouched) func (repo *Repository) GetTemplateRepo() (err error) { return repo.getTemplateRepo(x) } diff --git a/models/repo_list_test.go b/models/repo_list_test.go index ee3ad1a72e5e8..e3a7acd4a4019 100644 --- a/models/repo_list_test.go +++ b/models/repo_list_test.go @@ -188,12 +188,6 @@ func TestSearchRepository(t *testing.T) { {name: "AllPublic/PublicRepositoriesOfOrganization", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse}, count: 22}, - {name: "Template/Private", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 26, Private: true, Template: true}, - count: 2}, - {name: "Template/Public", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 26, Template: true}, - count: 1}, } for _, testCase := range testCases { diff --git a/modules/context/repo.go b/modules/context/repo.go index 494461fac59b2..1c83c1e0cc9a6 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -189,9 +189,9 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) { } } -// RetrieveTemplateRepo retrieves used template repository +// RetrieveTemplateRepo retrieves template repository used to generate this repository func RetrieveTemplateRepo(ctx *Context, repo *models.Repository) { - // Non-template repository will not return error in this method. + // Non-generated repository will not return error in this method. if err := repo.GetTemplateRepo(); err != nil { if models.IsErrRepoNotExist(err) { repo.TemplateID = 0 diff --git a/routers/repo/generate.go b/routers/repo/generate.go new file mode 100644 index 0000000000000..21dac57562bc0 --- /dev/null +++ b/routers/repo/generate.go @@ -0,0 +1,145 @@ +// Copyright 2019 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 repo + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + repo_service "code.gitea.io/gitea/services/repository" +) + +const ( + tplGenerate base.TplName = "repo/pulls/generate" +) + +func getTemplateRepository(ctx *context.Context) *models.Repository { + templateRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid")) + if err != nil { + if models.IsErrRepoNotExist(err) { + ctx.NotFound("GetRepositoryByID", nil) + } else { + ctx.ServerError("GetRepositoryByID", err) + } + return nil + } + + perm, err := models.GetUserRepoPermission(templateRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil + } + + if templateRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { + if log.IsTrace() { + if templateRepo.IsEmpty { + log.Trace("Empty fork repository %-v", templateRepo) + } else { + log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+ + "User in forkRepo has Permissions: %-+v", + ctx.User, + models.UnitTypeCode, + ctx.Repo, + perm) + } + } + ctx.NotFound("getForkRepository", nil) + return nil + } + + ctx.Data["repo_name"] = templateRepo.Name + ctx.Data["description"] = templateRepo.Description + ctx.Data["private"] = templateRepo.IsPrivate + ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate + + if err = templateRepo.GetOwner(); err != nil { + ctx.ServerError("GetOwner", err) + return nil + } + ctx.Data["GenerateFrom"] = templateRepo.Owner.Name + "/" + templateRepo.Name + ctx.Data["GenerateFromOwnerID"] = templateRepo.Owner.ID + + if err := ctx.User.GetOwnedOrganizations(); err != nil { + ctx.ServerError("GetOwnedOrganizations", err) + return nil + } + + ctx.Data["Orgs"] = ctx.User.OwnedOrgs + + ctx.Data["ContextUser"] = ctx.User + + return templateRepo +} + +// TemplateGenerate render repository template generate page +func TemplateGenerate(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("template_generate") + + getTemplateRepository(ctx) + if ctx.Written() { + return + } + + ctx.HTML(200, tplGenerate) +} + +// TemplateGeneratePost response for generating a repository template +func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { + ctx.Data["Title"] = ctx.Tr("template_generate") + + ctxUser := checkContextUser(ctx, form.UID) + if ctx.Written() { + return + } + + templateRepo := getTemplateRepository(ctx) + if ctx.Written() { + return + } + + ctx.Data["ContextUser"] = ctxUser + + if ctx.HasError() { + ctx.HTML(200, tplGenerate) + return + } + + // Check ownership of organization. + if ctxUser.IsOrganization() { + isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) + if err != nil { + ctx.ServerError("IsOwnedBy", err) + return + } else if !isOwner { + ctx.Error(403) + return + } + } + + private := form.Private || setting.Repository.ForcePrivate + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, private) + if err != nil { + ctx.Data["Err_RepoName"] = true + switch { + case models.IsErrRepoAlreadyExist(err): + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplGenerate, &form) + case models.IsErrNameReserved(err): + ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplGenerate, &form) + case models.IsErrNamePatternNotAllowed(err): + ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplGenerate, &form) + default: + ctx.ServerError("TemplateGeneratePost", err) + } + return + } + + log.Trace("Repository generate[%d]: %s/%s", templateRepo.ID, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) +} diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 6e12f5f5eb91a..3defd04b1bd1b 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -32,7 +32,6 @@ import ( const ( tplFork base.TplName = "repo/pulls/fork" - tplGenerate base.TplName = "repo/pulls/generate" tplCompareDiff base.TplName = "repo/diff/compare" tplPullCommits base.TplName = "repo/pulls/commits" tplPullFiles base.TplName = "repo/pulls/files" @@ -143,64 +142,6 @@ func getForkRepository(ctx *context.Context) *models.Repository { return forkRepo } -func getTemplateRepository(ctx *context.Context) *models.Repository { - templateRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid")) - if err != nil { - if models.IsErrRepoNotExist(err) { - ctx.NotFound("GetRepositoryByID", nil) - } else { - ctx.ServerError("GetRepositoryByID", err) - } - return nil - } - - perm, err := models.GetUserRepoPermission(templateRepo, ctx.User) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return nil - } - - if templateRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { - if log.IsTrace() { - if templateRepo.IsEmpty { - log.Trace("Empty fork repository %-v", templateRepo) - } else { - log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+ - "User in forkRepo has Permissions: %-+v", - ctx.User, - models.UnitTypeCode, - ctx.Repo, - perm) - } - } - ctx.NotFound("getForkRepository", nil) - return nil - } - - ctx.Data["repo_name"] = templateRepo.Name - ctx.Data["description"] = templateRepo.Description - ctx.Data["private"] = templateRepo.IsPrivate - ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate - - if err = templateRepo.GetOwner(); err != nil { - ctx.ServerError("GetOwner", err) - return nil - } - ctx.Data["GenerateFrom"] = templateRepo.Owner.Name + "/" + templateRepo.Name - ctx.Data["GenerateFromOwnerID"] = templateRepo.Owner.ID - - if err := ctx.User.GetOwnedOrganizations(); err != nil { - ctx.ServerError("GetOwnedOrganizations", err) - return nil - } - - ctx.Data["Orgs"] = ctx.User.OwnedOrgs - - ctx.Data["ContextUser"] = ctx.User - - return templateRepo -} - // Fork render repository fork page func Fork(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("new_fork") @@ -288,72 +229,6 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) { ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) } -// TemplateGenerate render repository template generate page -func TemplateGenerate(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("template_generate") - - getTemplateRepository(ctx) - if ctx.Written() { - return - } - - ctx.HTML(200, tplGenerate) -} - -// TemplateGeneratePost response for generating a repository template -func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { - ctx.Data["Title"] = ctx.Tr("template_generate") - - ctxUser := checkContextUser(ctx, form.UID) - if ctx.Written() { - return - } - - templateRepo := getTemplateRepository(ctx) - if ctx.Written() { - return - } - - ctx.Data["ContextUser"] = ctxUser - - if ctx.HasError() { - ctx.HTML(200, tplGenerate) - return - } - - // Check ownership of organization. - if ctxUser.IsOrganization() { - isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) - if err != nil { - ctx.ServerError("IsOwnedBy", err) - return - } else if !isOwner { - ctx.Error(403) - return - } - } - - private := form.Private || setting.Repository.ForcePrivate - repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, private) - if err != nil { - ctx.Data["Err_RepoName"] = true - switch { - case models.IsErrRepoAlreadyExist(err): - ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplGenerate, &form) - case models.IsErrNameReserved(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplGenerate, &form) - case models.IsErrNamePatternNotAllowed(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplGenerate, &form) - default: - ctx.ServerError("TemplateGeneratePost", err) - } - return - } - - log.Trace("Repository generate[%d]: %s/%s", templateRepo.ID, ctxUser.Name, repo.Name) - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) -} - func checkPullInfo(ctx *context.Context) *models.Issue { issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { From fb455307cd0fc60a0c893149f8e413fc7ada8485 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 15:40:52 -0500 Subject: [PATCH 11/30] make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> --- routers/repo/generate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/repo/generate.go b/routers/repo/generate.go index 21dac57562bc0..78b418fa5985a 100644 --- a/routers/repo/generate.go +++ b/routers/repo/generate.go @@ -17,7 +17,7 @@ import ( ) const ( - tplGenerate base.TplName = "repo/pulls/generate" + tplGenerate base.TplName = "repo/pulls/generate" ) func getTemplateRepository(ctx *context.Context) *models.Repository { From 2a27a5848d92cb43586a427a5f8853c4adb35d8d Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 15:57:02 -0500 Subject: [PATCH 12/30] Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/fixtures/user.yml | 2 +- models/repo_list.go | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 083043cb2f810..329d1207de402 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -30,7 +30,7 @@ is_admin: false avatar: avatar2 avatar_email: user2@example.com - num_repos: 9 + num_repos: 11 num_stars: 2 num_followers: 2 num_following: 1 diff --git a/models/repo_list.go b/models/repo_list.go index 7daf07b4c01cd..93f672f3c1679 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -117,7 +117,6 @@ type SearchRepoOptions struct { OwnerID int64 OrderBy SearchOrderBy Private bool // Include private repositories in results - Template bool // Include template repositories in results StarredByID int64 Page int IsProfile bool @@ -131,6 +130,10 @@ type SearchRepoOptions struct { // True -> include just forks // False -> include just non-forks Fork util.OptionalBool + // None -> include templates AND non-templates + // True -> include just templates + // False -> include just non-templates + Template util.OptionalBool // None -> include mirrors AND non-mirrors // True -> include just mirrors // False -> include just non-mirrors @@ -191,10 +194,8 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { cond = cond.And(accessCond) } - if opts.Template { - cond = cond.And(builder.Eq{"is_template": true}) - } else { - cond = cond.And(builder.Eq{"is_template": false}) + if opts.Template != util.OptionalBoolNone { + cond = cond.And(builder.Eq{"is_template": opts.Fork == util.OptionalBoolTrue}) } // Restrict to starred repositories From b135b00439561dd5bf25fe346c80708bfa1baabc Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 16:09:42 -0500 Subject: [PATCH 13/30] Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> --- routers/api/v1/repo/repo.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 1ba3f2816ea58..49c11f03d966e 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -123,13 +123,17 @@ func Search(ctx *context.APIContext) { TopicOnly: ctx.QueryBool("topic"), Collaborate: util.OptionalBoolNone, Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), - Template: ctx.Query("template") == "" || ctx.QueryBool("template"), + Template: util.OptionalBoolNone, UserIsAdmin: ctx.IsUserSiteAdmin(), UserID: ctx.Data["SignedUserID"].(int64), StarredByID: ctx.QueryInt64("starredBy"), IncludeDescription: ctx.QueryBool("includeDesc"), } + if ctx.Query("template") != "" { + opts.Template = util.OptionalBoolOf(ctx.QueryBool("template")) + } + if ctx.QueryBool("exclusive") { opts.Collaborate = util.OptionalBoolFalse } From a2c7aff67568a3d0d515e0a44fb2ffb6730085e9 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 16:18:22 -0500 Subject: [PATCH 14/30] make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo_list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/repo_list.go b/models/repo_list.go index 93f672f3c1679..49e4640da93a4 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -133,7 +133,7 @@ type SearchRepoOptions struct { // None -> include templates AND non-templates // True -> include just templates // False -> include just non-templates - Template util.OptionalBool + Template util.OptionalBool // None -> include mirrors AND non-mirrors // True -> include just mirrors // False -> include just non-mirrors From a9d5fd27d3d85157fc7aae85c9356b15769d0a63 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 16:51:16 -0500 Subject: [PATCH 15/30] Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/api_repo_test.go | 6 +++--- models/fixtures/repository.yml | 4 ++-- models/fixtures/user.yml | 4 ++-- models/repo_list_test.go | 9 ++++++--- templates/repo/header.tmpl | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 60fe4a3649576..88a11ef243632 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -70,9 +70,9 @@ func TestAPISearchRepo(t *testing.T) { expectedResults }{ {name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{ - nil: {count: 22}, - user: {count: 22}, - user2: {count: 22}}, + nil: {count: 24}, + user: {count: 24}, + user2: {count: 24}}, }, {name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10&private=false", expectedResults: expectedResults{ nil: {count: 10}, diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index d698ecd5301bd..d1b59d28fbe51 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -565,7 +565,7 @@ - id: 44 - owner_id: 2 + owner_id: 6 lower_name: template1 name: template1 is_private: false @@ -578,7 +578,7 @@ - id: 45 - owner_id: 2 + owner_id: 6 lower_name: template2 name: template2 is_private: false diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 329d1207de402..aaa702576734b 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -30,7 +30,7 @@ is_admin: false avatar: avatar2 avatar_email: user2@example.com - num_repos: 11 + num_repos: 9 num_stars: 2 num_followers: 2 num_following: 1 @@ -101,7 +101,7 @@ is_admin: false avatar: avatar6 avatar_email: user6@example.com - num_repos: 0 + num_repos: 2 num_members: 1 num_teams: 1 diff --git a/models/repo_list_test.go b/models/repo_list_test.go index e3a7acd4a4019..50d3b7ba1799d 100644 --- a/models/repo_list_test.go +++ b/models/repo_list_test.go @@ -174,10 +174,13 @@ func TestSearchRepository(t *testing.T) { opts: &SearchRepoOptions{Keyword: "big_test_", Page: 1, PageSize: 10, Private: true, AllPublic: true, Collaborate: util.OptionalBoolFalse}, count: 14}, {name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true}, + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse}, count: 22}, + {name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborativeAndTemplates", + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolTrue}, + count: 24}, {name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true}, + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true, Template: util.OptionalBoolFalse}, count: 28}, {name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName", opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true}, @@ -186,7 +189,7 @@ func TestSearchRepository(t *testing.T) { opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 18, Private: true, AllPublic: true}, count: 13}, {name: "AllPublic/PublicRepositoriesOfOrganization", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse}, + opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse}, count: 22}, } diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index dc4543b61e49b..b1b31183c4e81 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -12,6 +12,7 @@ <div class="divider"> / </div> <a href="{{$.RepoLink}}">{{.Name}}</a> {{if and .RelAvatarLink .IsPrivate}}<i class="mega-octicon octicon-lock"></i>{{end}} + {{if .IsTemplate}}<i class="icon fa-copy"></i>{{end}} {{if .IsArchived}}<i class="archive icon archived-icon"></i>{{end}} {{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{MirrorAddress $.Mirror}}">{{MirrorAddress $.Mirror}}</a></div>{{end}} {{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{SubStr .BaseRepo.RelLink 1 -1}}</a></div>{{end}} From ea3885f4f3414b925a690c870e9008fade8d60b8 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 17:06:41 -0500 Subject: [PATCH 16/30] Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> --- .../user27/template1.git/HEAD | 1 + .../user27/template1.git/config | 6 + .../user27/template1.git/description | 1 + .../template1.git/hooks/applypatch-msg.sample | 15 ++ .../template1.git/hooks/commit-msg.sample | 24 +++ .../hooks/fsmonitor-watchman.sample | 114 ++++++++++++ .../user27/template1.git/hooks/post-receive | 15 ++ .../template1.git/hooks/post-receive.d/gitea | 2 + .../template1.git/hooks/post-update.sample | 8 + .../template1.git/hooks/pre-applypatch.sample | 14 ++ .../template1.git/hooks/pre-commit.sample | 49 +++++ .../template1.git/hooks/pre-push.sample | 53 ++++++ .../template1.git/hooks/pre-rebase.sample | 169 ++++++++++++++++++ .../user27/template1.git/hooks/pre-receive | 15 ++ .../template1.git/hooks/pre-receive.d/gitea | 2 + .../template1.git/hooks/pre-receive.sample | 24 +++ .../hooks/prepare-commit-msg.sample | 42 +++++ .../user27/template1.git/hooks/update | 14 ++ .../user27/template1.git/hooks/update.d/gitea | 2 + .../user27/template1.git/hooks/update.sample | 128 +++++++++++++ .../user27/template1.git/info/exclude | 6 + .../user27/template1.git/info/refs | 1 + .../47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 | Bin 0 -> 84 bytes .../4d/31f3a12656368a8d9180f431d40d0fc408be2d | Bin 0 -> 29 bytes .../51/f84af231345367fd5d61ceb89efb3b6d757061 | Bin 0 -> 121 bytes .../79/3aa682b06ae032641abf70c5dfeade28c07c52 | Bin 0 -> 28 bytes .../aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 | Bin 0 -> 154 bytes .../dd/392e939ea4936b2459219c9c9a1f25547ccaeb | Bin 0 -> 53 bytes .../f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f | Bin 0 -> 54 bytes .../user27/template1.git/objects/info/packs | 1 + .../user27/template1.git/refs/heads/master | 1 + integrations/repo_generate_test.go | 4 +- models/fixtures/repository.yml | 5 +- models/fixtures/user.yml | 17 +- 34 files changed, 727 insertions(+), 6 deletions(-) create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/HEAD create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/config create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/description create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/applypatch-msg.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/fsmonitor-watchman.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/post-update.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-applypatch.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-commit.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-push.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-rebase.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/prepare-commit-msg.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/update create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/hooks/update.sample create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/info/exclude create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/info/refs create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs create mode 100644 integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user27/template1.git/HEAD b/integrations/gitea-repositories-meta/user27/template1.git/HEAD new file mode 100644 index 0000000000000..cb089cd89a7d7 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/integrations/gitea-repositories-meta/user27/template1.git/config b/integrations/gitea-repositories-meta/user27/template1.git/config new file mode 100644 index 0000000000000..64280b806c976 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = true + symlinks = false + ignorecase = true diff --git a/integrations/gitea-repositories-meta/user27/template1.git/description b/integrations/gitea-repositories-meta/user27/template1.git/description new file mode 100644 index 0000000000000..498b267a8c781 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/applypatch-msg.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/applypatch-msg.sample new file mode 100644 index 0000000000000..a5d7b84a67345 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/commit-msg.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/commit-msg.sample new file mode 100644 index 0000000000000..b58d1184a9d43 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/fsmonitor-watchman.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/fsmonitor-watchman.sample new file mode 100644 index 0000000000000..e673bb3980f3c --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/fsmonitor-watchman.sample @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 1) and a time in nanoseconds +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $time) = @ARGV; + +# Check the hook interface version + +if ($version == 1) { + # convert nanoseconds to seconds + $time = int $time / 1000000000; +} else { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree; +if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $git_work_tree = Win32::GetCwd(); + $git_work_tree =~ tr/\\/\//; +} else { + require Cwd; + $git_work_tree = Cwd::cwd(); +} + +my $retry = 1; + +launch_watchman(); + +sub launch_watchman { + + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $time but were not transient (ie created after + # $time but no longer exist). + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + # + # The category of transient files that we want to ignore will have a + # creation clock (cclock) newer than $time_t value and will also not + # currently exist. + + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $time, + "fields": ["name"], + "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] + }] + END + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; <CHLD_OUT>}; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + my $json_pkg; + eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; + } or do { + require JSON::PP; + $json_pkg = "JSON::PP"; + }; + + my $o = $json_pkg->new->utf8->decode($response); + + if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { + print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; + $retry--; + qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + print "/\0"; + eval { launch_watchman() }; + exit 0; + } + + die "Watchman: $o->{error}.\n" . + "Falling back to scanning...\n" if $o->{error}; + + binmode STDOUT, ":utf8"; + local $, = "\0"; + print @{$o->{files}}; +} diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea new file mode 100644 index 0000000000000..82c9c1c9990e4 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-update.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-update.sample new file mode 100644 index 0000000000000..ec17ec1939b7c --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-applypatch.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-applypatch.sample new file mode 100644 index 0000000000000..4142082bcb939 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-commit.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-commit.sample new file mode 100644 index 0000000000000..6a756416384c2 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-push.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-push.sample new file mode 100644 index 0000000000000..6187dbf4390fc --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# <local ref> <local sha1> <remote ref> <remote sha1> +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo >&2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-rebase.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-rebase.sample new file mode 100644 index 0000000000000..6cbef5c370d8c --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive new file mode 100644 index 0000000000000..1733c16a3757c --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea new file mode 100644 index 0000000000000..1ee0ad752188b --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.sample new file mode 100644 index 0000000000000..a1fd29ec14823 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/prepare-commit-msg.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/prepare-commit-msg.sample new file mode 100644 index 0000000000000..10fa14c5ab013 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update new file mode 100644 index 0000000000000..2918ffb7eb683 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" || continue +"${hook}" $1 $2 $3 +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea new file mode 100644 index 0000000000000..ba0376924b868 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.sample b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.sample new file mode 100644 index 0000000000000..80ba94135cc37 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 <ref> <oldrev> <newrev>)" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 <ref> <oldrev> <newrev>" >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/info/exclude b/integrations/gitea-repositories-meta/user27/template1.git/info/exclude new file mode 100644 index 0000000000000..a5196d1be8fb5 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/integrations/gitea-repositories-meta/user27/template1.git/info/refs b/integrations/gitea-repositories-meta/user27/template1.git/info/refs new file mode 100644 index 0000000000000..22f08279c0d70 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/info/refs @@ -0,0 +1 @@ +aacbdfe9e1c4b47f60abe81849045fa4e96f1d75 refs/heads/master diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 b/integrations/gitea-repositories-meta/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 new file mode 100644 index 0000000000000000000000000000000000000000..b6f121a4bb5d3bef8b829a9b56eb50fd3dcf8fce GIT binary patch literal 84 zcmV-a0IUCa0V^p=O;s?nU@$Z=Ff%bx2y%6F@paY9O=0jg{Jc;t%&e<-V#621E4=(i qIQHq97yyAnNosKk!(B_g$@7*>&Q^(3oHJ*ZylP0zsn-Cegc}#|fhG+A literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d b/integrations/gitea-repositories-meta/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d new file mode 100644 index 0000000000000000000000000000000000000000..d2f4c1d04ed06ac5c7caf9aca1f44840f06a5f81 GIT binary patch literal 29 kcmb<m^geacKghr&Eg($8^Q`U(PaRLwCy$sIT(#IZ0HNIp)Bpeg literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 b/integrations/gitea-repositories-meta/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 new file mode 100644 index 0000000000000000000000000000000000000000..aa34a8a767133313f4f9383bb5e1ebe52705de98 GIT binary patch literal 121 zcmV-<0EYi~0hP@?4#F@DKw;*b!WRJ9&R++FSUE;WZHPo$DRJ+QfD^F1?bEB<vNQuq z{$O1MlqZo|{H!@q&^ah!CG@D|RqlZ%QD2j~vfFd(un*}BXOm%k{j{x*lZ^{d%p5~T b&Tzzt=<4@m@{e)1wOK1K_+j@3R{S*{g26ky literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 b/integrations/gitea-repositories-meta/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 new file mode 100644 index 0000000000000000000000000000000000000000..3f9705fef4c1bed8a3b0a491a7ffda6ded0e49b9 GIT binary patch literal 28 kcmb<m^geacKghr&k>lhEoiK()F0GTUJQ8B?D`S@e0H0(Eg8%>k literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 b/integrations/gitea-repositories-meta/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 new file mode 100644 index 0000000000000000000000000000000000000000..74419f4b47cf77881c7d2b8f6716c5162c0c1584 GIT binary patch literal 154 zcmV;L0A>Gp0hNwB4#F@H1*v@scc}<ouh$L|LU5Gz4^kvS&PL++D7gX6RBuKvEz>lL zw%||FO3^N$i%<v0=tE_Q10)1yXVEc5&H#xkqxx_wvuHZD)gqvyUCER^q!Nc~sS%^k zfr9a%c$4?i^tP5}^-anu_OWxEU%jk%4HPU9QV9BN$QYH5XHx!g)H7$@?b*wYUcS<) IAM5Z#aLAZScK`qY literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb b/integrations/gitea-repositories-meta/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb new file mode 100644 index 0000000000000000000000000000000000000000..844eb1c2a63a9f5c0ca5ff049aedc9ccd60438be GIT binary patch literal 53 zcmV-50LuS(0V^p=O;s>9V=y!@Ff%bxC`m0Y(JQGaVW_lP*0dq(fl-Ro{(__TU)|F< LP!j|IN#_x*?Qaz* literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f b/integrations/gitea-repositories-meta/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f new file mode 100644 index 0000000000000000000000000000000000000000..0699bff833bc1e0a42bfdff36ad7fef2f93505c6 GIT binary patch literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2y%6F@paY9O=0jg{Jc;t%&e<-V#621E4=(i MIQHoR04~iA?=E#0MF0Q* literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs b/integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs @@ -0,0 +1 @@ + diff --git a/integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master b/integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master new file mode 100644 index 0000000000000..0f13243bfd640 --- /dev/null +++ b/integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master @@ -0,0 +1 @@ +aacbdfe9e1c4b47f60abe81849045fa4e96f1d75 diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index 9c2d927e804fc..d898ae24fe3d2 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -56,11 +56,11 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, tem func TestRepoGenerate(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user1") - testRepoGenerate(t, session, "user2", "repo1", "user1", "generated1") + testRepoGenerate(t, session, "user27", "template1", "user27", "generated1") } func TestRepoGenerateToOrg(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user2") - testRepoGenerate(t, session, "user2", "repo1", "user3", "generated2") + testRepoGenerate(t, session, "user27", "template1", "user27", "generated2") } diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index d1b59d28fbe51..70b0b97021b79 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -4,7 +4,6 @@ lower_name: repo1 name: repo1 is_private: false - is_template: true num_issues: 2 num_closed_issues: 1 num_pulls: 2 @@ -565,7 +564,7 @@ - id: 44 - owner_id: 6 + owner_id: 27 lower_name: template1 name: template1 is_private: false @@ -578,7 +577,7 @@ - id: 45 - owner_id: 6 + owner_id: 27 lower_name: template2 name: template2 is_private: false diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index aaa702576734b..2f841e6d34c4d 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -101,7 +101,7 @@ is_admin: false avatar: avatar6 avatar_email: user6@example.com - num_repos: 2 + num_repos: 0 num_members: 1 num_teams: 1 @@ -428,3 +428,18 @@ num_members: 0 num_teams: 1 repo_admin_change_team_access: true + +- + id: 7 + lower_name: user27 + name: user27 + full_name: User Twenty-Seven + email: user27@example.com + email_notifications_preference: enabled + passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password + type: 0 # individual + salt: ZogKvWdyEx + is_admin: false + avatar: avatar27 + avatar_email: user27@example.com + num_repos: 2 From 2c5a0872eb15fc11b798826040145ed6406f8f2f Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 31 Oct 2019 21:52:47 -0500 Subject: [PATCH 17/30] Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/repo_generate_test.go | 4 ++-- models/fixtures/user.yml | 2 +- models/repo_list.go | 2 +- models/repo_list_test.go | 6 +++--- models/user_test.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index d898ae24fe3d2..4c0d98c6def58 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -56,11 +56,11 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, tem func TestRepoGenerate(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user1") - testRepoGenerate(t, session, "user27", "template1", "user27", "generated1") + testRepoGenerate(t, session, "user27", "template1", "user1", "generated1") } func TestRepoGenerateToOrg(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user2") - testRepoGenerate(t, session, "user27", "template1", "user27", "generated2") + testRepoGenerate(t, session, "user27", "template1", "user2", "generated2") } diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 2f841e6d34c4d..5a3b04994cc99 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -430,7 +430,7 @@ repo_admin_change_team_access: true - - id: 7 + id: 27 lower_name: user27 name: user27 full_name: User Twenty-Seven diff --git a/models/repo_list.go b/models/repo_list.go index 49e4640da93a4..1ce7378fec413 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -195,7 +195,7 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { } if opts.Template != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_template": opts.Fork == util.OptionalBoolTrue}) + cond = cond.And(builder.Eq{"is_template": opts.Template == util.OptionalBoolTrue}) } // Restrict to starred repositories diff --git a/models/repo_list_test.go b/models/repo_list_test.go index 50d3b7ba1799d..b1dbf46af0cf0 100644 --- a/models/repo_list_test.go +++ b/models/repo_list_test.go @@ -176,9 +176,6 @@ func TestSearchRepository(t *testing.T) { {name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse}, count: 22}, - {name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborativeAndTemplates", - opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolTrue}, - count: 24}, {name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true, Template: util.OptionalBoolFalse}, count: 28}, @@ -191,6 +188,9 @@ func TestSearchRepository(t *testing.T) { {name: "AllPublic/PublicRepositoriesOfOrganization", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse}, count: 22}, + {name: "AllTemplates", + opts: &SearchRepoOptions{Page: 1, PageSize: 10, Template: util.OptionalBoolTrue}, + count: 2}, } for _, testCase := range testCases { diff --git a/models/user_test.go b/models/user_test.go index bcb955817c330..5dd1e70a72a71 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -153,7 +153,7 @@ func TestSearchUsers(t *testing.T) { } testUserSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1}, - []int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24}) + []int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27}) testUserSuccess(&SearchUserOptions{Page: 1, IsActive: util.OptionalBoolFalse}, []int64{9}) From 40d115e4b0dfc0a626d1d9785f96bdfcc0c80a4d Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Sat, 2 Nov 2019 13:24:11 -0500 Subject: [PATCH 18/30] Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> --- .../user27/template1.git/hooks/post-receive.d/gitea | 2 +- .../user27/template1.git/hooks/pre-receive.d/gitea | 2 +- .../user27/template1.git/hooks/update.d/gitea | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea index 82c9c1c9990e4..43a948da3a983 100644 --- a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea @@ -1,2 +1,2 @@ #!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" post-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea index 1ee0ad752188b..49d09406364a5 100644 --- a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea @@ -1,2 +1,2 @@ #!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" pre-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea index ba0376924b868..38101c242664a 100644 --- a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea +++ b/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea @@ -1,2 +1,2 @@ #!/usr/bin/env bash -"C:/Users/jolheiser/go/src/code.gitea.io/gitea/gitea.exe" hook --config='C:/Users/jolheiser/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3 +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" update $1 $2 $3 From a0dbee4f7dc9cd9378dfd2fb49226857c28b7a75 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Sun, 3 Nov 2019 21:14:41 -0600 Subject: [PATCH 19/30] Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 53 +++++++---- models/repo_list.go | 27 +++--- modules/auth/repo_form.go | 3 + modules/structs/repo.go | 1 + options/locale/locale_en-US.ini | 4 + public/js/index.js | 51 +++++++++- routers/api/v1/repo/repo.go | 4 + routers/repo/generate.go | 145 ----------------------------- routers/repo/repo.go | 55 ++++++++--- routers/routes/routes.go | 4 - services/repository/repository.go | 4 +- templates/repo/create.tmpl | 112 +++++++++++++--------- templates/repo/home.tmpl | 2 +- templates/repo/pulls/generate.tmpl | 74 --------------- templates/swagger/v1_json.tmpl | 9 ++ 15 files changed, 233 insertions(+), 315 deletions(-) delete mode 100644 routers/repo/generate.go delete mode 100644 templates/repo/pulls/generate.tmpl diff --git a/models/repo.go b/models/repo.go index 207f892bd9852..c14facc96c740 100644 --- a/models/repo.go +++ b/models/repo.go @@ -353,6 +353,7 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool) FullName: repo.FullName(), Description: repo.Description, Private: repo.IsPrivate, + Template: repo.IsTemplate, Empty: repo.IsEmpty, Archived: repo.IsArchived, Size: int(repo.Size / 1024), @@ -1243,6 +1244,18 @@ type CreateRepoOptions struct { Status RepositoryStatus } +// GenerateRepoOptions contains the template units to generate +type GenerateRepoOptions struct { + Name string + Description string + Private bool + GitContent bool +} + +func (gro GenerateRepoOptions) IsValid() bool { + return gro.GitContent // or other items as they are added +} + func getRepoInitFile(tp, name string) ([]byte, error) { cleanedName := strings.TrimLeft(path.Clean("/"+name), "/") relPath := path.Join("options", tp, cleanedName) @@ -2729,14 +2742,14 @@ func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) ( } // GenerateRepository generates a repository from a template -func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc string, private bool) (_ *Repository, err error) { +func GenerateRepository(doer, owner *User, templateRepo *Repository, opts GenerateRepoOptions) (_ *Repository, err error) { repo := &Repository{ OwnerID: owner.ID, Owner: owner, - Name: name, - LowerName: strings.ToLower(name), - Description: desc, - IsPrivate: private, + Name: opts.Name, + LowerName: strings.ToLower(opts.Name), + Description: opts.Description, + IsPrivate: opts.Private, IsEmpty: templateRepo.IsEmpty, TemplateID: templateRepo.ID, } @@ -2751,22 +2764,28 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, name, desc return nil, err } - repoPath := RepoPath(owner.Name, repo.Name) - if err := generateRepository(sess, repoPath, repo, templateRepo); err != nil { - return nil, err - } + if opts.GitContent { + repoPath := RepoPath(owner.Name, repo.Name) + if err := generateRepository(sess, repoPath, repo, templateRepo); err != nil { + return nil, err + } - //Commit repo to get generated repo ID - err = sess.Commit() - if err != nil { - return nil, err - } + //Commit repo to get generated repo ID + err = sess.Commit() + if err != nil { + return nil, err + } - if err = repo.UpdateSize(); err != nil { - log.Error("Failed to update size for repository: %v", err) + if err = repo.UpdateSize(); err != nil { + log.Error("Failed to update size for repository: %v", err) + } + + if err = copyLFS(repo, templateRepo); err != nil { + log.Error("Failed to copy LFS: %v", err) + } } - return repo, copyLFS(repo, templateRepo) + return repo, err } // GetForks returns all the forks of the repository diff --git a/models/repo_list.go b/models/repo_list.go index 1ce7378fec413..19b9d8ae3515f 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -111,17 +111,18 @@ func (repos MirrorRepositoryList) LoadAttributes() error { // SearchRepoOptions holds the search options type SearchRepoOptions struct { - UserID int64 - UserIsAdmin bool - Keyword string - OwnerID int64 - OrderBy SearchOrderBy - Private bool // Include private repositories in results - StarredByID int64 - Page int - IsProfile bool - AllPublic bool // Include also all public repositories - PageSize int // Can be smaller than or equal to setting.ExplorePagingNum + UserID int64 + UserIsAdmin bool + Keyword string + OwnerID int64 + PriorityOwnerID int64 + OrderBy SearchOrderBy + Private bool // Include private repositories in results + StarredByID int64 + Page int + IsProfile bool + AllPublic bool // Include also all public repositories + PageSize int // Can be smaller than or equal to setting.ExplorePagingNum // None -> include collaborative AND non-collaborative // True -> include just collaborative // False -> incude just non-collaborative @@ -274,6 +275,10 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { opts.OrderBy = SearchOrderByAlphabetically } + if opts.PriorityOwnerID > 0 { + opts.OrderBy = SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = %d THEN 0 ELSE owner_id END, %s", opts.PriorityOwnerID, opts.OrderBy)) + } + sess := x.NewSession() defer sess.Close() diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 7f7666d1f5d3c..cbf75bb467da6 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -36,6 +36,9 @@ type CreateRepoForm struct { IssueLabels string License string Readme string + + RepoTemplate int64 + GitContent bool } // Validate validates the fields diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 47f3fd43c3ec5..ebfb0a05869b2 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -54,6 +54,7 @@ type Repository struct { Empty bool `json:"empty"` Private bool `json:"private"` Fork bool `json:"fork"` + Template bool `json:"template"` Parent *Repository `json:"parent"` Mirror bool `json:"mirror"` Size int `json:"size"` diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1da86db3ec69d..4a64e73183960 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -579,6 +579,7 @@ owner = Owner repo_name = Repository Name repo_name_helper = Good repository names use short, memorable and unique keywords. template = Template +template_select = Select a template. template_helper = Make repository a template template_description = A repository template can be used to generate a repository with the same files as the template. visibility = Visibility @@ -620,6 +621,9 @@ forks = Forks pick_reaction = Pick your reaction reactions_more = and %d more +template.generate_items = Generation Items +template.git_content = Git Content + archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. archive.issue.nocomment = This repo is archived. You cannot comment on issues. archive.pull.nocomment = This repo is archived. You cannot comment on pull requests. diff --git a/public/js/index.js b/public/js/index.js index 53650890f0c97..a18de25e882c4 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -2135,6 +2135,52 @@ function initWipTitle() { }); } +function initTemplateSearch() { + let $repoTemplate = $("#repo_template"); + let checkTemplate = function() { + let $templateUnits = $("#template_units"); + let $nonTemplate = $("#non_template"); + if ($repoTemplate.val() !== "") { + $templateUnits.show(); + $nonTemplate.hide(); + } else { + $templateUnits.hide(); + $nonTemplate.show(); + } + }; + $repoTemplate.change(checkTemplate); + checkTemplate(); + + let changeOwner = function() { + $("#repo_template_search") + .dropdown({ + apiSettings: { + url: suburl + '/api/v1/repos/search?q={query}&template=true&priority_owner_id=' + $("#uid").val(), + onResponse: function(response) { + const filteredResponse = {'success': true, 'results': []}; + filteredResponse.results.push({ + 'name': '', + 'value': '' + }); + // Parse the response from the api to work with our dropdown + $.each(response.data, function(_r, repo) { + filteredResponse.results.push({ + 'name' : htmlEncode(repo.name) , + 'value' : repo.id + }); + }); + return filteredResponse; + }, + cache: false, + }, + + fullTextSearch: true + }); + }; + $("#uid").change(changeOwner); + changeOwner(); +} + $(document).ready(function () { csrf = $('meta[name=_csrf]').attr("content"); suburl = $('meta[name=_suburl]').attr("content"); @@ -2376,6 +2422,7 @@ $(document).ready(function () { initWipTitle(); initPullRequestReview(); initRepoStatusChecker(); + initTemplateSearch(); // Repo clone url. if ($('#repo-clone-url').length > 0) { @@ -3264,7 +3311,7 @@ function initIssueList() { $('#new-dependency-drop-list') .dropdown({ apiSettings: { - url: issueSearchUrl, + url: issueSearchUrl, onResponse: function(response) { const filteredResponse = {'success': true, 'results': []}; const currIssueId = $('#new-dependency-drop-list').data('issue-id'); @@ -3275,7 +3322,7 @@ function initIssueList() { return; } filteredResponse.results.push({ - 'name' : '#' + issue.number + ' ' + htmlEncode(issue.title) + + 'name' : '#' + issue.number + ' ' + htmlEncode(issue.title) + '<div class="text small dont-break-out">' + htmlEncode(issue.repository.full_name) + '</div>', 'value' : issue.id }); diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 49c11f03d966e..6d558998283a0 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -69,6 +69,9 @@ func Search(ctx *context.APIContext) { // description: search only for repos that the user with the given id owns or contributes to // type: integer // format: int64 + // - name: priority_owner_id + // description: repo owner to prioritize in the results + // format: int64 // - name: starredBy // in: query // description: search only for repos that the user with the given id has starred @@ -118,6 +121,7 @@ func Search(ctx *context.APIContext) { opts := &models.SearchRepoOptions{ Keyword: strings.Trim(ctx.Query("q"), " "), OwnerID: ctx.QueryInt64("uid"), + PriorityOwnerID: ctx.QueryInt64("priority_owner_id"), Page: ctx.QueryInt("page"), PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")), TopicOnly: ctx.QueryBool("topic"), diff --git a/routers/repo/generate.go b/routers/repo/generate.go deleted file mode 100644 index 78b418fa5985a..0000000000000 --- a/routers/repo/generate.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2019 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 repo - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/auth" - "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - - repo_service "code.gitea.io/gitea/services/repository" -) - -const ( - tplGenerate base.TplName = "repo/pulls/generate" -) - -func getTemplateRepository(ctx *context.Context) *models.Repository { - templateRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid")) - if err != nil { - if models.IsErrRepoNotExist(err) { - ctx.NotFound("GetRepositoryByID", nil) - } else { - ctx.ServerError("GetRepositoryByID", err) - } - return nil - } - - perm, err := models.GetUserRepoPermission(templateRepo, ctx.User) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return nil - } - - if templateRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { - if log.IsTrace() { - if templateRepo.IsEmpty { - log.Trace("Empty fork repository %-v", templateRepo) - } else { - log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+ - "User in forkRepo has Permissions: %-+v", - ctx.User, - models.UnitTypeCode, - ctx.Repo, - perm) - } - } - ctx.NotFound("getForkRepository", nil) - return nil - } - - ctx.Data["repo_name"] = templateRepo.Name - ctx.Data["description"] = templateRepo.Description - ctx.Data["private"] = templateRepo.IsPrivate - ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate - - if err = templateRepo.GetOwner(); err != nil { - ctx.ServerError("GetOwner", err) - return nil - } - ctx.Data["GenerateFrom"] = templateRepo.Owner.Name + "/" + templateRepo.Name - ctx.Data["GenerateFromOwnerID"] = templateRepo.Owner.ID - - if err := ctx.User.GetOwnedOrganizations(); err != nil { - ctx.ServerError("GetOwnedOrganizations", err) - return nil - } - - ctx.Data["Orgs"] = ctx.User.OwnedOrgs - - ctx.Data["ContextUser"] = ctx.User - - return templateRepo -} - -// TemplateGenerate render repository template generate page -func TemplateGenerate(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("template_generate") - - getTemplateRepository(ctx) - if ctx.Written() { - return - } - - ctx.HTML(200, tplGenerate) -} - -// TemplateGeneratePost response for generating a repository template -func TemplateGeneratePost(ctx *context.Context, form auth.CreateRepoForm) { - ctx.Data["Title"] = ctx.Tr("template_generate") - - ctxUser := checkContextUser(ctx, form.UID) - if ctx.Written() { - return - } - - templateRepo := getTemplateRepository(ctx) - if ctx.Written() { - return - } - - ctx.Data["ContextUser"] = ctxUser - - if ctx.HasError() { - ctx.HTML(200, tplGenerate) - return - } - - // Check ownership of organization. - if ctxUser.IsOrganization() { - isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) - if err != nil { - ctx.ServerError("IsOwnedBy", err) - return - } else if !isOwner { - ctx.Error(403) - return - } - } - - private := form.Private || setting.Repository.ForcePrivate - repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, form.RepoName, form.Description, private) - if err != nil { - ctx.Data["Err_RepoName"] = true - switch { - case models.IsErrRepoAlreadyExist(err): - ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplGenerate, &form) - case models.IsErrNameReserved(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tplGenerate, &form) - case models.IsErrNamePatternNotAllowed(err): - ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplGenerate, &form) - default: - ctx.ServerError("TemplateGeneratePost", err) - } - return - } - - log.Trace("Repository generate[%d]: %s/%s", templateRepo.ID, ctxUser.Name, repo.Name) - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) -} diff --git a/routers/repo/repo.go b/routers/repo/repo.go index cf1845a727bb4..a8c28d3060644 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -123,6 +123,8 @@ func Create(ctx *context.Context) { ctx.Data["private"] = getRepoPrivate(ctx) ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate + ctx.Data["repo_template"] = ctx.Query("template_id") + ctxUser := checkContextUser(ctx, ctx.QueryInt64("org")) if ctx.Written() { return @@ -170,20 +172,45 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { return } - repo, err := repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{ - Name: form.RepoName, - Description: form.Description, - Gitignores: form.Gitignores, - IssueLabels: form.IssueLabels, - License: form.License, - Readme: form.Readme, - IsPrivate: form.Private || setting.Repository.ForcePrivate, - AutoInit: form.AutoInit, - }) - if err == nil { - log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) - return + var err error + if form.RepoTemplate > 0 { + opts := models.GenerateRepoOptions{ + Name: form.RepoName, + Description: form.Description, + Private: form.Private, + GitContent: form.GitContent, + } + + if !opts.IsValid() { + ctx.RenderWithErr("Must select at least one generation unit", tplCreate, form) + return + } + + templateRepo, err := models.GetRepositoryByID(form.RepoTemplate) + if err == nil { + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts) + if err == nil { + log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) + return + } + } + } else { + repo, err := repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{ + Name: form.RepoName, + Description: form.Description, + Gitignores: form.Gitignores, + IssueLabels: form.IssueLabels, + License: form.License, + Readme: form.Readme, + IsPrivate: form.Private || setting.Repository.ForcePrivate, + AutoInit: form.AutoInit, + }) + if err == nil { + log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) + return + } } handleCreateError(ctx, ctxUser, err, "CreatePost", tplCreate, &form) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 160c6a573bc1c..13a5bb27084d0 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -616,10 +616,6 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo("/:repoid").Get(repo.Fork). Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) - m.Group("/generate", func() { - m.Combo("/:repoid").Get(repo.TemplateGenerate). - Post(bindIgnErr(auth.CreateRepoForm{}), repo.TemplateGeneratePost) - }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) }, reqSignIn) // ***** Release Attachment Download without Signin diff --git a/services/repository/repository.go b/services/repository/repository.go index 7bbe0f92b16dc..b1156b41d5df4 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -45,8 +45,8 @@ func ForkRepository(doer, u *models.User, oldRepo *models.Repository, name, desc } // GenerateRepository generates a repository from a template -func GenerateRepository(doer, u *models.User, oldRepo *models.Repository, name, desc string, private bool) (*models.Repository, error) { - repo, err := models.GenerateRepository(doer, u, oldRepo, name, desc, private) +func GenerateRepository(doer, u *models.User, oldRepo *models.Repository, opts models.GenerateRepoOptions) (*models.Repository, error) { + repo, err := models.GenerateRepository(doer, u, oldRepo, opts) if err != nil { if repo != nil { if errDelete := models.DeleteRepository(doer, u.ID, repo.ID); errDelete != nil { diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index 1a53e3c893501..d1fd2e52ac213 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -55,68 +55,90 @@ <label for="description">{{.i18n.Tr "repo.repo_desc"}}</label> <textarea id="description" name="description">{{.description}}</textarea> </div> - <div class="inline field"> - <label>{{.i18n.Tr "repo.issue_labels"}}</label> - <div class="ui search normal selection dropdown"> - <input type="hidden" name="issue_labels" value="{{.issueLabels}}"> - <div class="default text">{{.i18n.Tr "repo.issue_labels_helper"}}</div> + <label>{{.i18n.Tr "repo.template"}}</label> + <div id="repo_template_search" class="ui search normal selection dropdown"> + <input type="hidden" id="repo_template" name="repo_template" value="{{.repo_template}}"> + <div class="default text">{{.i18n.Tr "repo.template_select"}}</div> <div class="menu"> - <div class="item" data-value="">{{.i18n.Tr "repo.issue_labels_helper"}}</div> - {{range .LabelTemplates}} - <div class="item" data-value="{{.}}">{{.}}</div> - {{end}} </div> </div> </div> - <div class="ui divider"></div> - - <div class="inline field"> - <label>.gitignore</label> - <div class="ui multiple search normal selection dropdown"> - <input type="hidden" name="gitignores" value="{{.gitignores}}"> - <div class="default text">{{.i18n.Tr "repo.repo_gitignore_helper"}}</div> - <div class="menu"> - {{range .Gitignores}} - <div class="item" data-value="{{.}}">{{.}}</div> - {{end}} + <div id="template_units" style="display: none;"> + <div class="inline field"> + <label>{{.i18n.Tr "repo.template.generate_items"}}</label> + <div class="ui checkbox"> + <input class="hidden" name="git_content" type="checkbox" tabindex="0" {{if .git_content}}checked{{end}}> + <label>{{.i18n.Tr "repo.template.git_content"}}</label> </div> </div> </div> - <div class="inline field"> - <label>{{.i18n.Tr "repo.license"}}</label> - <div class="ui search selection dropdown"> - <input type="hidden" name="license" value="{{.license}}"> - <div class="default text">{{.i18n.Tr "repo.license_helper"}}</div> - <div class="menu"> - <div class="item" data-value="">{{.i18n.Tr "repo.license_helper"}}</div> - {{range .Licenses}} - <div class="item" data-value="{{.}}">{{.}}</div> - {{end}} + + <div id="non_template"> + <div class="inline field"> + <label>{{.i18n.Tr "repo.issue_labels"}}</label> + <div class="ui search normal selection dropdown"> + <input type="hidden" name="issue_labels" value="{{.issueLabels}}"> + <div class="default text">{{.i18n.Tr "repo.issue_labels_helper"}}</div> + <div class="menu"> + <div class="item" data-value="">{{.i18n.Tr "repo.issue_labels_helper"}}</div> + {{range .LabelTemplates}} + <div class="item" data-value="{{.}}">{{.}}</div> + {{end}} + </div> </div> </div> - </div> - <div class="inline field"> - <label>{{.i18n.Tr "repo.readme"}}</label> - <div class="ui selection dropdown"> - <input type="hidden" name="readme" value="{{.readme}}"> - <div class="default text">{{.i18n.Tr "repo.readme_helper"}}</div> - <div class="menu"> - {{range .Readmes}} - <div class="item" data-value="{{.}}">{{.}}</div> - {{end}} + <div class="ui divider"></div> + + <div class="inline field"> + <label>.gitignore</label> + <div class="ui multiple search normal selection dropdown"> + <input type="hidden" name="gitignores" value="{{.gitignores}}"> + <div class="default text">{{.i18n.Tr "repo.repo_gitignore_helper"}}</div> + <div class="menu"> + {{range .Gitignores}} + <div class="item" data-value="{{.}}">{{.}}</div> + {{end}} + </div> </div> </div> - </div> - <div class="inline field"> - <div class="ui checkbox" id="auto-init"> - <input class="hidden" name="auto_init" type="checkbox" tabindex="0" {{if .auto_init}}checked{{end}}> - <label>{{.i18n.Tr "repo.auto_init"}}</label> + <div class="inline field"> + <label>{{.i18n.Tr "repo.license"}}</label> + <div class="ui search selection dropdown"> + <input type="hidden" name="license" value="{{.license}}"> + <div class="default text">{{.i18n.Tr "repo.license_helper"}}</div> + <div class="menu"> + <div class="item" data-value="">{{.i18n.Tr "repo.license_helper"}}</div> + {{range .Licenses}} + <div class="item" data-value="{{.}}">{{.}}</div> + {{end}} + </div> + </div> + </div> + + <div class="inline field"> + <label>{{.i18n.Tr "repo.readme"}}</label> + <div class="ui selection dropdown"> + <input type="hidden" name="readme" value="{{.readme}}"> + <div class="default text">{{.i18n.Tr "repo.readme_helper"}}</div> + <div class="menu"> + {{range .Readmes}} + <div class="item" data-value="{{.}}">{{.}}</div> + {{end}} + </div> + </div> + </div> + <div class="inline field"> + <div class="ui checkbox" id="auto-init"> + <input class="hidden" name="auto_init" type="checkbox" tabindex="0" {{if .auto_init}}checked{{end}}> + <label>{{.i18n.Tr "repo.auto_init"}}</label> + </div> </div> </div> + <br/> <div class="inline field"> <label></label> <button class="ui green button"> diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 5812a4f5ba361..19989bbe06138 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -98,7 +98,7 @@ {{if eq $n 0}} {{if .Repository.IsTemplate}} <div class="ui tiny blue buttons"> - <a href="{{AppSubUrl}}/repo/generate/{{.Repository.ID}}" class="ui button"> + <a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button"> {{.i18n.Tr "repo.use_template"}} </a> </div> diff --git a/templates/repo/pulls/generate.tmpl b/templates/repo/pulls/generate.tmpl deleted file mode 100644 index 0c422e15d0f48..0000000000000 --- a/templates/repo/pulls/generate.tmpl +++ /dev/null @@ -1,74 +0,0 @@ -{{template "base/head" .}} -<div class="repository new fork"> - <div class="ui middle very relaxed page grid"> - <div class="column"> - <form class="ui form" action="{{.Link}}" method="post"> - {{.CsrfTokenHtml}} - <h3 class="ui top attached header"> - {{.i18n.Tr "new_repo"}} - </h3> - <div class="ui attached segment"> - {{template "base/alert" .}} - <div class="inline required field {{if .Err_Owner}}error{{end}}"> - <label>{{.i18n.Tr "repo.owner"}}</label> - <div class="ui selection owner dropdown"> - <input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required> - <span class="text" title="{{.ContextUser.Name}}"> - <img class="ui mini image" src="{{.ContextUser.RelAvatarLink}}"> - {{.ContextUser.ShortName 20}} - </span> - <i class="dropdown icon"></i> - <div class="menu"> - <div class="item" data-value="{{.SignedUser.ID}}" title="{{.SignedUser.Name}}"> - <img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}"> - {{.SignedUser.ShortName 20}} - </div> - {{range .Orgs}} - <div class="item" data-value="{{.ID}}" title="{{.Name}}"> - <img class="ui mini image" src="{{.RelAvatarLink}}"> - {{.ShortName 20}} - </div> - {{end}} - </div> - </div> - </div> - - <div class="inline field"> - <label>{{.i18n.Tr "repo.generate_from"}}</label> - <a href="{{AppSubUrl}}/{{.GenerateFrom}}">{{.GenerateFrom}}</a> - </div> - <div class="inline required field {{if .Err_RepoName}}error{{end}}"> - <label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label> - <input id="repo_name" name="repo_name" value="{{.repo_name}}" required> - </div> - <div class="inline field"> - <label>{{.i18n.Tr "repo.visibility"}}</label> - <div class="ui checkbox"> - {{if .IsForcedPrivate}} - <input name="private" type="checkbox" checked readonly> - <label>{{.i18n.Tr "repo.visibility_helper_forced" | Safe}}</label> - {{else}} - <input name="private" type="checkbox" {{if .private}}checked{{end}}> - <label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label> - {{end}} - </div> - <span class="help">{{.i18n.Tr "repo.visibility_description"}}</span> - </div> - <div class="inline field {{if .Err_Description}}error{{end}}"> - <label for="description">{{.i18n.Tr "repo.repo_desc"}}</label> - <textarea id="description" name="description">{{.description}}</textarea> - </div> - - <div class="inline field"> - <label></label> - <button class="ui green button"> - {{.i18n.Tr "repo.generate_repo"}} - </button> - <a class="ui button" href="{{AppSubUrl}}/{{.ForkFrom}}">{{.i18n.Tr "cancel"}}</a> - </div> - </div> - </form> - </div> - </div> -</div> -{{template "base/footer" .}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index ad3281aeacfdc..9f3f4abd24f08 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1226,6 +1226,11 @@ "name": "uid", "in": "query" }, + { + "format": "int64", + "description": "repo owner to prioritize in the results", + "name": "priority_owner_id" + }, { "type": "integer", "format": "int64", @@ -10309,6 +10314,10 @@ "format": "int64", "x-go-name": "Stars" }, + "template": { + "type": "boolean", + "x-go-name": "Template" + }, "updated_at": { "type": "string", "format": "date-time", From f491cd7d8e38404a57c5e115af887ac84df0331f Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Sun, 3 Nov 2019 22:51:17 -0600 Subject: [PATCH 20/30] Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/repo_generate_test.go | 17 +++++++++-------- models/repo.go | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index 4c0d98c6def58..b8f2a45e1e3fd 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -16,7 +16,7 @@ import ( ) func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, templateRepoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder { - forkOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: generateOwnerName}).(*models.User) + generateOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: generateOwnerName}).(*models.User) // Step0: check the existence of the generated repo req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) @@ -28,21 +28,22 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, tem // Step2: click the "Use this template" button htmlDoc := NewHTMLParser(t, resp.Body) - link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/generate/\"]").Attr("href") + link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/create\"]").Attr("href") assert.True(t, exists, "The template has changed") req = NewRequest(t, "GET", link) resp = session.MakeRequest(t, req, http.StatusOK) - // Step3: fill the form of the generate + // Step3: fill the form of the create htmlDoc = NewHTMLParser(t, resp.Body) - link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/generate/\"]").Attr("action") + link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/create\"]").Attr("action") assert.True(t, exists, "The template has changed") - _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value") + _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", generateOwner.ID)).Attr("data-value") assert.True(t, exists, fmt.Sprintf("Generate owner '%s' is not present in select box", generateOwnerName)) req = NewRequestWithValues(t, "POST", link, map[string]string{ - "_csrf": htmlDoc.GetCSRF(), - "uid": fmt.Sprintf("%d", forkOwner.ID), - "repo_name": generateRepoName, + "_csrf": htmlDoc.GetCSRF(), + "uid": fmt.Sprintf("%d", generateOwner.ID), + "repo_name": generateRepoName, + "git_content": "true", }) resp = session.MakeRequest(t, req, http.StatusFound) diff --git a/models/repo.go b/models/repo.go index c14facc96c740..c4742af957de7 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1252,6 +1252,7 @@ type GenerateRepoOptions struct { GitContent bool } +// IsValid checks whether at least one option is chosen for generation func (gro GenerateRepoOptions) IsValid() bool { return gro.GitContent // or other items as they are added } From b1bb752143cca1c786081d6acb2d23e6e3e32ad0 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Sun, 3 Nov 2019 23:22:56 -0600 Subject: [PATCH 21/30] Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> --- public/js/index.js | 10 +++++----- routers/api/v1/repo/repo.go | 2 ++ templates/swagger/v1_json.tmpl | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/public/js/index.js b/public/js/index.js index a18de25e882c4..dd33f1e25dc8c 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -2136,10 +2136,10 @@ function initWipTitle() { } function initTemplateSearch() { - let $repoTemplate = $("#repo_template"); - let checkTemplate = function() { - let $templateUnits = $("#template_units"); - let $nonTemplate = $("#non_template"); + const $repoTemplate = $("#repo_template"); + const checkTemplate = function() { + const $templateUnits = $("#template_units"); + const $nonTemplate = $("#non_template"); if ($repoTemplate.val() !== "") { $templateUnits.show(); $nonTemplate.hide(); @@ -2151,7 +2151,7 @@ function initTemplateSearch() { $repoTemplate.change(checkTemplate); checkTemplate(); - let changeOwner = function() { + const changeOwner = function() { $("#repo_template_search") .dropdown({ apiSettings: { diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 6d558998283a0..36b3eddd9f1ff 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -70,7 +70,9 @@ func Search(ctx *context.APIContext) { // type: integer // format: int64 // - name: priority_owner_id + // in: query // description: repo owner to prioritize in the results + // type: integer // format: int64 // - name: starredBy // in: query diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9f3f4abd24f08..ff987c8d017f8 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1227,9 +1227,11 @@ "in": "query" }, { + "type": "integer", "format": "int64", "description": "repo owner to prioritize in the results", - "name": "priority_owner_id" + "name": "priority_owner_id", + "in": "query" }, { "type": "integer", From e5b6e95ee99febc5752584a6da3dd35971be84eb Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 4 Nov 2019 10:00:03 -0600 Subject: [PATCH 22/30] Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo_list.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/models/repo_list.go b/models/repo_list.go index 19b9d8ae3515f..34fac8b05531d 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -321,11 +321,15 @@ func accessibleRepositoryCondition(userID int64) builder.Cond { builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePrivate}))), ), // 2. Be able to see all repositories that we have access to - builder.In("`repository`.id", builder.Select("repo_id"). - From("`access`"). - Where(builder.And( - builder.Eq{"user_id": userID}, - builder.Gt{"mode": int(AccessModeNone)}))), + builder.Or( + builder.In("`repository`.id", builder.Select("repo_id"). + From("`access`"). + Where(builder.And( + builder.Eq{"user_id": userID}, + builder.Gt{"mode": int(AccessModeNone)}))), + builder.In("`repository`.id", builder.Select("id"). + From("`repository`"). + Where(builder.Eq{"owner_id": userID}))), // 3. Be able to see all repositories that we are in a team builder.In("`repository`.id", builder.Select("`team_repo`.repo_id"). From("team_repo"). From 0fcd460e903a95f874352be0cce6bfa0d17fdee7 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 4 Nov 2019 10:08:32 -0600 Subject: [PATCH 23/30] Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> --- options/locale/locale_en-US.ini | 2 +- routers/repo/repo.go | 2 +- templates/repo/create.tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4a64e73183960..dadb3f95cc5fc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -621,7 +621,7 @@ forks = Forks pick_reaction = Pick your reaction reactions_more = and %d more -template.generate_items = Generation Items +template.items = Template Items template.git_content = Git Content archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. diff --git a/routers/repo/repo.go b/routers/repo/repo.go index a8c28d3060644..31497f30bb373 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -182,7 +182,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { } if !opts.IsValid() { - ctx.RenderWithErr("Must select at least one generation unit", tplCreate, form) + ctx.RenderWithErr("Must select at least one template item", tplCreate, form) return } diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index d1fd2e52ac213..b69c191658970 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -67,7 +67,7 @@ <div id="template_units" style="display: none;"> <div class="inline field"> - <label>{{.i18n.Tr "repo.template.generate_items"}}</label> + <label>{{.i18n.Tr "repo.template.items"}}</label> <div class="ui checkbox"> <input class="hidden" name="git_content" type="checkbox" tabindex="0" {{if .git_content}}checked{{end}}> <label>{{.i18n.Tr "repo.template.git_content"}}</label> From 06cce3d7e704f406cc289002f80e8a1b49c663c1 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 4 Nov 2019 10:31:21 -0600 Subject: [PATCH 24/30] Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/api_repo_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 88a11ef243632..a80e5142a85fe 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -92,7 +92,7 @@ func TestAPISearchRepo(t *testing.T) { {name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{ nil: {count: 5}, user: {count: 9, includesPrivate: true}, - user2: {count: 5, includesPrivate: true}}, + user2: {count: 6, includesPrivate: true}}, }, {name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{ nil: {count: 1}, From df50f7ec60e33695932a9d8fb44b9f5fb46143df Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 4 Nov 2019 10:47:33 -0600 Subject: [PATCH 25/30] Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> --- integrations/api_repo_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index a80e5142a85fe..bde0a01324660 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -103,7 +103,7 @@ func TestAPISearchRepo(t *testing.T) { {name: "RepositoriesAccessibleAndRelatedToUser3", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user3.ID), expectedResults: expectedResults{ nil: {count: 1}, user: {count: 4, includesPrivate: true}, - user2: {count: 2, includesPrivate: true}, + user2: {count: 3, includesPrivate: true}, user3: {count: 4, includesPrivate: true}}, }, {name: "RepositoriesOwnedByOrganization", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", orgUser.ID), expectedResults: expectedResults{ From 814b6397af96ff0c4e138dc8a1b9c6b7fb1e22ac Mon Sep 17 00:00:00 2001 From: John Olheiser <42128690+jolheiser@users.noreply.github.com> Date: Mon, 4 Nov 2019 21:31:29 -0600 Subject: [PATCH 26/30] Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> --- options/locale/locale_en-US.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index dadb3f95cc5fc..7aa6ba23c67c3 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -622,7 +622,7 @@ pick_reaction = Pick your reaction reactions_more = and %d more template.items = Template Items -template.git_content = Git Content +template.git_content = Git Content from default branch archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. archive.issue.nocomment = This repo is archived. You cannot comment on issues. From 1e0596188e47dce0733547ef2a343513d8730bf7 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Mon, 4 Nov 2019 22:17:49 -0600 Subject: [PATCH 27/30] Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 17 +++++++++-------- modules/context/repo.go | 4 ++++ options/locale/locale_en-US.ini | 2 +- routers/repo/repo.go | 12 ++++++++++-- templates/repo/create.tmpl | 2 +- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/models/repo.go b/models/repo.go index c4742af957de7..0d484227b083b 100644 --- a/models/repo.go +++ b/models/repo.go @@ -2745,14 +2745,15 @@ func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) ( // GenerateRepository generates a repository from a template func GenerateRepository(doer, owner *User, templateRepo *Repository, opts GenerateRepoOptions) (_ *Repository, err error) { repo := &Repository{ - OwnerID: owner.ID, - Owner: owner, - Name: opts.Name, - LowerName: strings.ToLower(opts.Name), - Description: opts.Description, - IsPrivate: opts.Private, - IsEmpty: templateRepo.IsEmpty, - TemplateID: templateRepo.ID, + OwnerID: owner.ID, + Owner: owner, + Name: opts.Name, + LowerName: strings.ToLower(opts.Name), + Description: opts.Description, + IsPrivate: opts.Private, + IsEmpty: templateRepo.IsEmpty, + IsFsckEnabled: true, + TemplateID: templateRepo.ID, } sess := x.NewSession() diff --git a/modules/context/repo.go b/modules/context/repo.go index 1c83c1e0cc9a6..1eabac67603a0 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -203,6 +203,10 @@ func RetrieveTemplateRepo(ctx *Context, repo *models.Repository) { ctx.ServerError("TemplateRepo.GetOwner", err) return } + + if !repo.TemplateRepo.CheckUnitUser(ctx.User.ID, ctx.User.IsAdmin, models.UnitTypeCode) { + repo.TemplateID = 0 + } } // ComposeGoGetImport returns go-get-import meta content. diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 7aa6ba23c67c3..ead2442cda9d4 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -622,7 +622,7 @@ pick_reaction = Pick your reaction reactions_more = and %d more template.items = Template Items -template.git_content = Git Content from default branch +template.git_content = Git Content (Default Branch) archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. archive.issue.nocomment = This repo is archived. You cannot comment on issues. diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 31497f30bb373..0aeba172a3333 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -123,14 +123,22 @@ func Create(ctx *context.Context) { ctx.Data["private"] = getRepoPrivate(ctx) ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate - ctx.Data["repo_template"] = ctx.Query("template_id") - ctxUser := checkContextUser(ctx, ctx.QueryInt64("org")) if ctx.Written() { return } ctx.Data["ContextUser"] = ctxUser + ctx.Data["repo_template_name"] = ctx.Tr("repo.template_select") + templateID := ctx.QueryInt64("template_id") + if templateID > 0 { + templateRepo, err := models.GetRepositoryByID(templateID) + if err == nil && templateRepo.CheckUnitUser(ctxUser.ID, ctxUser.IsAdmin, models.UnitTypeCode) { + ctx.Data["repo_template"] = templateID + ctx.Data["repo_template_name"] = templateRepo.Name + } + } + ctx.HTML(200, tplCreate) } diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index b69c191658970..504ffb584894f 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -59,7 +59,7 @@ <label>{{.i18n.Tr "repo.template"}}</label> <div id="repo_template_search" class="ui search normal selection dropdown"> <input type="hidden" id="repo_template" name="repo_template" value="{{.repo_template}}"> - <div class="default text">{{.i18n.Tr "repo.template_select"}}</div> + <div class="default text">{{.repo_template_name}}</div> <div class="menu"> </div> </div> From 2b9fc604e2313a65be59d4353aea50c43610f469 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 7 Nov 2019 17:03:13 -0600 Subject: [PATCH 28/30] Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 41 ++++++++++++++++++++++----------- modules/auth/repo_form.go | 1 + options/locale/locale_en-US.ini | 3 ++- routers/repo/pull.go | 29 +++++++++++++++-------- routers/repo/repo.go | 22 ++++++++++++------ templates/repo/create.tmpl | 4 ++++ 6 files changed, 69 insertions(+), 31 deletions(-) diff --git a/models/repo.go b/models/repo.go index 6c59847e984be..1de4e43ab5215 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1250,11 +1250,12 @@ type GenerateRepoOptions struct { Description string Private bool GitContent bool + Topics bool } // IsValid checks whether at least one option is chosen for generation func (gro GenerateRepoOptions) IsValid() bool { - return gro.GitContent // or other items as they are added + return gro.GitContent || gro.Topics // or other items as they are added } func getRepoInitFile(tp, name string) ([]byte, error) { @@ -2758,18 +2759,30 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, opts Genera LowerName: strings.ToLower(opts.Name), Description: opts.Description, IsPrivate: opts.Private, - IsEmpty: templateRepo.IsEmpty, - IsFsckEnabled: true, + IsEmpty: !opts.GitContent, + IsFsckEnabled: templateRepo.IsFsckEnabled, TemplateID: templateRepo.ID, } - sess := x.NewSession() - defer sess.Close() - if err = sess.Begin(); err != nil { + createSess := x.NewSession() + defer createSess.Close() + if err = createSess.Begin(); err != nil { return nil, err } - if err = createRepository(sess, doer, owner, repo); err != nil { + if err = createRepository(createSess, doer, owner, repo); err != nil { + return nil, err + } + + //Commit repo to get created repo ID + err = createSess.Commit() + if err != nil { + return nil, err + } + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { return nil, err } @@ -2779,12 +2792,6 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, opts Genera return nil, err } - //Commit repo to get generated repo ID - err = sess.Commit() - if err != nil { - return nil, err - } - if err = repo.UpdateSize(); err != nil { log.Error("Failed to update size for repository: %v", err) } @@ -2794,6 +2801,14 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, opts Genera } } + if opts.Topics { + for _, topic := range templateRepo.Topics { + if _, err := addTopicByNameToRepo(sess, repo.ID, topic); err != nil { + return nil, err + } + } + } + return repo, err } diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index cbf75bb467da6..2602dc42ebd9f 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -39,6 +39,7 @@ type CreateRepoForm struct { RepoTemplate int64 GitContent bool + Topics bool } // Validate validates the fields diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1ef011d607e16..17afc6c062986 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -581,7 +581,7 @@ repo_name_helper = Good repository names use short, memorable and unique keyword template = Template template_select = Select a template. template_helper = Make repository a template -template_description = A repository template can be used to generate a repository with the same files as the template. +template_description = A repository template can be used to generate a repository based on this one. visibility = Visibility visibility_description = Only the owner or the organization members if they have rights, will be able to see it. visibility_helper = Make Repository Private @@ -623,6 +623,7 @@ reactions_more = and %d more template.items = Template Items template.git_content = Git Content (Default Branch) +template.topics = Topics archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. archive.issue.nocomment = This repo is archived. You cannot comment on issues. diff --git a/routers/repo/pull.go b/routers/repo/pull.go index cb9c7c116406e..ac84dd16d8e7a 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -50,8 +50,8 @@ var ( } ) -func getForkRepository(ctx *context.Context) *models.Repository { - forkRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid")) +func getRepository(ctx *context.Context, repoID int64) *models.Repository { + repo, err := models.GetRepositoryByID(repoID) if err != nil { if models.IsErrRepoNotExist(err) { ctx.NotFound("GetRepositoryByID", nil) @@ -61,26 +61,34 @@ func getForkRepository(ctx *context.Context) *models.Repository { return nil } - perm, err := models.GetUserRepoPermission(forkRepo, ctx.User) + perm, err := models.GetUserRepoPermission(repo, ctx.User) if err != nil { ctx.ServerError("GetUserRepoPermission", err) return nil } - if forkRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { + if repo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { if log.IsTrace() { - if forkRepo.IsEmpty { - log.Trace("Empty fork repository %-v", forkRepo) + if repo.IsEmpty { + log.Trace("Empty repository %-v", repo) } else { - log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+ - "User in forkRepo has Permissions: %-+v", + log.Trace("Permission Denied: User %-v cannot read %-v of repo %-v\n"+ + "User in repo has Permissions: %-+v", ctx.User, models.UnitTypeCode, ctx.Repo, perm) } } - ctx.NotFound("getForkRepository", nil) + ctx.NotFound("getRepository", nil) + return nil + } + return repo +} + +func getForkRepository(ctx *context.Context) *models.Repository { + forkRepo := getRepository(ctx, ctx.ParamsInt64(":repoid")) + if ctx.Written() { return nil } @@ -89,7 +97,7 @@ func getForkRepository(ctx *context.Context) *models.Repository { ctx.Data["IsPrivate"] = forkRepo.IsPrivate canForkToUser := forkRepo.OwnerID != ctx.User.ID && !ctx.User.HasForkedRepo(forkRepo.ID) - if err = forkRepo.GetOwner(); err != nil { + if err := forkRepo.GetOwner(); err != nil { ctx.ServerError("GetOwner", err) return nil } @@ -108,6 +116,7 @@ func getForkRepository(ctx *context.Context) *models.Repository { } var traverseParentRepo = forkRepo + var err error for { if ctx.User.ID == traverseParentRepo.OwnerID { canForkToUser = false diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 0aeba172a3333..bb899340a0147 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -187,6 +187,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { Description: form.Description, Private: form.Private, GitContent: form.GitContent, + Topics: form.Topics, } if !opts.IsValid() { @@ -194,14 +195,21 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { return } - templateRepo, err := models.GetRepositoryByID(form.RepoTemplate) + templateRepo := getRepository(ctx, form.RepoTemplate) + if ctx.Written() { + return + } + + if !templateRepo.IsTemplate { + ctx.RenderWithErr("Must select a template repository", tplCreate, form) + return + } + + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts) if err == nil { - repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts) - if err == nil { - log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) - return - } + log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) + return } } else { repo, err := repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{ diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index 504ffb584894f..666e6b84c2b1c 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -72,6 +72,10 @@ <input class="hidden" name="git_content" type="checkbox" tabindex="0" {{if .git_content}}checked{{end}}> <label>{{.i18n.Tr "repo.template.git_content"}}</label> </div> + <div class="ui checkbox"> + <input class="hidden" name="topics" type="checkbox" tabindex="0" {{if .topics}}checked{{end}}> + <label>{{.i18n.Tr "repo.template.topics"}}</label> + </div> </div> </div> From 4832df7153cff5fe3c0b00dd929eaf36150284e5 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 7 Nov 2019 21:08:23 -0600 Subject: [PATCH 29/30] Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> --- models/repo.go | 51 +++++++++++++++++++------------------- public/js/index.js | 2 +- templates/repo/create.tmpl | 3 +++ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/models/repo.go b/models/repo.go index 1de4e43ab5215..91e575bf4b566 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1470,11 +1470,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C } // generateRepository initializes repository from template -func generateRepository(e Engine, repoPath string, repo, templateRepo *Repository) (err error) { - if err = checkInitRepository(repoPath); err != nil { - return err - } - +func generateRepository(e Engine, repo, templateRepo *Repository) (err error) { tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond())) if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil { @@ -2654,27 +2650,26 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) { return repo, has } -func copyLFS(newRepo, oldRepo *Repository) error { - sess := x.NewSession() - defer sess.Close() - if err := sess.Begin(); err != nil { - return err - } +// CopyLFS copies LFS data from one repo to another +func CopyLFS(newRepo, oldRepo *Repository) error { + return copyLFS(x, newRepo, oldRepo) +} +func copyLFS(e Engine, newRepo, oldRepo *Repository) error { var lfsObjects []*LFSMetaObject - if err := sess.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil { + if err := e.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil { return err } for _, v := range lfsObjects { v.ID = 0 v.RepositoryID = newRepo.ID - if _, err := sess.Insert(v); err != nil { + if _, err := e.Insert(v); err != nil { return err } } - return sess.Commit() + return nil } // ForkRepository forks a repository @@ -2747,7 +2742,7 @@ func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) ( log.Error("Failed to update size for repository: %v", err) } - return repo, copyLFS(repo, oldRepo) + return repo, CopyLFS(repo, oldRepo) } // GenerateRepository generates a repository from a template @@ -2783,33 +2778,37 @@ func GenerateRepository(doer, owner *User, templateRepo *Repository, opts Genera sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { - return nil, err + return repo, err + } + + repoPath := RepoPath(owner.Name, repo.Name) + if err = checkInitRepository(repoPath); err != nil { + return repo, err } if opts.GitContent { - repoPath := RepoPath(owner.Name, repo.Name) - if err := generateRepository(sess, repoPath, repo, templateRepo); err != nil { - return nil, err + if err = generateRepository(sess, repo, templateRepo); err != nil { + return repo, err } - if err = repo.UpdateSize(); err != nil { - log.Error("Failed to update size for repository: %v", err) + if err = repo.updateSize(sess); err != nil { + return repo, fmt.Errorf("failed to update size for repository: %v", err) } - if err = copyLFS(repo, templateRepo); err != nil { - log.Error("Failed to copy LFS: %v", err) + if err = copyLFS(sess, repo, templateRepo); err != nil { + return repo, fmt.Errorf("failed to copy LFS: %v", err) } } if opts.Topics { for _, topic := range templateRepo.Topics { - if _, err := addTopicByNameToRepo(sess, repo.ID, topic); err != nil { - return nil, err + if _, err = addTopicByNameToRepo(sess, repo.ID, topic); err != nil { + return repo, err } } } - return repo, err + return repo, sess.Commit() } // GetForks returns all the forks of the repository diff --git a/public/js/index.js b/public/js/index.js index dd33f1e25dc8c..bcdad064e4497 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -2165,7 +2165,7 @@ function initTemplateSearch() { // Parse the response from the api to work with our dropdown $.each(response.data, function(_r, repo) { filteredResponse.results.push({ - 'name' : htmlEncode(repo.name) , + 'name' : htmlEncode(repo.full_name) , 'value' : repo.id }); }); diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index 666e6b84c2b1c..f728a9363117a 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -72,6 +72,9 @@ <input class="hidden" name="git_content" type="checkbox" tabindex="0" {{if .git_content}}checked{{end}}> <label>{{.i18n.Tr "repo.template.git_content"}}</label> </div> + </div> + <div class="inline field"> + <label></label> <div class="ui checkbox"> <input class="hidden" name="topics" type="checkbox" tabindex="0" {{if .topics}}checked{{end}}> <label>{{.i18n.Tr "repo.template.topics"}}</label> From 7941084980bd833326d1fd7cd725decfedf4b600 Mon Sep 17 00:00:00 2001 From: jolheiser <john.olheiser@gmail.com> Date: Thu, 7 Nov 2019 22:37:21 -0600 Subject: [PATCH 30/30] Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com> --- options/locale/locale_en-US.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 17afc6c062986..31baa9c49f038 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -581,7 +581,7 @@ repo_name_helper = Good repository names use short, memorable and unique keyword template = Template template_select = Select a template. template_helper = Make repository a template -template_description = A repository template can be used to generate a repository based on this one. +template_description = Template repositories let users generate new repositories with the same directory structure, files, and optional settings. visibility = Visibility visibility_description = Only the owner or the organization members if they have rights, will be able to see it. visibility_helper = Make Repository Private