code.gitea.io/gitea@v1.19.3/modules/git/pipeline/catfile.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 "strconv" 13 "strings" 14 "sync" 15 16 "code.gitea.io/gitea/modules/git" 17 "code.gitea.io/gitea/modules/log" 18 ) 19 20 // CatFileBatchCheck runs cat-file with --batch-check 21 func CatFileBatchCheck(ctx context.Context, shasToCheckReader *io.PipeReader, catFileCheckWriter *io.PipeWriter, wg *sync.WaitGroup, tmpBasePath string) { 22 defer wg.Done() 23 defer shasToCheckReader.Close() 24 defer catFileCheckWriter.Close() 25 26 stderr := new(bytes.Buffer) 27 var errbuf strings.Builder 28 cmd := git.NewCommand(ctx, "cat-file", "--batch-check") 29 if err := cmd.Run(&git.RunOpts{ 30 Dir: tmpBasePath, 31 Stdin: shasToCheckReader, 32 Stdout: catFileCheckWriter, 33 Stderr: stderr, 34 }); err != nil { 35 _ = catFileCheckWriter.CloseWithError(fmt.Errorf("git cat-file --batch-check [%s]: %w - %s", tmpBasePath, err, errbuf.String())) 36 } 37 } 38 39 // CatFileBatchCheckAllObjects runs cat-file with --batch-check --batch-all 40 func CatFileBatchCheckAllObjects(ctx context.Context, catFileCheckWriter *io.PipeWriter, wg *sync.WaitGroup, tmpBasePath string, errChan chan<- error) { 41 defer wg.Done() 42 defer catFileCheckWriter.Close() 43 44 stderr := new(bytes.Buffer) 45 var errbuf strings.Builder 46 cmd := git.NewCommand(ctx, "cat-file", "--batch-check", "--batch-all-objects") 47 if err := cmd.Run(&git.RunOpts{ 48 Dir: tmpBasePath, 49 Stdout: catFileCheckWriter, 50 Stderr: stderr, 51 }); err != nil { 52 log.Error("git cat-file --batch-check --batch-all-object [%s]: %v - %s", tmpBasePath, err, errbuf.String()) 53 err = fmt.Errorf("git cat-file --batch-check --batch-all-object [%s]: %w - %s", tmpBasePath, err, errbuf.String()) 54 _ = catFileCheckWriter.CloseWithError(err) 55 errChan <- err 56 } 57 } 58 59 // CatFileBatch runs cat-file --batch 60 func CatFileBatch(ctx context.Context, shasToBatchReader *io.PipeReader, catFileBatchWriter *io.PipeWriter, wg *sync.WaitGroup, tmpBasePath string) { 61 defer wg.Done() 62 defer shasToBatchReader.Close() 63 defer catFileBatchWriter.Close() 64 65 stderr := new(bytes.Buffer) 66 var errbuf strings.Builder 67 if err := git.NewCommand(ctx, "cat-file", "--batch").Run(&git.RunOpts{ 68 Dir: tmpBasePath, 69 Stdout: catFileBatchWriter, 70 Stdin: shasToBatchReader, 71 Stderr: stderr, 72 }); err != nil { 73 _ = shasToBatchReader.CloseWithError(fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String())) 74 } 75 } 76 77 // BlobsLessThan1024FromCatFileBatchCheck reads a pipeline from cat-file --batch-check and returns the blobs <1024 in size 78 func BlobsLessThan1024FromCatFileBatchCheck(catFileCheckReader *io.PipeReader, shasToBatchWriter *io.PipeWriter, wg *sync.WaitGroup) { 79 defer wg.Done() 80 defer catFileCheckReader.Close() 81 scanner := bufio.NewScanner(catFileCheckReader) 82 defer func() { 83 _ = shasToBatchWriter.CloseWithError(scanner.Err()) 84 }() 85 for scanner.Scan() { 86 line := scanner.Text() 87 if len(line) == 0 { 88 continue 89 } 90 fields := strings.Split(line, " ") 91 if len(fields) < 3 || fields[1] != "blob" { 92 continue 93 } 94 size, _ := strconv.Atoi(fields[2]) 95 if size > 1024 { 96 continue 97 } 98 toWrite := []byte(fields[0] + "\n") 99 for len(toWrite) > 0 { 100 n, err := shasToBatchWriter.Write(toWrite) 101 if err != nil { 102 _ = catFileCheckReader.CloseWithError(err) 103 break 104 } 105 toWrite = toWrite[n:] 106 } 107 } 108 }