or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

config.mdindex.mdobjects.mdplumbing.mdreferences.mdremote-operations.mdrepository-operations.mdstorage.mdtransport.mdworktree-operations.md
tile.json

transport.mddocs/

Transport

This document covers transport protocols and authentication methods for communicating with remote Git repositories.

Overview

go-git supports multiple transport protocols:

  • HTTP/HTTPS - Web-based Git protocol
  • SSH - Secure shell protocol
  • Git - Native Git protocol
  • File - Local filesystem

Transport Interface

type Transport interface {
    NewUploadPackSession(*Endpoint, AuthMethod) (UploadPackSession, error)
    NewReceivePackSession(*Endpoint, AuthMethod) (ReceivePackSession, error)
}

Endpoint

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() string

Example:

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)
}

Authentication Methods

HTTP Basic Authentication

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() string

Example:

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
}

HTTP Token Authentication

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() string

Example:

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
}

SSH Public Key Authentication

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
}

SSH Password Authentication

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
}

TLS Configuration

Skip TLS Verification

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
}

Custom CA Bundle

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
}

Client Certificates

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
}

Proxy Configuration

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
}

Transport Client

import "github.com/go-git/go-git/v5/plumbing/transport/client"

func NewClient(url string) (transport.Transport, error)

var Protocols map[string]transport.Transport

Example:

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)
}

Common Errors

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")
)

Best Practices

1. Use Environment Variables for Credentials

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
}

2. Handle Authentication Errors

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
}

3. Use SSH Agent

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
}

See Also

  • Remote Operations - Using transport for remote operations
  • Repository Operations - Clone operations