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.9KB

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