code.gitea.io/gitea@v1.19.3/modules/git/pipeline/revlist.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package pipeline 5 6 import ( 7 "bufio" 8 "bytes" 9 "context" 10 "fmt" 11 "io" 12 "strings" 13 "sync" 14 15 "code.gitea.io/gitea/modules/git" 16 "code.gitea.io/gitea/modules/log" 17 ) 18 19 // RevListAllObjects runs rev-list --objects --all and writes to a pipewriter 20 func RevListAllObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.WaitGroup, basePath string, errChan chan<- error) { 21 defer wg.Done() 22 defer revListWriter.Close() 23 24 stderr := new(bytes.Buffer) 25 var errbuf strings.Builder 26 cmd := git.NewCommand(ctx, "rev-list", "--objects", "--all") 27 if err := cmd.Run(&git.RunOpts{ 28 Dir: basePath, 29 Stdout: revListWriter, 30 Stderr: stderr, 31 }); err != nil { 32 log.Error("git rev-list --objects --all [%s]: %v - %s", basePath, err, errbuf.String()) 33 err = fmt.Errorf("git rev-list --objects --all [%s]: %w - %s", basePath, err, errbuf.String()) 34 _ = revListWriter.CloseWithError(err) 35 errChan <- err 36 } 37 } 38 39 // RevListObjects run rev-list --objects from headSHA to baseSHA 40 func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.WaitGroup, tmpBasePath, headSHA, baseSHA string, errChan chan<- error) { 41 defer wg.Done() 42 defer revListWriter.Close() 43 stderr := new(bytes.Buffer) 44 var errbuf strings.Builder 45 cmd := git.NewCommand(ctx, "rev-list", "--objects").AddDynamicArguments(headSHA) 46 if baseSHA != "" { 47 cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA) 48 } 49 if err := cmd.Run(&git.RunOpts{ 50 Dir: tmpBasePath, 51 Stdout: revListWriter, 52 Stderr: stderr, 53 }); err != nil { 54 log.Error("git rev-list [%s]: %v - %s", tmpBasePath, err, errbuf.String()) 55 errChan <- fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String()) 56 } 57 } 58 59 // BlobsFromRevListObjects reads a RevListAllObjects and only selects blobs 60 func BlobsFromRevListObjects(revListReader *io.PipeReader, shasToCheckWriter *io.PipeWriter, wg *sync.WaitGroup) { 61 defer wg.Done() 62 defer revListReader.Close() 63 scanner := bufio.NewScanner(revListReader) 64 defer func() { 65 _ = shasToCheckWriter.CloseWithError(scanner.Err()) 66 }() 67 for scanner.Scan() { 68 line := scanner.Text() 69 if len(line) == 0 { 70 continue 71 } 72 fields := strings.Split(line, " ") 73 if len(fields) < 2 || len(fields[1]) == 0 { 74 continue 75 } 76 toWrite := []byte(fields[0] + "\n") 77 for len(toWrite) > 0 { 78 n, err := shasToCheckWriter.Write(toWrite) 79 if err != nil { 80 _ = revListReader.CloseWithError(err) 81 break 82 } 83 toWrite = toWrite[n:] 84 } 85 } 86 }