You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_ref_nogogit.go 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. //go:build !gogit
  4. package git
  5. import (
  6. "bufio"
  7. "io"
  8. "strings"
  9. )
  10. // GetRefsFiltered returns all references of the repository that matches patterm exactly or starting with.
  11. func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) {
  12. stdoutReader, stdoutWriter := io.Pipe()
  13. defer func() {
  14. _ = stdoutReader.Close()
  15. _ = stdoutWriter.Close()
  16. }()
  17. go func() {
  18. stderrBuilder := &strings.Builder{}
  19. err := NewCommand(repo.Ctx, "for-each-ref").Run(&RunOpts{
  20. Dir: repo.Path,
  21. Stdout: stdoutWriter,
  22. Stderr: stderrBuilder,
  23. })
  24. if err != nil {
  25. _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
  26. } else {
  27. _ = stdoutWriter.Close()
  28. }
  29. }()
  30. refs := make([]*Reference, 0)
  31. bufReader := bufio.NewReader(stdoutReader)
  32. for {
  33. // The output of for-each-ref is simply a list:
  34. // <sha> SP <type> TAB <ref> LF
  35. sha, err := bufReader.ReadString(' ')
  36. if err == io.EOF {
  37. break
  38. }
  39. if err != nil {
  40. return nil, err
  41. }
  42. sha = sha[:len(sha)-1]
  43. typ, err := bufReader.ReadString('\t')
  44. if err == io.EOF {
  45. // This should not happen, but we'll tolerate it
  46. break
  47. }
  48. if err != nil {
  49. return nil, err
  50. }
  51. typ = typ[:len(typ)-1]
  52. refName, err := bufReader.ReadString('\n')
  53. if err == io.EOF {
  54. // This should not happen, but we'll tolerate it
  55. break
  56. }
  57. if err != nil {
  58. return nil, err
  59. }
  60. refName = refName[:len(refName)-1]
  61. // refName cannot be HEAD but can be remotes or stash
  62. if strings.HasPrefix(refName, RemotePrefix) || refName == "/refs/stash" {
  63. continue
  64. }
  65. if pattern == "" || strings.HasPrefix(refName, pattern) {
  66. r := &Reference{
  67. Name: refName,
  68. Object: MustIDFromString(sha),
  69. Type: typ,
  70. repo: repo,
  71. }
  72. refs = append(refs, r)
  73. }
  74. }
  75. return refs, nil
  76. }