Initial support for push options (#12169)

* Initial support for push options

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Fix misspelling 🤦

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Fix formatting after conflict resolution

* defer close git repo

* According the GitLab documentation, git >= 2.10

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Words are hard. Thanks @mrsdizzie 😅

Co-authored-by: mrsdizzie <info@mrsdizzie.com>

* Only update if there are push options

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: mrsdizzie <info@mrsdizzie.com>
tokarchuk/v1.17
John Olheiser 4 years ago committed by GitHub
parent e7d65cbc6e
commit 43a397ce9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      cmd/doctor.go
  2. 16
      cmd/hook.go
  3. 31
      docs/content/doc/usage/push-options.en-us.md
  4. 6
      modules/git/git.go
  5. 22
      modules/private/hook.go
  6. 12
      routers/private/hook.go

@ -127,6 +127,12 @@ var checklist = []check{
isDefault: false, isDefault: false,
f: runDoctorUserStarNum, f: runDoctorUserStarNum,
}, },
{
title: "Enable push options",
name: "enable-push-options",
isDefault: false,
f: runDoctorEnablePushOptions,
},
// more checks please append here // more checks please append here
} }
@ -605,3 +611,28 @@ func runDoctorCheckDBConsistency(ctx *cli.Context) ([]string, error) {
return results, nil return results, nil
} }
func runDoctorEnablePushOptions(ctx *cli.Context) ([]string, error) {
numRepos := 0
_, err := iterateRepositories(func(repo *models.Repository) ([]string, error) {
numRepos++
r, err := git.OpenRepository(repo.RepoPath())
if err != nil {
return nil, err
}
defer r.Close()
if ctx.Bool("fix") {
_, err := git.NewCommand("config", "receive.advertisePushOptions", "true").RunInDir(r.Path)
return nil, err
}
return nil, nil
})
var prefix string
if !ctx.Bool("fix") {
prefix = "DRY RUN: "
}
return []string{fmt.Sprintf("%sEnabled push options for %d repositories.", prefix, numRepos)}, err
}

@ -178,6 +178,7 @@ Gitea or set your environment appropriately.`, "")
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories), GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
GitObjectDirectory: os.Getenv(private.GitObjectDirectory), GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
GitQuarantinePath: os.Getenv(private.GitQuarantinePath), GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
GitPushOptions: pushOptions(),
ProtectedBranchID: prID, ProtectedBranchID: prID,
IsDeployKey: isDeployKey, IsDeployKey: isDeployKey,
} }
@ -326,6 +327,7 @@ Gitea or set your environment appropriately.`, "")
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories), GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
GitObjectDirectory: os.Getenv(private.GitObjectDirectory), GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
GitQuarantinePath: os.Getenv(private.GitQuarantinePath), GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
GitPushOptions: pushOptions(),
} }
oldCommitIDs := make([]string, hookBatchSize) oldCommitIDs := make([]string, hookBatchSize)
newCommitIDs := make([]string, hookBatchSize) newCommitIDs := make([]string, hookBatchSize)
@ -438,3 +440,17 @@ func hookPrintResults(results []private.HookPostReceiveBranchResult) {
os.Stderr.Sync() os.Stderr.Sync()
} }
} }
func pushOptions() map[string]string {
opts := make(map[string]string)
if pushCount, err := strconv.Atoi(os.Getenv(private.GitPushOptionCount)); err == nil {
for idx := 0; idx < pushCount; idx++ {
opt := os.Getenv(fmt.Sprintf("GIT_PUSH_OPTION_%d", idx))
kv := strings.SplitN(opt, "=", 2)
if len(kv) == 2 {
opts[kv[0]] = kv[1]
}
}
}
return opts
}

@ -0,0 +1,31 @@
---
date: "2020-07-06T16:00:00+02:00"
title: "Usage: Push Options"
slug: "push-options"
weight: 15
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Push Options"
weight: 15
identifier: "push-options"
---
# Push Options
In Gitea `1.13`, support for some [push options](https://git-scm.com/docs/git-push#Documentation/git-push.txt--oltoptiongt)
were added.
## Supported Options
- `repo.private` (true|false) - Change the repository's visibility.
This is particularly useful when combined with push-to-create.
- `repo.template` (true|false) - Change whether the repository is a template.
Example of changing a repository's visibility to public:
```shell
git push -o repo.private=false -u origin master
```

@ -120,6 +120,12 @@ func Init(ctx context.Context) error {
return err return err
} }
if version.Compare(gitVersion, "2.10", ">=") {
if err := checkAndSetConfig("receive.advertisePushOptions", "true", true); err != nil {
return err
}
}
if version.Compare(gitVersion, "2.18", ">=") { if version.Compare(gitVersion, "2.18", ">=") {
if err := checkAndSetConfig("core.commitGraph", "true", true); err != nil { if err := checkAndSetConfig("core.commitGraph", "true", true); err != nil {
return err return err

@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"strconv"
"time" "time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -19,8 +20,28 @@ const (
GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES" GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
GitObjectDirectory = "GIT_OBJECT_DIRECTORY" GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
GitQuarantinePath = "GIT_QUARANTINE_PATH" GitQuarantinePath = "GIT_QUARANTINE_PATH"
GitPushOptionCount = "GIT_PUSH_OPTION_COUNT"
) )
// GitPushOptions is a wrapper around a map[string]string
type GitPushOptions map[string]string
// GitPushOptions keys
const (
GitPushOptionRepoPrivate = "repo.private"
GitPushOptionRepoTemplate = "repo.template"
)
// Bool checks for a key in the map and parses as a boolean
func (g GitPushOptions) Bool(key string, def bool) bool {
if val, ok := g[key]; ok {
if b, err := strconv.ParseBool(val); err == nil {
return b
}
}
return def
}
// HookOptions represents the options for the Hook calls // HookOptions represents the options for the Hook calls
type HookOptions struct { type HookOptions struct {
OldCommitIDs []string OldCommitIDs []string
@ -31,6 +52,7 @@ type HookOptions struct {
GitObjectDirectory string GitObjectDirectory string
GitAlternativeObjectDirectories string GitAlternativeObjectDirectories string
GitQuarantinePath string GitQuarantinePath string
GitPushOptions GitPushOptions
ProtectedBranchID int64 ProtectedBranchID int64
IsDeployKey bool IsDeployKey bool
} }

@ -436,6 +436,18 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) {
} }
} }
// Push Options
if repo != nil && len(opts.GitPushOptions) > 0 {
repo.IsPrivate = opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate, repo.IsPrivate)
repo.IsTemplate = opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate, repo.IsTemplate)
if err := models.UpdateRepositoryCols(repo, "is_private", "is_template"); err != nil {
log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
})
}
}
results := make([]private.HookPostReceiveBranchResult, 0, len(opts.OldCommitIDs)) results := make([]private.HookPostReceiveBranchResult, 0, len(opts.OldCommitIDs))
// We have to reload the repo in case its state is changed above // We have to reload the repo in case its state is changed above

Loading…
Cancel
Save