diff --git a/blob.go b/blob.go index dd3084931..a6e392eeb 100644 --- a/blob.go +++ b/blob.go @@ -22,11 +22,16 @@ type Blob struct { // Data gets content of blob all at once and wrap it as io.Reader. // This can be very slow and memory consuming for huge content. func (b *Blob) Data() (io.Reader, error) { - stdout, err := NewCommand("show", b.ID.String()).RunInDirBytes(b.repo.Path) - if err != nil { - return nil, err + stdout := new(bytes.Buffer) + stderr := new(bytes.Buffer) + + // Preallocate memory to save ~50% memory usage on big files. + stdout.Grow(int(b.Size() + 2048)) + + if err := b.DataPipeline(stdout, stderr); err != nil { + return nil, concatenateError(err, stderr.String()) } - return bytes.NewBuffer(stdout), nil + return stdout, nil } // DataPipeline gets content of blob and write the result or error to stdout or stderr diff --git a/blob_test.go b/blob_test.go index 9487de63a..11b01d9fa 100644 --- a/blob_test.go +++ b/blob_test.go @@ -17,6 +17,9 @@ var testBlob = &Blob{ repo: &Repository{}, TreeEntry: &TreeEntry{ ID: MustIDFromString("176d8dfe018c850d01851b05fb8a430096247353"), + ptree: &Tree{ + repo: &Repository{}, + }, }, }