This document covers transport protocols and authentication methods for communicating with remote Git repositories.
go-git supports multiple transport protocols:
type Transport interface {
NewUploadPackSession(*Endpoint, AuthMethod) (UploadPackSession, error)
NewReceivePackSession(*Endpoint, AuthMethod) (ReceivePackSession, error)
}type Endpoint struct {
Protocol string
User string
Password string
Host string
Port int
Path string
InsecureSkipTLS bool
ClientCert []byte
ClientKey []byte
CaBundle []byte
Proxy ProxyOptions
}
func NewEndpoint(url string) (*Endpoint, error)
func (e *Endpoint) String() stringExample:
package main
import (
"fmt"
"github.com/go-git/go-git/v5/plumbing/transport"
)
func main() {
// Parse endpoint
ep, err := transport.NewEndpoint("https://github.com/user/repo.git")
if err != nil {
panic(err)
}
fmt.Println("Protocol:", ep.Protocol)
fmt.Println("Host:", ep.Host)
fmt.Println("Path:", ep.Path)
}import "github.com/go-git/go-git/v5/plumbing/transport/http"
type BasicAuth struct {
Username string
Password string
}
func (a *BasicAuth) Name() string
func (a *BasicAuth) String() stringExample:
package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)
func main() {
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://github.com/private/repo",
Auth: &http.BasicAuth{
Username: "username",
Password: "password",
},
})
if err != nil {
panic(err)
}
_ = r
}import "github.com/go-git/go-git/v5/plumbing/transport/http"
type TokenAuth struct {
Token string
}
func (a *TokenAuth) Name() string
func (a *TokenAuth) String() stringExample:
package main
import (
"os"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)
func main() {
token := os.Getenv("GITHUB_TOKEN")
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://github.com/private/repo",
Auth: &http.TokenAuth{
Token: token,
},
})
if err != nil {
panic(err)
}
_ = r
}import "github.com/go-git/go-git/v5/plumbing/transport/ssh"
type PublicKeys struct {
User string
Signer ssh.Signer
}
func NewPublicKeys(user string, pemBytes []byte, password string) (*PublicKeys, error)
func NewPublicKeysFromFile(user, pemFile, password string) (*PublicKeys, error)
func (a *PublicKeys) Name() string
func (a *PublicKeys) String() string
func (a *PublicKeys) ClientConfig() (*ssh.ClientConfig, error)Example:
package main
import (
"os"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
)
func main() {
sshKey := os.Getenv("HOME") + "/.ssh/id_rsa"
auth, err := ssh.NewPublicKeysFromFile("git", sshKey, "")
if err != nil {
panic(err)
}
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "git@github.com:user/repo.git",
Auth: auth,
})
if err != nil {
panic(err)
}
_ = r
}import "github.com/go-git/go-git/v5/plumbing/transport/ssh"
type Password struct {
User string
Password string
}
func (a *Password) Name() string
func (a *Password) String() string
func (a *Password) ClientConfig() (*ssh.ClientConfig, error)Example:
package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
)
func main() {
auth := &ssh.Password{
User: "git",
Password: "password",
}
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "ssh://git@example.com/repo.git",
Auth: auth,
})
if err != nil {
panic(err)
}
_ = r
}package main
import (
"github.com/go-git/go-git/v5"
)
func main() {
// WARNING: Only for testing or self-signed certificates
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://self-signed.example.com/repo.git",
InsecureSkipTLS: true,
})
if err != nil {
panic(err)
}
_ = r
}package main
import (
"os"
"github.com/go-git/go-git/v5"
)
func main() {
caBundle, err := os.ReadFile("/path/to/ca-cert.pem")
if err != nil {
panic(err)
}
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://example.com/repo.git",
CABundle: caBundle,
})
if err != nil {
panic(err)
}
_ = r
}package main
import (
"os"
"github.com/go-git/go-git/v5"
)
func main() {
clientCert, _ := os.ReadFile("/path/to/client.crt")
clientKey, _ := os.ReadFile("/path/to/client.key")
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://example.com/repo.git",
ClientCert: clientCert,
ClientKey: clientKey,
})
if err != nil {
panic(err)
}
_ = r
}type ProxyOptions struct {
URL string
Username string
Password string
}
func (o *ProxyOptions) Validate() error
func (o *ProxyOptions) FullURL() (*url.URL, error)Example:
package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport"
)
func main() {
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://github.com/user/repo",
ProxyOptions: transport.ProxyOptions{
URL: "http://proxy.example.com:8080",
Username: "proxy-user",
Password: "proxy-pass",
},
})
if err != nil {
panic(err)
}
_ = r
}import "github.com/go-git/go-git/v5/plumbing/transport/client"
func NewClient(url string) (transport.Transport, error)
var Protocols map[string]transport.TransportExample:
package main
import (
"fmt"
"github.com/go-git/go-git/v5/plumbing/transport/client"
)
func main() {
// Get transport for URL
tr, err := client.NewClient("https://github.com/user/repo")
if err != nil {
panic(err)
}
fmt.Printf("Transport: %T\n", tr)
}var (
ErrRepositoryNotFound = errors.New("repository not found")
ErrEmptyRemoteRepository = errors.New("remote repository is empty")
ErrAuthenticationRequired = errors.New("authentication required")
ErrAuthorizationFailed = errors.New("authorization failed")
ErrEmptyUploadPackRequest = errors.New("empty upload pack request")
ErrInvalidAuthMethod = errors.New("invalid auth method")
ErrAlreadyConnected = errors.New("session already established")
)package main
import (
"os"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)
func main() {
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://github.com/private/repo",
Auth: &http.BasicAuth{
Username: os.Getenv("GIT_USERNAME"),
Password: os.Getenv("GIT_PASSWORD"),
},
})
if err != nil {
panic(err)
}
_ = r
}package main
import (
"errors"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)
func main() {
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "https://github.com/private/repo",
Auth: &http.BasicAuth{
Username: "user",
Password: "wrong",
},
})
if err != nil {
if errors.Is(err, transport.ErrAuthenticationRequired) {
println("Authentication required")
} else if errors.Is(err, transport.ErrAuthorizationFailed) {
println("Invalid credentials")
} else {
panic(err)
}
return
}
_ = r
}package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
)
func main() {
// Use SSH agent for authentication
auth, err := ssh.NewSSHAgentAuth("git")
if err != nil {
panic(err)
}
r, err := git.PlainClone("/tmp/repo", false, &git.CloneOptions{
URL: "git@github.com:user/repo.git",
Auth: auth,
})
if err != nil {
panic(err)
}
_ = r
}