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