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  }