diff --git a/git/command/command.go b/git/command/command.go index 3f1b67f6d..d8551304e 100644 --- a/git/command/command.go +++ b/git/command/command.go @@ -133,13 +133,15 @@ func (c *Command) Run(ctx context.Context, opts ...RunOptionFunc) (err error) { return ctx.Err() case err = <-result: - if err != nil && errAsBuff { - buff, ok := options.Stderr.(*bytes.Buffer) - if ok { - return NewError(err, buff.Bytes()) - } + if err == nil { + return nil } - return err + + var stderr []byte + if buff, ok := options.Stderr.(*bytes.Buffer); ok && errAsBuff { + stderr = buff.Bytes() + } + return NewError(err, stderr) } } diff --git a/git/command/error.go b/git/command/error.go index 6a9f74563..dcddbd521 100644 --- a/git/command/error.go +++ b/git/command/error.go @@ -17,6 +17,7 @@ package command import ( "errors" "fmt" + "os/exec" ) var ( @@ -24,7 +25,7 @@ var ( ErrInvalidArg = errors.New("invalid argument") ) -// Error type with optional Stderr payload. +// Error type with optional ExitCode and Stderr payload. type Error struct { Err error StdErr []byte @@ -38,6 +39,15 @@ func NewError(err error, stderr []byte) *Error { } } +func (e *Error) ExitCode() int { + var exitErr *exec.ExitError + ok := errors.As(e.Err, &exitErr) + if ok { + return exitErr.ExitCode() + } + return 0 +} + func (e *Error) Error() string { if len(e.StdErr) != 0 { return fmt.Sprintf("%s: %s", e.Err.Error(), e.StdErr) @@ -45,6 +55,10 @@ func (e *Error) Error() string { return e.Err.Error() } +func (e *Error) Unwrap() error { + return e.Err +} + // AsError unwraps Error otherwise return nil. func AsError(err error) (e *Error) { if errors.As(err, &e) {