mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-18 15:21:04 +00:00
e9991b1f06
Backport #22568 The merge and update branch code was previously a little tangled and had some very long functions. The functions were not very clear in their reasoning and there were deficiencies in their logging and at least one bug in the handling of LFS for update by rebase. This PR substantially refactors this code and splits things out to into separate functions. It also attempts to tidy up the calls by wrapping things in "context"s. There are also attempts to improve logging when there are errors. Signed-off-by: Andrew Thornton <art27@cantab.net> Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: delvh <dev.lh@web.de>
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package pipeline
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"sync"
|
|
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/log"
|
|
)
|
|
|
|
// RevListAllObjects runs rev-list --objects --all and writes to a pipewriter
|
|
func RevListAllObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.WaitGroup, basePath string, errChan chan<- error) {
|
|
defer wg.Done()
|
|
defer revListWriter.Close()
|
|
|
|
stderr := new(bytes.Buffer)
|
|
var errbuf strings.Builder
|
|
cmd := git.NewCommand(ctx, "rev-list", "--objects", "--all")
|
|
if err := cmd.Run(&git.RunOpts{
|
|
Dir: basePath,
|
|
Stdout: revListWriter,
|
|
Stderr: stderr,
|
|
}); err != nil {
|
|
log.Error("git rev-list --objects --all [%s]: %v - %s", basePath, err, errbuf.String())
|
|
err = fmt.Errorf("git rev-list --objects --all [%s]: %w - %s", basePath, err, errbuf.String())
|
|
_ = revListWriter.CloseWithError(err)
|
|
errChan <- err
|
|
}
|
|
}
|
|
|
|
// RevListObjects run rev-list --objects from headSHA to baseSHA
|
|
func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.WaitGroup, tmpBasePath, headSHA, baseSHA string, errChan chan<- error) {
|
|
defer wg.Done()
|
|
defer revListWriter.Close()
|
|
stderr := new(bytes.Buffer)
|
|
var errbuf strings.Builder
|
|
cmd := git.NewCommand(ctx, "rev-list", "--objects").AddDynamicArguments(headSHA)
|
|
if baseSHA != "" {
|
|
cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA)
|
|
}
|
|
if err := cmd.Run(&git.RunOpts{
|
|
Dir: tmpBasePath,
|
|
Stdout: revListWriter,
|
|
Stderr: stderr,
|
|
}); err != nil {
|
|
log.Error("git rev-list [%s]: %v - %s", tmpBasePath, err, errbuf.String())
|
|
errChan <- fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String())
|
|
}
|
|
}
|
|
|
|
// BlobsFromRevListObjects reads a RevListAllObjects and only selects blobs
|
|
func BlobsFromRevListObjects(revListReader *io.PipeReader, shasToCheckWriter *io.PipeWriter, wg *sync.WaitGroup) {
|
|
defer wg.Done()
|
|
defer revListReader.Close()
|
|
scanner := bufio.NewScanner(revListReader)
|
|
defer func() {
|
|
_ = shasToCheckWriter.CloseWithError(scanner.Err())
|
|
}()
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
fields := strings.Split(line, " ")
|
|
if len(fields) < 2 || len(fields[1]) == 0 {
|
|
continue
|
|
}
|
|
toWrite := []byte(fields[0] + "\n")
|
|
for len(toWrite) > 0 {
|
|
n, err := shasToCheckWriter.Write(toWrite)
|
|
if err != nil {
|
|
_ = revListReader.CloseWithError(err)
|
|
break
|
|
}
|
|
toWrite = toWrite[n:]
|
|
}
|
|
}
|
|
}
|