aboutsummaryrefslogtreecommitdiffstats
path: root/modules/git
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2020-01-15 08:32:57 +0000
committerAntoine GIRARD <sapk@users.noreply.github.com>2020-01-15 09:32:57 +0100
commit66ee9b87f9aaabef836ec72bfaf8032b359b29c1 (patch)
treeb6d134fb5ccc83c4b7ddad6a0eb6206496cc8b76 /modules/git
parent6b1fa1235904947187266789b204f19bc03872be (diff)
downloadgitea-66ee9b87f9aaabef836ec72bfaf8032b359b29c1.tar.gz
gitea-66ee9b87f9aaabef836ec72bfaf8032b359b29c1.zip
Add require signed commit for protected branch (#9708)
* Add require signed commit for protected branch * Fix fmt * Make editor show if they will be signed * bugfix * Add basic merge check and better information for CRUD * linting comment * Add descriptors to merge signing * Slight refactor * Slight improvement to appearances * Handle Merge API * manage CRUD API * Move error to error.go * Remove fix to delete.go * prep for merge * need to tolerate \r\n in message * check protected branch before trying to load it * Apply suggestions from code review Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * fix commit-reader Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Diffstat (limited to 'modules/git')
-rw-r--r--modules/git/command.go8
-rw-r--r--modules/git/commit.go10
-rw-r--r--modules/git/commit_reader.go108
3 files changed, 119 insertions, 7 deletions
diff --git a/modules/git/command.go b/modules/git/command.go
index 33143dbd75..3cb676c8da 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -97,7 +97,7 @@ func (c *Command) RunInDirTimeoutEnvFullPipeline(env []string, timeout time.Dura
// RunInDirTimeoutEnvFullPipelineFunc executes the command in given directory with given timeout,
// it pipes stdout and stderr to given io.Writer and passes in an io.Reader as stdin. Between cmd.Start and cmd.Wait the passed in function is run.
-func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.Duration, dir string, stdout, stderr io.Writer, stdin io.Reader, fn func(context.Context, context.CancelFunc)) error {
+func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.Duration, dir string, stdout, stderr io.Writer, stdin io.Reader, fn func(context.Context, context.CancelFunc) error) error {
if timeout == -1 {
timeout = DefaultCommandExecutionTimeout
@@ -135,7 +135,11 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.
defer process.GetManager().Remove(pid)
if fn != nil {
- fn(ctx, cancel)
+ err := fn(ctx, cancel)
+ if err != nil {
+ cancel()
+ return err
+ }
}
if err := cmd.Wait(); err != nil && ctx.Err() != context.DeadlineExceeded {
diff --git a/modules/git/commit.go b/modules/git/commit.go
index dfb7adcd1a..9646d56063 100644
--- a/modules/git/commit.go
+++ b/modules/git/commit.go
@@ -33,7 +33,7 @@ type Commit struct {
CommitMessage string
Signature *CommitGPGSignature
- parents []SHA1 // SHA1 strings
+ Parents []SHA1 // SHA1 strings
submoduleCache *ObjectCache
}
@@ -94,7 +94,7 @@ func convertCommit(c *object.Commit) *Commit {
Committer: &c.Committer,
Author: &c.Author,
Signature: convertPGPSignature(c),
- parents: c.ParentHashes,
+ Parents: c.ParentHashes,
}
}
@@ -111,10 +111,10 @@ func (c *Commit) Summary() string {
// ParentID returns oid of n-th parent (0-based index).
// It returns nil if no such parent exists.
func (c *Commit) ParentID(n int) (SHA1, error) {
- if n >= len(c.parents) {
+ if n >= len(c.Parents) {
return SHA1{}, ErrNotExist{"", ""}
}
- return c.parents[n], nil
+ return c.Parents[n], nil
}
// Parent returns n-th parent (0-based index) of the commit.
@@ -133,7 +133,7 @@ func (c *Commit) Parent(n int) (*Commit, error) {
// ParentCount returns number of parents of the commit.
// 0 if this is the root commit, otherwise 1,2, etc.
func (c *Commit) ParentCount() int {
- return len(c.parents)
+ return len(c.Parents)
}
func isImageFile(data []byte) (string, bool) {
diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go
new file mode 100644
index 0000000000..06d8f426d7
--- /dev/null
+++ b/modules/git/commit_reader.go
@@ -0,0 +1,108 @@
+// Copyright 2020 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 git
+
+import (
+ "bufio"
+ "bytes"
+ "io"
+ "strings"
+
+ "gopkg.in/src-d/go-git.v4/plumbing"
+)
+
+// CommitFromReader will generate a Commit from a provided reader
+// We will need this to interpret commits from cat-file
+func CommitFromReader(gitRepo *Repository, sha plumbing.Hash, reader io.Reader) (*Commit, error) {
+ commit := &Commit{
+ ID: sha,
+ }
+
+ payloadSB := new(strings.Builder)
+ signatureSB := new(strings.Builder)
+ messageSB := new(strings.Builder)
+ message := false
+ pgpsig := false
+
+ scanner := bufio.NewScanner(reader)
+ // Split by '\n' but include the '\n'
+ scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
+ if atEOF && len(data) == 0 {
+ return 0, nil, nil
+ }
+ if i := bytes.IndexByte(data, '\n'); i >= 0 {
+ // We have a full newline-terminated line.
+ return i + 1, data[0 : i+1], nil
+ }
+ // If we're at EOF, we have a final, non-terminated line. Return it.
+ if atEOF {
+ return len(data), data, nil
+ }
+ // Request more data.
+ return 0, nil, nil
+ })
+
+ for scanner.Scan() {
+ line := scanner.Bytes()
+ if pgpsig {
+ if len(line) > 0 && line[0] == ' ' {
+ _, _ = signatureSB.Write(line[1:])
+ continue
+ } else {
+ pgpsig = false
+ }
+ }
+
+ if !message {
+ // This is probably not correct but is copied from go-gits interpretation...
+ trimmed := bytes.TrimSpace(line)
+ if len(trimmed) == 0 {
+ message = true
+ _, _ = payloadSB.Write(line)
+ continue
+ }
+
+ split := bytes.SplitN(trimmed, []byte{' '}, 2)
+ var data []byte
+ if len(split) > 1 {
+ data = split[1]
+ }
+
+ switch string(split[0]) {
+ case "tree":
+ commit.Tree = *NewTree(gitRepo, plumbing.NewHash(string(data)))
+ _, _ = payloadSB.Write(line)
+ case "parent":
+ commit.Parents = append(commit.Parents, plumbing.NewHash(string(data)))
+ _, _ = payloadSB.Write(line)
+ case "author":
+ commit.Author = &Signature{}
+ commit.Author.Decode(data)
+ _, _ = payloadSB.Write(line)
+ case "committer":
+ commit.Committer = &Signature{}
+ commit.Committer.Decode(data)
+ _, _ = payloadSB.Write(line)
+ case "gpgsig":
+ _, _ = signatureSB.Write(data)
+ _ = signatureSB.WriteByte('\n')
+ pgpsig = true
+ }
+ } else {
+ _, _ = messageSB.Write(line)
+ }
+ }
+ commit.CommitMessage = messageSB.String()
+ _, _ = payloadSB.WriteString(commit.CommitMessage)
+ commit.Signature = &CommitGPGSignature{
+ Signature: signatureSB.String(),
+ Payload: payloadSB.String(),
+ }
+ if len(commit.Signature.Signature) == 0 {
+ commit.Signature = nil
+ }
+
+ return commit, scanner.Err()
+}