Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

commit_reader.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "bufio"
  6. "bytes"
  7. "io"
  8. "strings"
  9. )
  10. // CommitFromReader will generate a Commit from a provided reader
  11. // We need this to interpret commits from cat-file or cat-file --batch
  12. //
  13. // If used as part of a cat-file --batch stream you need to limit the reader to the correct size
  14. func CommitFromReader(gitRepo *Repository, objectID ObjectID, reader io.Reader) (*Commit, error) {
  15. commit := &Commit{
  16. ID: objectID,
  17. Author: &Signature{},
  18. Committer: &Signature{},
  19. }
  20. payloadSB := new(strings.Builder)
  21. signatureSB := new(strings.Builder)
  22. messageSB := new(strings.Builder)
  23. message := false
  24. pgpsig := false
  25. bufReader, ok := reader.(*bufio.Reader)
  26. if !ok {
  27. bufReader = bufio.NewReader(reader)
  28. }
  29. readLoop:
  30. for {
  31. line, err := bufReader.ReadBytes('\n')
  32. if err != nil {
  33. if err == io.EOF {
  34. if message {
  35. _, _ = messageSB.Write(line)
  36. }
  37. _, _ = payloadSB.Write(line)
  38. break readLoop
  39. }
  40. return nil, err
  41. }
  42. if pgpsig {
  43. if len(line) > 0 && line[0] == ' ' {
  44. _, _ = signatureSB.Write(line[1:])
  45. continue
  46. }
  47. pgpsig = false
  48. }
  49. if !message {
  50. // This is probably not correct but is copied from go-gits interpretation...
  51. trimmed := bytes.TrimSpace(line)
  52. if len(trimmed) == 0 {
  53. message = true
  54. _, _ = payloadSB.Write(line)
  55. continue
  56. }
  57. split := bytes.SplitN(trimmed, []byte{' '}, 2)
  58. var data []byte
  59. if len(split) > 1 {
  60. data = split[1]
  61. }
  62. switch string(split[0]) {
  63. case "tree":
  64. commit.Tree = *NewTree(gitRepo, MustIDFromString(string(data)))
  65. _, _ = payloadSB.Write(line)
  66. case "parent":
  67. commit.Parents = append(commit.Parents, MustIDFromString(string(data)))
  68. _, _ = payloadSB.Write(line)
  69. case "author":
  70. commit.Author = &Signature{}
  71. commit.Author.Decode(data)
  72. _, _ = payloadSB.Write(line)
  73. case "committer":
  74. commit.Committer = &Signature{}
  75. commit.Committer.Decode(data)
  76. _, _ = payloadSB.Write(line)
  77. case "encoding":
  78. _, _ = payloadSB.Write(line)
  79. case "gpgsig":
  80. fallthrough
  81. case "gpgsig-sha256": // FIXME: no intertop, so only 1 exists at present.
  82. _, _ = signatureSB.Write(data)
  83. _ = signatureSB.WriteByte('\n')
  84. pgpsig = true
  85. }
  86. } else {
  87. _, _ = messageSB.Write(line)
  88. _, _ = payloadSB.Write(line)
  89. }
  90. }
  91. commit.CommitMessage = messageSB.String()
  92. commit.Signature = &CommitSignature{
  93. Signature: signatureSB.String(),
  94. Payload: payloadSB.String(),
  95. }
  96. if len(commit.Signature.Signature) == 0 {
  97. commit.Signature = nil
  98. }
  99. return commit, nil
  100. }