internal/git/gitcmd/blob.go (50 lines of code) (raw):

package gitcmd import ( "context" "fmt" "io" "strings" "gitlab.com/gitlab-org/gitaly/v16/internal/command" "gitlab.com/gitlab-org/gitaly/v16/internal/git" "gitlab.com/gitlab-org/gitaly/v16/internal/structerr" ) // WriteBlobConfig is the configuration used to write blobs into the repository. type WriteBlobConfig struct { // Path is used by git to decide which filters to run on the content. Path string } // WriteBlob writes a blob into the given repository. func WriteBlob(ctx context.Context, repoExecutor RepositoryExecutor, content io.Reader, cfg WriteBlobConfig) (git.ObjectID, error) { options := []Option{ Flag{Name: "--stdin"}, Flag{Name: "-w"}, } if cfg.Path != "" { options = append(options, ValueFlag{Name: "--path", Value: cfg.Path}) } var stdout, stderr strings.Builder cmd, err := repoExecutor.Exec(ctx, Command{ Name: "hash-object", Flags: options, }, WithStdin(content), WithStdout(&stdout), WithStderr(&stderr), ) if err != nil { return "", fmt.Errorf("executing hash-object: %w", err) } if err := cmd.Wait(); err != nil { if exitStatus, ok := command.ExitStatus(err); ok { return "", structerr.New("writing blob failed with error code %d", exitStatus).WithMetadata("stderr", stderr.String()) } return "", structerr.New("writing blob: %w", err) } objectHash, err := repoExecutor.ObjectHash(ctx) if err != nil { return "", fmt.Errorf("detecting object hash: %w", err) } oid, err := objectHash.FromHex(strings.TrimSuffix(stdout.String(), "\n")) if err != nil { return "", fmt.Errorf("reading blob object ID: %w", err) } return oid, nil }