aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/hook.go148
-rw-r--r--docs/content/doc/advanced/config-cheat-sheet.en-us.md2
-rw-r--r--modules/setting/git.go4
3 files changed, 128 insertions, 26 deletions
diff --git a/cmd/hook.go b/cmd/hook.go
index aabd9637c2..331f6a2d2d 100644
--- a/cmd/hook.go
+++ b/cmd/hook.go
@@ -8,10 +8,12 @@ import (
"bufio"
"bytes"
"fmt"
+ "io"
"net/http"
"os"
"strconv"
"strings"
+ "time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
@@ -58,6 +60,85 @@ var (
}
)
+type delayWriter struct {
+ internal io.Writer
+ buf *bytes.Buffer
+ timer *time.Timer
+}
+
+func newDelayWriter(internal io.Writer, delay time.Duration) *delayWriter {
+ timer := time.NewTimer(delay)
+ return &delayWriter{
+ internal: internal,
+ buf: &bytes.Buffer{},
+ timer: timer,
+ }
+}
+
+func (d *delayWriter) Write(p []byte) (n int, err error) {
+ if d.buf != nil {
+ select {
+ case <-d.timer.C:
+ _, err := d.internal.Write(d.buf.Bytes())
+ if err != nil {
+ return 0, err
+ }
+ d.buf = nil
+ return d.internal.Write(p)
+ default:
+ return d.buf.Write(p)
+ }
+ }
+ return d.internal.Write(p)
+}
+
+func (d *delayWriter) WriteString(s string) (n int, err error) {
+ if d.buf != nil {
+ select {
+ case <-d.timer.C:
+ _, err := d.internal.Write(d.buf.Bytes())
+ if err != nil {
+ return 0, err
+ }
+ d.buf = nil
+ return d.internal.Write([]byte(s))
+ default:
+ return d.buf.WriteString(s)
+ }
+ }
+ return d.internal.Write([]byte(s))
+}
+
+func (d *delayWriter) Close() error {
+ if d == nil {
+ return nil
+ }
+ stopped := d.timer.Stop()
+ if stopped {
+ return nil
+ }
+ select {
+ case <-d.timer.C:
+ default:
+ }
+ if d.buf == nil {
+ return nil
+ }
+ _, err := d.internal.Write(d.buf.Bytes())
+ d.buf = nil
+ return err
+}
+
+type nilWriter struct{}
+
+func (n *nilWriter) Write(p []byte) (int, error) {
+ return len(p), nil
+}
+
+func (n *nilWriter) WriteString(s string) (int, error) {
+ return len(s), nil
+}
+
func runHookPreReceive(c *cli.Context) error {
if os.Getenv(models.EnvIsInternal) == "true" {
return nil
@@ -101,6 +182,18 @@ Gitea or set your environment appropriately.`, "")
total := 0
lastline := 0
+ var out io.Writer
+ out = &nilWriter{}
+ if setting.Git.VerbosePush {
+ if setting.Git.VerbosePushDelay > 0 {
+ dWriter := newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
+ defer dWriter.Close()
+ out = dWriter
+ } else {
+ out = os.Stdout
+ }
+ }
+
for scanner.Scan() {
// TODO: support news feeds for wiki
if isWiki {
@@ -124,12 +217,10 @@ Gitea or set your environment appropriately.`, "")
newCommitIDs[count] = newCommitID
refFullNames[count] = refFullName
count++
- fmt.Fprintf(os.Stdout, "*")
- os.Stdout.Sync()
+ fmt.Fprintf(out, "*")
if count >= hookBatchSize {
- fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
- os.Stdout.Sync()
+ fmt.Fprintf(out, " Checking %d branches\n", count)
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
@@ -147,12 +238,10 @@ Gitea or set your environment appropriately.`, "")
lastline = 0
}
} else {
- fmt.Fprintf(os.Stdout, ".")
- os.Stdout.Sync()
+ fmt.Fprintf(out, ".")
}
if lastline >= hookBatchSize {
- fmt.Fprintf(os.Stdout, "\n")
- os.Stdout.Sync()
+ fmt.Fprintf(out, "\n")
lastline = 0
}
}
@@ -162,8 +251,7 @@ Gitea or set your environment appropriately.`, "")
hookOptions.NewCommitIDs = newCommitIDs[:count]
hookOptions.RefFullNames = refFullNames[:count]
- fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
- os.Stdout.Sync()
+ fmt.Fprintf(out, " Checking %d branches\n", count)
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
switch statusCode {
@@ -173,14 +261,11 @@ Gitea or set your environment appropriately.`, "")
fail(msg, "")
}
} else if lastline > 0 {
- fmt.Fprintf(os.Stdout, "\n")
- os.Stdout.Sync()
+ fmt.Fprintf(out, "\n")
lastline = 0
}
- fmt.Fprintf(os.Stdout, "Checked %d references in total\n", total)
- os.Stdout.Sync()
-
+ fmt.Fprintf(out, "Checked %d references in total\n", total)
return nil
}
@@ -206,6 +291,19 @@ Gitea or set your environment appropriately.`, "")
}
}
+ var out io.Writer
+ var dWriter *delayWriter
+ out = &nilWriter{}
+ if setting.Git.VerbosePush {
+ if setting.Git.VerbosePushDelay > 0 {
+ dWriter = newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
+ defer dWriter.Close()
+ out = dWriter
+ } else {
+ out = os.Stdout
+ }
+ }
+
// the environment setted on serv command
repoUser := os.Getenv(models.EnvRepoUsername)
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
@@ -241,7 +339,7 @@ Gitea or set your environment appropriately.`, "")
continue
}
- fmt.Fprintf(os.Stdout, ".")
+ fmt.Fprintf(out, ".")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = string(fields[2])
@@ -250,16 +348,15 @@ Gitea or set your environment appropriately.`, "")
}
count++
total++
- os.Stdout.Sync()
if count >= hookBatchSize {
- fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
- os.Stdout.Sync()
+ fmt.Fprintf(out, " Processing %d references\n", count)
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
hookOptions.RefFullNames = refFullNames
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
if resp == nil {
+ _ = dWriter.Close()
hookPrintResults(results)
fail("Internal Server Error", err)
}
@@ -277,9 +374,9 @@ Gitea or set your environment appropriately.`, "")
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
- fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
- os.Stdout.Sync()
+ fmt.Fprintf(out, "Processed %d references in total\n", total)
+ _ = dWriter.Close()
hookPrintResults(results)
return nil
}
@@ -288,19 +385,18 @@ Gitea or set your environment appropriately.`, "")
hookOptions.NewCommitIDs = newCommitIDs[:count]
hookOptions.RefFullNames = refFullNames[:count]
- fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
- os.Stdout.Sync()
+ fmt.Fprintf(out, " Processing %d references\n", count)
resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
if resp == nil {
+ _ = dWriter.Close()
hookPrintResults(results)
fail("Internal Server Error", err)
}
wasEmpty = wasEmpty || resp.RepoWasEmpty
results = append(results, resp.Results...)
- fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
- os.Stdout.Sync()
+ fmt.Fprintf(out, "Processed %d references in total\n", total)
if wasEmpty && masterPushed {
// We need to tell the repo to reset the default branch to master
@@ -309,7 +405,7 @@ Gitea or set your environment appropriately.`, "")
fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
-
+ _ = dWriter.Close()
hookPrintResults(results)
return nil
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index dc6a1ba346..ea17096ea5 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -522,6 +522,8 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false`
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1
+- `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
+- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
## Git - Timeout settings (`git.timeout`)
- `DEFAUlT`: **360**: Git operations default timeout seconds.
diff --git a/modules/setting/git.go b/modules/setting/git.go
index 8495be8836..8c8179cba6 100644
--- a/modules/setting/git.go
+++ b/modules/setting/git.go
@@ -21,6 +21,8 @@ var (
MaxGitDiffLines int
MaxGitDiffLineCharacters int
MaxGitDiffFiles int
+ VerbosePush bool
+ VerbosePushDelay time.Duration
GCArgs []string `ini:"GC_ARGS" delim:" "`
EnableAutoGitWireProtocol bool
Timeout struct {
@@ -36,6 +38,8 @@ var (
MaxGitDiffLines: 1000,
MaxGitDiffLineCharacters: 5000,
MaxGitDiffFiles: 100,
+ VerbosePush: true,
+ VerbosePushDelay: 5 * time.Second,
GCArgs: []string{},
EnableAutoGitWireProtocol: true,
Timeout: struct {