github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/repo_ref_nogogit.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 //go:build !gogit 7 8 package git 9 10 import ( 11 "bufio" 12 "io" 13 "strings" 14 ) 15 16 // GetRefsFiltered returns all references of the repository that matches patterm exactly or starting with. 17 func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { 18 stdoutReader, stdoutWriter := io.Pipe() 19 defer func() { 20 _ = stdoutReader.Close() 21 _ = stdoutWriter.Close() 22 }() 23 24 go func() { 25 stderrBuilder := &strings.Builder{} 26 err := NewCommand(repo.Ctx, "for-each-ref").Run(&RunOpts{ 27 Dir: repo.Path, 28 Stdout: stdoutWriter, 29 Stderr: stderrBuilder, 30 }) 31 if err != nil { 32 _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String())) 33 } else { 34 _ = stdoutWriter.Close() 35 } 36 }() 37 38 refs := make([]*Reference, 0) 39 bufReader := bufio.NewReader(stdoutReader) 40 for { 41 // The output of for-each-ref is simply a list: 42 // <sha> SP <type> TAB <ref> LF 43 sha, err := bufReader.ReadString(' ') 44 if err == io.EOF { 45 break 46 } 47 if err != nil { 48 return nil, err 49 } 50 sha = sha[:len(sha)-1] 51 52 typ, err := bufReader.ReadString('\t') 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 typ = typ[:len(typ)-1] 61 62 refName, err := bufReader.ReadString('\n') 63 if err == io.EOF { 64 // This should not happen, but we'll tolerate it 65 break 66 } 67 if err != nil { 68 return nil, err 69 } 70 refName = refName[:len(refName)-1] 71 72 // refName cannot be HEAD but can be remotes or stash 73 if strings.HasPrefix(refName, RemotePrefix) || refName == "/refs/stash" { 74 continue 75 } 76 77 if pattern == "" || strings.HasPrefix(refName, pattern) { 78 r := &Reference{ 79 Name: refName, 80 Object: MustIDFromString(sha), 81 Type: typ, 82 repo: repo, 83 } 84 refs = append(refs, r) 85 } 86 } 87 88 return refs, nil 89 }