Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

commit_reader.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package git
  5. import (
  6. "bufio"
  7. "bytes"
  8. "io"
  9. "strings"
  10. "gopkg.in/src-d/go-git.v4/plumbing"
  11. )
  12. // CommitFromReader will generate a Commit from a provided reader
  13. // We will need this to interpret commits from cat-file
  14. func CommitFromReader(gitRepo *Repository, sha plumbing.Hash, reader io.Reader) (*Commit, error) {
  15. commit := &Commit{
  16. ID: sha,
  17. }
  18. payloadSB := new(strings.Builder)
  19. signatureSB := new(strings.Builder)
  20. messageSB := new(strings.Builder)
  21. message := false
  22. pgpsig := false
  23. scanner := bufio.NewScanner(reader)
  24. // Split by '\n' but include the '\n'
  25. scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
  26. if atEOF && len(data) == 0 {
  27. return 0, nil, nil
  28. }
  29. if i := bytes.IndexByte(data, '\n'); i >= 0 {
  30. // We have a full newline-terminated line.
  31. return i + 1, data[0 : i+1], nil
  32. }
  33. // If we're at EOF, we have a final, non-terminated line. Return it.
  34. if atEOF {
  35. return len(data), data, nil
  36. }
  37. // Request more data.
  38. return 0, nil, nil
  39. })
  40. for scanner.Scan() {
  41. line := scanner.Bytes()
  42. if pgpsig {
  43. if len(line) > 0 && line[0] == ' ' {
  44. _, _ = signatureSB.Write(line[1:])
  45. continue
  46. } else {
  47. pgpsig = false
  48. }
  49. }
  50. if !message {
  51. // This is probably not correct but is copied from go-gits interpretation...
  52. trimmed := bytes.TrimSpace(line)
  53. if len(trimmed) == 0 {
  54. message = true
  55. _, _ = payloadSB.Write(line)
  56. continue
  57. }
  58. split := bytes.SplitN(trimmed, []byte{' '}, 2)
  59. var data []byte
  60. if len(split) > 1 {
  61. data = split[1]
  62. }
  63. switch string(split[0]) {
  64. case "tree":
  65. commit.Tree = *NewTree(gitRepo, plumbing.NewHash(string(data)))
  66. _, _ = payloadSB.Write(line)
  67. case "parent":
  68. commit.Parents = append(commit.Parents, plumbing.NewHash(string(data)))
  69. _, _ = payloadSB.Write(line)
  70. case "author":
  71. commit.Author = &Signature{}
  72. commit.Author.Decode(data)
  73. _, _ = payloadSB.Write(line)
  74. case "committer":
  75. commit.Committer = &Signature{}
  76. commit.Committer.Decode(data)
  77. _, _ = payloadSB.Write(line)
  78. case "gpgsig":
  79. _, _ = signatureSB.Write(data)
  80. _ = signatureSB.WriteByte('\n')
  81. pgpsig = true
  82. }
  83. } else {
  84. _, _ = messageSB.Write(line)
  85. }
  86. }
  87. commit.CommitMessage = messageSB.String()
  88. _, _ = payloadSB.WriteString(commit.CommitMessage)
  89. commit.Signature = &CommitGPGSignature{
  90. Signature: signatureSB.String(),
  91. Payload: payloadSB.String(),
  92. }
  93. if len(commit.Signature.Signature) == 0 {
  94. commit.Signature = nil
  95. }
  96. return commit, scanner.Err()
  97. }