git

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2025 License: MIT Imports: 21 Imported by: 0

README

Git Library for Go

Go Reference Go Report Card License

A high-level, idiomatic Go wrapper for Git operations built on go-git. This library provides a clean, task-oriented API for common Git workflows while enforcing filesystem abstraction for both on-disk and in-memory repositories.

Features

  • 🎯 Simple, task-oriented API - Focus on what you want to do, not how Git does it
  • 🧪 Testable by design - Full in-memory filesystem support for testing
  • 🔒 Secure defaults - Built-in authentication, host verification, and credential safety
  • Performance optimized - LRU caching, shallow operations, and efficient diffs
  • 🔧 Go idiomatic - Accepts interfaces, returns concrete types, follows Go patterns
  • ⏱️ Context support - All operations support timeouts and cancellation
  • 📦 Zero external dependencies - Only depends on go-git and the filesystem abstraction

Table of Contents

Installation

go get github.com/input-output-hk/catalyst-forge-libs/git

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"
    "github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
    // Create filesystem
    fs := billyfs.NewOSFS("./my-repo")

    // Initialize a new repository
    repo, err := git.Init(context.Background(), &git.Options{
        FS:      fs,
        Workdir: ".",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Create and commit a file
    err = fs.WriteFile("README.md", []byte("# My Project\n"), 0644)
    if err != nil {
        log.Fatal(err)
    }

    // Stage the file
    err = repo.Add(context.Background(), "README.md")
    if err != nil {
        log.Fatal(err)
    }

    // Commit
    sha, err := repo.Commit(context.Background(), "Initial commit", git.Signature{
        Name:  "John Doe",
        Email: "john@example.com",
    }, git.CommitOpts{})
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Created commit: %s\n", sha)
}

Core Concepts

Filesystem Abstraction

This library requires the use of the project's filesystem abstraction (fs.Filesystem). This design enables:

  • Complete testability with in-memory repositories
  • Consistent I/O patterns across the codebase
  • Easy mocking and testing without touching disk
  • Sandboxed operations for security
Options Pattern

All repository operations start with an Options struct that configures the repository:

type Options struct {
    FS              fs.Filesystem  // Required: filesystem to use
    Workdir         string         // Working directory (default: ".")
    Bare            bool           // Create/use bare repository
    StorerCacheSize int            // LRU cache size (default: 1000)
    Auth            AuthProvider   // Authentication provider
    HTTPClient      *http.Client   // Custom HTTP client
    ShallowDepth    int            // Shallow clone depth (0 = full)
}

API Documentation

Repository Operations
Initialize a Repository
repo, err := git.Init(ctx, &git.Options{
    FS:      fs,
    Workdir: ".",
    Bare:    false,  // Set true for bare repository
})
Open Existing Repository
repo, err := git.Open(ctx, &git.Options{
    FS:      fs,
    Workdir: ".",
})
Clone Repository
repo, err := git.Clone(ctx, "https://github.com/user/repo.git", &git.Options{
    FS:           fs,
    Workdir:      ".",
    ShallowDepth: 1,    // Shallow clone with depth 1
    Auth:         auth,  // Optional authentication
})
Branch Management
Create and Switch Branches
// Get current branch
branch, err := repo.CurrentBranch(ctx)

// Create new branch
err = repo.CreateBranch(ctx, "feature/new", "HEAD", false, false)

// Checkout branch
err = repo.CheckoutBranch(ctx, "feature/new", false, false)

// Create and checkout in one step
err = repo.CheckoutBranch(ctx, "feature/another", true, false)

// Delete branch
err = repo.DeleteBranch(ctx, "old-feature")

// Checkout remote branch
err = repo.CheckoutRemoteBranch(ctx, "origin", "main", "main", true)
Staging and Commits
Working with Files
// Stage files
err = repo.Add(ctx, "file1.go", "file2.go")

// Stage all changes
err = repo.Add(ctx, ".")

// Unstage files
err = repo.Unstage(ctx, "file1.go")

// Remove files
err = repo.Remove(ctx, "deleted.go")
Creating Commits
sha, err := repo.Commit(ctx, "feat: add new feature", git.Signature{
    Name:  "Jane Doe",
    Email: "jane@example.com",
}, git.CommitOpts{
    AllowEmpty: false,  // Prevent empty commits
})
Synchronization
Fetch, Pull, and Push
// Fetch from remote
err = repo.Fetch(ctx, "origin", true, 0)  // true = prune stale branches

// Pull with fast-forward only
err = repo.PullFFOnly(ctx, "origin")

// Fetch and merge
err = repo.FetchAndMerge(ctx, "origin", "main", git.FastForwardOnly)

// Push current branch
err = repo.Push(ctx, "origin", false)  // false = no force push
Tags
Tag Management
// Create annotated tag
err = repo.CreateTag(ctx, "v1.0.0", "HEAD", "Release v1.0.0", true)

// Create lightweight tag
err = repo.CreateTag(ctx, "latest", "HEAD", "", false)

// List tags
tags, err := repo.Tags(ctx)

// List tags with filter
tags, err := repo.Tags(ctx, git.TagPatternFilter("v*"))

// Delete tag
err = repo.DeleteTag(ctx, "old-tag")
History and Diffs
Query Commit History
// Get commit log with filters
iter, err := repo.Log(ctx, git.LogFilter{
    Since:    &sinceTime,
    Until:    &untilTime,
    Author:   "Jane",
    Path:     []string{"src/"},
    MaxCount: 100,
})
defer iter.Close()

// Iterate commits
err = iter.ForEach(func(c *object.Commit) error {
    fmt.Printf("%s: %s\n", c.Hash, c.Message)
    return nil
})
Compute Diffs
// Diff between commits
diff, err := repo.Diff(ctx, "HEAD~1", "HEAD", nil)

// Diff with filters
diff, err := repo.Diff(ctx, "v1.0.0", "v2.0.0",
    git.ExtensionFilter(".go", ".mod"),
    git.PathPrefixFilter("src/"),
)

fmt.Printf("Files changed: %d\n", diff.FileCount)
fmt.Println(diff.Text)
References
Working with References
// List references by type
branches, err := repo.Refs(ctx, git.RefBranch, "")
tags, err := repo.Refs(ctx, git.RefTag, "")
remotes, err := repo.Refs(ctx, git.RefRemoteBranch, "")

// Resolve any reference
resolved, err := repo.Resolve(ctx, "HEAD~2")
fmt.Printf("Type: %s, Hash: %s\n", resolved.Kind, resolved.Hash)

Authentication

The library supports authentication through the AuthProvider interface. You can implement custom providers or use the built-in ones:

// Custom auth provider
type TokenAuth struct {
    token string
}

func (a *TokenAuth) Method(ctx context.Context, url string) (transport.AuthMethod, error) {
    return &http.BasicAuth{
        Username: "token",
        Password: a.token,
    }, nil
}

// Use with repository
repo, err := git.Clone(ctx, remoteURL, &git.Options{
    FS:   fs,
    Auth: &TokenAuth{token: "github_pat_..."},
})

In-Memory Operations

Perfect for testing and temporary operations:

// Create in-memory filesystem
memFS := billyfs.NewInMemoryFS()

// All operations work exactly the same
repo, err := git.Init(ctx, &git.Options{
    FS:      memFS,
    Workdir: "/",
})

// Create files in memory
err = memFS.WriteFile("test.txt", []byte("content"), 0644)
err = repo.Add(ctx, "test.txt")
sha, err := repo.Commit(ctx, "test", sig, git.CommitOpts{})

Error Handling

The library provides sentinel errors for common conditions:

import "errors"

err := repo.Push(ctx, "origin", false)
switch {
case errors.Is(err, git.ErrNotFastForward):
    // Handle non-fast-forward
case errors.Is(err, git.ErrAuthRequired):
    // Handle missing auth
case errors.Is(err, git.ErrAlreadyUpToDate):
    // Nothing to do
default:
    // Handle other errors
}

Available sentinel errors:

  • ErrAlreadyUpToDate - No changes to fetch/pull/push
  • ErrAuthRequired - Authentication needed but not provided
  • ErrAuthFailed - Authentication failed
  • ErrBranchExists - Branch already exists
  • ErrBranchMissing - Branch not found
  • ErrTagExists - Tag already exists
  • ErrTagMissing - Tag not found
  • ErrNotFastForward - Merge would not be fast-forward
  • ErrMergeConflict - Merge has conflicts
  • ErrInvalidRef - Invalid reference format
  • ErrResolveFailed - Cannot resolve reference

Examples

Complete Workflow Example
func completeWorkflow(ctx context.Context) error {
    // Initialize repository
    fs := billyfs.NewOSFS("./project")
    repo, err := git.Init(ctx, &git.Options{FS: fs})
    if err != nil {
        return err
    }

    // Create initial structure
    files := map[string]string{
        "README.md":   "# Project\n",
        "main.go":     "package main\n",
        ".gitignore":  "*.tmp\n",
    }

    for path, content := range files {
        if err := fs.WriteFile(path, []byte(content), 0644); err != nil {
            return err
        }
    }

    // Initial commit
    if err := repo.Add(ctx, "."); err != nil {
        return err
    }

    sha, err := repo.Commit(ctx, "Initial commit", git.Signature{
        Name:  "Bot",
        Email: "bot@example.com",
    }, git.CommitOpts{})
    if err != nil {
        return err
    }

    // Create feature branch
    if err := repo.CreateBranch(ctx, "feature/awesome", sha, false, false); err != nil {
        return err
    }

    if err := repo.CheckoutBranch(ctx, "feature/awesome", false, false); err != nil {
        return err
    }

    // Make changes on feature branch
    if err := fs.WriteFile("feature.go", []byte("package main\n"), 0644); err != nil {
        return err
    }

    if err := repo.Add(ctx, "feature.go"); err != nil {
        return err
    }

    _, err = repo.Commit(ctx, "Add feature", git.Signature{
        Name:  "Developer",
        Email: "dev@example.com",
    }, git.CommitOpts{})

    return err
}
More Examples

See the example_test.go file for more comprehensive examples including:

  • Repository initialization and cloning
  • Branch operations
  • Commit workflows
  • Tag management
  • History traversal
  • Diff computation
  • Remote synchronization

Testing

The library is designed for testability:

func TestMyGitOperation(t *testing.T) {
    // Use in-memory filesystem for fast, isolated tests
    fs := billyfs.NewInMemoryFS()

    repo, err := git.Init(context.Background(), &git.Options{
        FS:      fs,
        Workdir: "/",
    })
    require.NoError(t, err)

    // Test your git operations without touching disk
    err = fs.WriteFile("test.txt", []byte("test"), 0644)
    require.NoError(t, err)

    err = repo.Add(context.Background(), "test.txt")
    require.NoError(t, err)

    // Assertions...
}

Performance

Optimizations
  • LRU Object Cache: Configure StorerCacheSize in Options (default: 1000)
  • Shallow Operations: Use ShallowDepth for faster clones of large repositories
  • Selective Fetching: Fetch only needed branches with pruning
  • Filtered Diffs: Use path filters to compute diffs only for relevant files
Benchmarks
// Shallow clone for large repositories
repo, err := git.Clone(ctx, url, &git.Options{
    FS:           fs,
    ShallowDepth: 1,  // Only fetch latest commit
})

// Filtered diff for performance
diff, err := repo.Diff(ctx, "HEAD~100", "HEAD",
    git.PathPrefixFilter("src/"),  // Only diff src/ directory
    git.ExtensionFilter(".go"),    // Only Go files
)

Thread Safety

  • Read operations are safe for concurrent use (Log, Diff, Refs, CurrentBranch)
  • Write operations must be serialized (Add, Commit, Push, etc.)
  • Each Repo instance maintains its own state

Limitations

This library intentionally does not support:

  • Interactive operations (rebase -i, add -i)
  • Complex merge conflict resolution
  • Submodule management (planned for future)
  • Direct git CLI invocation

For advanced use cases not covered by this facade, you can access the underlying go-git repository, though this is discouraged for maintainability.

Contributing

Contributions are welcome! Please ensure:

  1. All code follows the Go Coding Standards
  2. Tests are written for new functionality (test-first development)
  3. Documentation is updated for API changes
  4. golangci-lint passes with zero errors
  5. Maintain backward compatibility
Development Setup
# Clone the repository
git clone https://github.com/input-output-hk/catalyst-forge-libs
cd catalyst-forge-libs/git

# Install dependencies
go mod download

# Run tests
go test -v -race ./...

# Run linter
golangci-lint run ./...

# Check coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgments

Support

For issues, questions, or contributions, please visit:

Documentation

Overview

Package git provides branch management operations for git repositories. This file contains all branch-related operations including creation, checkout, deletion, and remote branch handling.

Package git provides high-level Git operations through a clean facade. This file contains diff-related operations for comparing revisions.

Package git provides a high-level, idiomatic Go wrapper for git operations.

This package offers a clean facade over go-git, exposing task-oriented operations for common git workflows while enforcing the use of the project's native filesystem abstraction. All operations work with both on-disk and in-memory repositories.

Design Principles

The package follows these core principles:

  • Minimal surface area - easy to learn and extend
  • Testability by construction - in-memory FS, controlled side effects
  • Security & performance - context timeouts, auth integration, object caching
  • Go idioms - accepts interfaces, returns concrete types

Basic Usage

Initialize or open a repository:

import (
    "context"
    billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"
    "github.com/input-output-hk/catalyst-forge-libs/git"
)

// Create filesystem (can be OS-backed or in-memory)
fs := billyfs.NewOSFS("/path/to/repo")

// Open existing repository
repo, err := git.Open(context.Background(), &git.Options{
    FS: fs,
    Workdir: ".",
})

// Or initialize new repository
repo, err := git.Init(context.Background(), &git.Options{
    FS: fs,
    Workdir: ".",
})

Working with Branches

Create and switch branches:

// Create new branch from current HEAD
err = repo.CreateBranch(ctx, "feature/new", "HEAD", false, false)

// Checkout the branch
err = repo.CheckoutBranch(ctx, "feature/new", false, false)

// Get current branch
branch, err := repo.CurrentBranch(ctx)

Making Commits

Stage files and create commits:

// Stage files
err = repo.Add(ctx, "file1.go", "file2.go")

// Or stage everything
err = repo.Add(ctx, ".")

// Create commit
sha, err := repo.Commit(ctx, "feat: add new feature", git.Signature{
    Name:  "John Doe",
    Email: "john@example.com",
}, git.CommitOpts{})

Synchronization

Fetch, pull, and push changes:

// Fetch from remote
err = repo.Fetch(ctx, "origin", true, 0)

// Pull with fast-forward only
err = repo.PullFFOnly(ctx, "origin")

// Push current branch
err = repo.Push(ctx, "origin", false)

Working with Tags

Create and manage tags:

// Create annotated tag
err = repo.CreateTag(ctx, "v1.0.0", "HEAD", "Release v1.0.0", true)

// List tags matching pattern
tags, err := repo.Tags(ctx, git.TagPatternFilter("v*"))

// Delete tag
err = repo.DeleteTag(ctx, "v1.0.0")

History and Diffs

Query commit history and compute diffs:

// Get commit history with filters
iter, err := repo.Log(ctx, git.LogFilter{
    Author:   "John",
    MaxCount: 10,
})
defer iter.Close()

// Iterate through commits
err = iter.ForEach(func(c *object.Commit) error {
    fmt.Printf("%s: %s\n", c.Hash, c.Message)
    return nil
})

// Compute diff between revisions
diff, err := repo.Diff(ctx, "HEAD~1", "HEAD", git.ExtensionFilter(".go"))
fmt.Println(diff.Text)

Authentication

The package supports authentication through the AuthProvider interface. Implementations for HTTPS (token/password) and SSH (key file, agent) are available in the internal/auth package. Users can implement their own AuthProvider for custom authentication needs:

type MyAuthProvider struct {
    token string
}

func (a *MyAuthProvider) Method(ctx context.Context, url string) (transport.AuthMethod, error) {
    // Return appropriate auth method based on URL
    return &http.BasicAuth{Username: "token", Password: a.token}, nil
}

// Use in options
opts := &git.Options{
    FS:   fs,
    Auth: &MyAuthProvider{token: "github_pat_..."},
}

In-Memory Operations

All operations can run entirely in memory for testing:

// Create in-memory filesystem
memFS := billyfs.NewInMemoryFS()

// Initialize in-memory repository
repo, err := git.Init(ctx, &git.Options{
    FS:      memFS,
    Workdir: "/",
})

// All operations work the same
err = memFS.WriteFile("test.txt", []byte("content"), 0644)
err = repo.Add(ctx, "test.txt")
sha, err := repo.Commit(ctx, "test commit", sig, git.CommitOpts{})

Error Handling

The package provides sentinel errors for common conditions:

err := repo.Push(ctx, "origin", false)
if errors.Is(err, git.ErrNotFastForward) {
    // Handle non-fast-forward push
}
if errors.Is(err, git.ErrAuthRequired) {
    // Handle missing authentication
}

Context Support

All operations accept a context for timeout and cancellation:

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

err = repo.Clone(ctx, "https://github.com/example/repo.git", opts)
if err != nil {
    // Operation was cancelled or timed out
}

Thread Safety

A Repo instance is NOT safe for concurrent writes. Read operations (Log, Diff, Refs, CurrentBranch, etc.) can be called concurrently. Write operations (Add, Commit, Push, etc.) must be serialized.

Performance Considerations

The package includes several performance optimizations:

  • LRU object cache (configurable via StorerCacheSize)
  • Shallow clone/fetch support (via ShallowDepth option)
  • Path filtering for diffs to reduce computation
  • Efficient ref iteration without loading full objects

Limitations

This package intentionally does not support:

  • Interactive operations (rebase -i, add -i)
  • Complex merge conflict resolution
  • Submodule management (may be added later)
  • Direct git CLI invocation

For advanced use cases not covered by this facade, the underlying go-git repository object can be accessed if needed (though this is discouraged for maintainability).

Package git provides sentinel errors for common git operations. All errors can be checked using errors.Is() for programmatic handling.

Package git provides a high-level Go wrapper for go-git operations. It exposes task-oriented operations for repository management while operating exclusively through the project's native filesystem abstraction.

Package git provides high-level Git operations through a clean facade. This file contains history-related operations including commit logging and iteration.

Package git provides high-level Git operations through a clean facade. This file contains reference-related operations for listing and resolving refs.

Package git provides a high-level Go wrapper for go-git operations. This file contains synchronization operations (fetch, pull, merge, push).

Package git provides a high-level Go wrapper for go-git operations. This file contains tag-related operations for repository management.

Package git provides a high-level Go wrapper for go-git operations. This file contains worktree operations (add, remove, unstage, commit).

Index

Examples

Constants

View Source
const (
	// DefaultStorerCacheSize is the default size for the LRU object cache.
	DefaultStorerCacheSize = 1000

	// DefaultWorkdir is the default worktree directory name.
	DefaultWorkdir = "."

	// DefaultRemoteName is the default remote name used for operations.
	DefaultRemoteName = "origin"
)

Variables

View Source
var ErrAlreadyUpToDate = errors.New("already up to date")

ErrAlreadyUpToDate is returned when fetch, pull, or push operations result in no changes because the local and remote states are already synchronized.

View Source
var ErrAuthFailed = errors.New("authentication failed")

ErrAuthFailed is returned when authentication was attempted but failed (invalid credentials, expired tokens, etc.).

View Source
var ErrAuthRequired = errors.New("authentication required")

ErrAuthRequired is returned when an operation requires authentication but no credentials were provided or available.

View Source
var ErrBranchExists = errors.New("branch already exists")

ErrBranchExists is returned when attempting to create a branch that already exists and force creation was not requested.

View Source
var ErrBranchMissing = errors.New("branch does not exist")

ErrBranchMissing is returned when attempting to operate on a branch that does not exist.

View Source
var ErrEmptyCommit = errors.New("cannot create empty commit")

ErrEmptyCommit is returned when attempting to create a commit with no changes and AllowEmpty is false.

View Source
var ErrInvalidRef = errors.New("invalid reference")

ErrInvalidRef is returned when a reference name or revision specification is malformed or invalid according to git's reference naming rules.

View Source
var ErrMergeConflict = errors.New("merge conflict")

ErrMergeConflict is returned when a merge operation encounters conflicts that cannot be automatically resolved.

View Source
var ErrNotFastForward = errors.New("not a fast-forward")

ErrNotFastForward is returned when a push or pull operation cannot be performed as a fast-forward merge and requires manual conflict resolution.

View Source
var ErrResolveFailed = errors.New("cannot resolve revision")

ErrResolveFailed is returned when a revision specification cannot be resolved to a valid commit hash (e.g., branch/tag doesn't exist, invalid SHA).

View Source
var ErrTagExists = errors.New("tag already exists")

ErrTagExists is returned when attempting to create a tag that already exists and force creation was not requested.

View Source
var ErrTagMissing = errors.New("tag does not exist")

ErrTagMissing is returned when attempting to operate on a tag that does not exist.

Functions

func WrapError

func WrapError(err error, msg string) error

WrapError wraps an error with additional context while preserving the ability to check against sentinel errors using errors.Is().

func WrapErrorf

func WrapErrorf(err error, format string, args ...interface{}) error

WrapErrorf wraps an error with formatted additional context while preserving the ability to check against sentinel errors using errors.Is().

Types

type AuthProvider

type AuthProvider interface {
	// Method returns the appropriate transport.AuthMethod for the given remote URL.
	// Returns nil if no authentication is needed/available for this URL.
	// Returns an error if authentication cannot be resolved for the URL.
	Method(remoteURL string) (transport.AuthMethod, error)
}

AuthProvider resolves authentication methods for git operations. Implementations should handle different URL schemes and credential sources.

type ChangeFilter

type ChangeFilter func(*object.Change) bool

ChangeFilter is a predicate function for filtering changes in diffs. It returns true if the change should be included in the diff output. Filters are applied progressively - if any filter returns false, the change is excluded.

func AddedFilter

func AddedFilter() ChangeFilter

AddedFilter creates a filter that only includes newly added files.

func AndFilter

func AndFilter(filters ...ChangeFilter) ChangeFilter

AndFilter combines multiple filters with AND logic - all must pass.

func ChangeExcludePathFilter

func ChangeExcludePathFilter(path string) ChangeFilter

ChangeExcludePathFilter returns a filter that excludes changes affecting the specified path. This is useful for filtering out certain paths while keeping all others.

func ChangeExtensionFilter

func ChangeExtensionFilter(ext string) ChangeFilter

ChangeExtensionFilter returns a filter that includes changes to files with the specified extension. The extension should include the dot (e.g., ".go", ".md").

func ChangePathFilter

func ChangePathFilter(path string) ChangeFilter

ChangePathFilter returns a filter that includes changes affecting the specified path. The path can be a file or directory. For directories, all files within are matched.

func CustomFilter

func CustomFilter(predicate func(*object.Change) bool) ChangeFilter

CustomFilter allows creating a filter with a custom predicate function. This is useful for one-off filtering logic.

func DeletedFilter

func DeletedFilter() ChangeFilter

DeletedFilter creates a filter that only includes deleted files.

func ExtensionFilter

func ExtensionFilter(extensions ...string) ChangeFilter

ExtensionFilter creates a filter that includes changes for files with the given extensions. Extensions should include the dot (e.g., ".go", ".js").

func MaxSizeFilter

func MaxSizeFilter(maxBytes int64) ChangeFilter

MaxSizeFilter creates a filter that excludes files larger than the specified size in bytes. Note: This requires fetching the blob objects to check their size, which may impact performance.

func ModifiedFilter

func ModifiedFilter() ChangeFilter

ModifiedFilter creates a filter that only includes modified files (not added or deleted).

func NonBinaryFilter

func NonBinaryFilter() ChangeFilter

NonBinaryFilter creates a filter that excludes binary files. It uses file extension heuristics to identify binary files.

func NotFilter

func NotFilter(filter ChangeFilter) ChangeFilter

NotFilter creates a filter that inverts the result of another filter.

func OrFilter

func OrFilter(filters ...ChangeFilter) ChangeFilter

OrFilter combines multiple filters with OR logic - at least one must pass.

func PathFilter

func PathFilter(pattern string) ChangeFilter

PathFilter creates a filter that includes changes matching the given path pattern. The pattern can include wildcards (* and ?) and is matched against both the old and new file names (to handle renames).

func PathPrefixFilter

func PathPrefixFilter(prefix string) ChangeFilter

PathPrefixFilter creates a filter that includes changes with paths starting with the given prefix. This is useful for filtering by directory.

func RenamedFilter

func RenamedFilter() ChangeFilter

RenamedFilter creates a filter that only includes renamed/moved files.

type CommitIter

type CommitIter struct {
	// contains filtered or unexported fields
}

CommitIter represents an iterator over commits returned by Log operations. It provides methods to iterate through commits efficiently without loading all commits into memory at once.

func (*CommitIter) Close

func (ci *CommitIter) Close()

Close closes the iterator and releases any associated resources.

func (*CommitIter) ForEach

func (ci *CommitIter) ForEach(fn func(*object.Commit) error) error

ForEach executes the provided function for each commit in the iterator. Iteration stops if the function returns an error.

func (*CommitIter) Next

func (ci *CommitIter) Next() (*object.Commit, error)

Next returns the next commit in the iteration. Returns nil when iteration is complete.

type CommitOpts

type CommitOpts struct {
	// AllowEmpty allows creating commits with no changes.
	// By default, empty commits are not allowed.
	AllowEmpty bool

	// All adds all modified and untracked files to the index before committing.
	// Equivalent to running 'git add .' before commit.
	All bool

	// Amend amends the tip of the current branch with this commit.
	// This replaces the current commit rather than creating a new one.
	Amend bool
}

CommitOpts configures commit creation behavior. These options control how commits are created and what files are included.

type LogFilter

type LogFilter struct {
	// Since limits the log to commits after the specified time.
	// Only commits with timestamps after this time will be included.
	Since *time.Time

	// Until limits the log to commits before the specified time.
	// Only commits with timestamps before this time will be included.
	Until *time.Time

	// Author filters commits by author name/email pattern.
	// Supports glob patterns for partial matching.
	Author string

	// Path filters commits that modified the specified path(s).
	// Only commits that touched these paths will be included.
	Path []string

	// MaxCount limits the number of commits returned.
	// If 0, all matching commits are returned.
	MaxCount int
}

LogFilter configures which commits to include in log operations. Use this to filter commits by time range, author, paths, or limit the result count.

type MergeStrategy

type MergeStrategy int8

MergeStrategy represents the different types of merge strategies. Currently, only FastForwardOnly is supported by go-git.

const (
	// FastForwardOnly represents a merge strategy that only allows fast-forward merges.
	// This will fail if a merge commit would be required.
	FastForwardOnly MergeStrategy = iota
)

func (MergeStrategy) String

func (s MergeStrategy) String() string

String returns a human-readable string representation of the MergeStrategy.

type Options

type Options struct {
	// FS is the REQUIRED native filesystem root (OS or in-memory).
	// All repository state lives within this filesystem.
	FS fs.Filesystem

	// Workdir is the path within FS for the worktree root.
	// Defaults to "." (current directory in FS).
	Workdir string

	// Bare indicates if this should be a bare repository (.git only, no worktree).
	// Defaults to false (non-bare repository with worktree).
	Bare bool

	// StorerCacheSize sets the LRU objects cache entries.
	// Higher values improve performance but use more memory.
	// Defaults to DefaultStorerCacheSize.
	StorerCacheSize int

	// Auth is an optional provider that resolves per-URL AuthMethod.
	// If nil, no authentication will be available.
	Auth AuthProvider

	// HTTPClient is an optional custom transport for network operations.
	// If nil, a default client with reasonable timeouts is used.
	HTTPClient *http.Client

	// ShallowDepth sets the depth for shallow clone/fetch operations.
	// If > 0, operations will be shallow with the specified depth.
	// If 0, full clone/fetch operations are performed.
	ShallowDepth int
}

Options configures repository discovery/creation and performance.

func (*Options) Validate

func (o *Options) Validate() error

Validate checks that the Options are properly configured. It returns an error if required fields are missing or invalid.

type PatchText

type PatchText struct {
	// Text contains the unified diff in string format.
	Text string

	// IsBinary indicates whether the diff contains binary files.
	// When true, the diff text may be truncated or contain binary markers.
	IsBinary bool

	// FileCount indicates the number of files that have changes.
	FileCount int
}

PatchText represents unified diff text between two revisions. It contains the formatted diff output that can be displayed to users or processed by other tools.

type RefKind

type RefKind int

RefKind represents the type of git reference. This is used to classify references when listing or resolving them.

const (
	// RefBranch indicates a local branch reference (refs/heads/*).
	RefBranch RefKind = iota

	// RefRemoteBranch indicates a remote branch reference (refs/remotes/*/*).
	RefRemoteBranch

	// RefTag indicates a tag reference (refs/tags/*).
	RefTag

	// RefRemote indicates a generic remote reference.
	RefRemote

	// RefCommit indicates a commit hash (not a symbolic reference).
	RefCommit

	// RefOther indicates any other type of reference.
	RefOther
)

func (RefKind) String

func (k RefKind) String() string

String returns a human-readable string representation of the RefKind.

type Repo

type Repo struct {
	// contains filtered or unexported fields
}

Repo represents a git repository and provides high-level operations. It wraps a go-git Repository and Worktree, operating exclusively through the project's native filesystem abstraction.

func Clone

func Clone(ctx context.Context, remoteURL string, opts *Options) (*Repo, error)

Clone creates a new repository by cloning from a remote URL. It supports both bare and non-bare repositories, shallow cloning, and authentication.

The remoteURL should be a valid git URL (https://, ssh://, or file:// for local repos). For shallow clones, set ShallowDepth > 0 to limit the clone depth. Authentication is handled via the AuthProvider if credentials are required.

Context timeout/cancellation is honored during the clone operation.

Example

ExampleClone demonstrates how to clone a remote repository.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	fs := billyfs.NewOSFS("/tmp/cloned-repo")

	// Clone repository (authentication can be provided via Auth field)
	repo, err := git.Clone(context.Background(), "https://github.com/example/repo.git", &git.Options{
		FS:           fs,
		Workdir:      ".",
		ShallowDepth: 1, // Shallow clone for faster operation
		// Auth: myAuthProvider, // Provide AuthProvider implementation
	})
	if err != nil {
		log.Fatal(err)
	}

	// List files in the cloned repo
	files, err := fs.ReadDir(".")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Cloned %d files\n", len(files))
	_ = repo // Use repo for further operations
}

func Init

func Init(ctx context.Context, opts *Options) (*Repo, error)

Init creates a new git repository at the specified location. It initializes both bare and non-bare repositories with proper storage and worktree setup.

Example

ExampleInit demonstrates how to initialize a new git repository.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Create filesystem
	fs := billyfs.NewInMemoryFS()

	// Initialize repository
	repo, err := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})
	if err != nil {
		log.Fatal(err)
	}

	// Create a file
	err = fs.WriteFile("README.md", []byte("# My Project\n"), 0o644)
	if err != nil {
		log.Fatal(err)
	}

	// Stage and commit
	err = repo.Add(context.Background(), "README.md")
	if err != nil {
		log.Fatal(err)
	}

	sha, err := repo.Commit(context.Background(), "Initial commit", git.Signature{
		Name:  "Example User",
		Email: "user@example.com",
	}, git.CommitOpts{})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Created commit: %s\n", sha[:7])
}

func Open

func Open(ctx context.Context, opts *Options) (*Repo, error)

Open discovers and opens an existing git repository. The repository must already exist at the specified workdir within the filesystem. For non-bare repositories, both .git directory and worktree must be present. For bare repositories, only the .git directory structure is expected.

Context timeout/cancellation is honored during repository validation.

Example

ExampleOpen demonstrates how to open an existing repository.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Open repository from filesystem
	fs := billyfs.NewOSFS("/path/to/repo")

	repo, err := git.Open(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})
	if err != nil {
		log.Fatal(err)
	}

	// Get current branch
	branch, err := repo.CurrentBranch(context.Background())
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Current branch: %s\n", branch)
}

func (*Repo) Add

func (r *Repo) Add(ctx context.Context, paths ...string) error

Add stages files in the worktree for the next commit. It supports glob patterns and handles missing files appropriately. Files that don't exist are silently ignored (matching git add behavior).

Context timeout/cancellation is honored during the operation.

func (*Repo) CheckoutBranch

func (r *Repo) CheckoutBranch(ctx context.Context, name string, createIfMissing, force bool) error

CheckoutBranch switches to the specified branch. If createIfMissing is true, it creates the branch if it doesn't exist. If force is true, it discards any uncommitted changes in the working tree.

Context timeout/cancellation is honored during the operation.

func (*Repo) CheckoutRemoteBranch

func (r *Repo) CheckoutRemoteBranch(ctx context.Context, remote, remoteBranch, localName string, track bool) error

CheckoutRemoteBranch creates a local branch from a remote branch and optionally sets up tracking. If localName is empty, it uses the same name as the remote branch.

Context timeout/cancellation is honored during the operation.

func (*Repo) Commit

func (r *Repo) Commit(ctx context.Context, msg string, who Signature, opts CommitOpts) (string, error)

Commit creates a new commit with the specified message and author/committer. It returns the SHA of the new commit. The CommitOpts can be used to control commit behavior such as allowing empty commits.

Context timeout/cancellation is honored during the operation.

Example

ExampleRepo_Commit demonstrates staging files and creating commits.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Setup repository
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	ctx := context.Background()

	// Create some files
	_ = fs.WriteFile("main.go", []byte("package main\n"), 0o644)
	_ = fs.WriteFile("README.md", []byte("# Project\n"), 0o644)

	// Stage specific files
	err := repo.Add(ctx, "main.go", "README.md")
	if err != nil {
		log.Fatal(err)
	}

	// Create commit with signature
	sha, err := repo.Commit(ctx, "feat: initial implementation", git.Signature{
		Name:  "Jane Doe",
		Email: "jane@example.com",
	}, git.CommitOpts{
		// Options like AllowEmpty can be set here
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Commit created: %s\n", sha[:7])
}

func (*Repo) CreateBranch

func (r *Repo) CreateBranch(ctx context.Context, name, startRev string, trackRemote, force bool) error

CreateBranch creates a new branch from the specified revision. It supports creating branches from any valid revision (commit hash, branch name, tag, etc.). If trackRemote is true, it sets up remote tracking configuration. If force is true, it overwrites any existing branch with the same name.

Context timeout/cancellation is honored during the operation.

Example

ExampleRepo_CreateBranch demonstrates branch creation and checkout.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Assume repo is already initialized
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	ctx := context.Background()

	// Create an initial commit so HEAD resolves
	_ = fs.WriteFile("init.txt", []byte("init"), 0o644)
	_ = repo.Add(ctx, "init.txt")
	_, _ = repo.Commit(ctx, "Initial", git.Signature{Name: "Example", Email: "ex@example.com"}, git.CommitOpts{})

	// Create a new branch from HEAD
	err := repo.CreateBranch(ctx, "feature/new-feature", "HEAD", false, false)
	if err != nil {
		log.Fatal(err)
	}

	// Checkout the new branch
	err = repo.CheckoutBranch(ctx, "feature/new-feature", false, false)
	if err != nil {
		log.Fatal(err)
	}

	// Verify current branch
	branch, err := repo.CurrentBranch(ctx)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Switched to branch: %s\n", branch)
}
Output:
Switched to branch: feature/new-feature

func (*Repo) CreateTag

func (r *Repo) CreateTag(ctx context.Context, name, target, message string, annotated bool) error

CreateTag creates a new tag at the specified target revision. If message is provided and annotated is true, an annotated tag is created. If message is empty or annotated is false, a lightweight tag is created. The target can be any valid revision specifier (commit hash, branch name, etc.).

Context timeout/cancellation is honored during the operation.

func (*Repo) CurrentBranch

func (r *Repo) CurrentBranch(ctx context.Context) (string, error)

CurrentBranch returns the name of the currently checked out branch. It returns an error if HEAD is in a detached state.

Context timeout/cancellation is honored during the operation.

func (*Repo) DeleteBranch

func (r *Repo) DeleteBranch(ctx context.Context, name string) error

DeleteBranch deletes the specified local branch. It prevents deletion of the currently checked out branch.

Context timeout/cancellation is honored during the operation.

func (*Repo) DeleteTag

func (r *Repo) DeleteTag(ctx context.Context, name string) error

DeleteTag deletes the specified tag from the repository. Returns ErrTagMissing if the tag does not exist.

Context timeout/cancellation is honored during the operation.

func (*Repo) Diff

func (r *Repo) Diff(ctx context.Context, a, b string, filters ...ChangeFilter) (*PatchText, error)

Diff computes the diff between two revisions and returns unified diff text. The revisions 'a' and 'b' can be any valid git revision specifiers (commit hashes, branch names, tags, etc.).

Filters are applied progressively - a change must pass ALL filters to be included. If no filters are provided, all changes are included.

The method handles binary files appropriately by detecting them and marking the result accordingly. The returned PatchText contains the unified diff text that can be displayed to users or processed by other tools.

Context timeout/cancellation is honored during the operation.

Example

ExampleRepo_Diff demonstrates computing diffs between revisions.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Setup repository with changes
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	ctx := context.Background()

	// Initial commit
	_ = fs.WriteFile("file.txt", []byte("Line 1\n"), 0o644)
	_ = repo.Add(ctx, "file.txt")
	_, _ = repo.Commit(ctx, "Initial", git.Signature{
		Name:  "Test",
		Email: "test@example.com",
	}, git.CommitOpts{})

	// Make changes
	_ = fs.WriteFile("file.txt", []byte("Line 1\nLine 2\n"), 0o644)
	_ = repo.Add(ctx, "file.txt")
	_, _ = repo.Commit(ctx, "Add line", git.Signature{
		Name:  "Test",
		Email: "test@example.com",
	}, git.CommitOpts{})

	// Compute diff
	diff, err := repo.Diff(ctx, "HEAD~1", "HEAD", nil)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Files changed: %d\n", diff.FileCount)
	fmt.Printf("Contains binary: %v\n", diff.IsBinary)
	// The diff text contains the unified diff output
	// fmt.Println(diff.Text)
	

func (*Repo) Fetch

func (r *Repo) Fetch(ctx context.Context, remote string, prune bool, depth int) error

Fetch fetches changes from the specified remote. It supports pruning stale remote branches and shallow fetching when depth > 0. Returns ErrAlreadyUpToDate if there are no changes to fetch.

Context timeout/cancellation is honored during the fetch operation.

Example

ExampleRepo_Fetch demonstrates fetching from a remote repository.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Assume repo with remote configured
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	ctx := context.Background()

	// Fetch from remote with pruning
	err := repo.Fetch(ctx, "origin", true, 0)
	if err != nil {
		if errors.Is(err, git.ErrAlreadyUpToDate) {
			fmt.Println("Already up to date")
		} else {
			log.Fatal(err)
		}
	}

	// Fetch with shallow depth for large repos
	err = repo.Fetch(ctx, "origin", false, 10)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Fetch completed")
}

func (*Repo) FetchAndMerge

func (r *Repo) FetchAndMerge(ctx context.Context, remote, fromRef string, strategy MergeStrategy) error

FetchAndMerge fetches changes from the specified remote and merges the fromRef. It supports different merge strategies as specified by the strategy parameter. Currently, only FastForwardOnly is supported by go-git.

Context timeout/cancellation is honored during the operation.

func (*Repo) Log

func (r *Repo) Log(ctx context.Context, f LogFilter) (*CommitIter, error)

Log returns a commit iterator for the repository with the specified filters applied. The LogFilter can be used to limit results by time range, author, paths, or maximum count. The returned CommitIter should be closed when no longer needed to free resources.

Context timeout/cancellation is honored during the operation.

Example

ExampleRepo_Log demonstrates querying commit history.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/go-git/go-git/v5/plumbing/object"
	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Assume repo with history exists
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	// Create some commits for the example
	for i := 0; i < 5; i++ {
		_ = fs.WriteFile(fmt.Sprintf("file%d.txt", i), []byte("content"), 0o644)
		_ = repo.Add(context.Background(), ".")
		_, _ = repo.Commit(context.Background(), fmt.Sprintf("Commit %d", i), git.Signature{
			Name:  "Test",
			Email: "test@example.com",
		}, git.CommitOpts{})
	}

	ctx := context.Background()

	// Query commit history with filters
	iter, err := repo.Log(ctx, git.LogFilter{
		MaxCount: 3,      // Limit to 3 commits
		Author:   "Test", // Filter by author
	})
	if err != nil {
		log.Fatal(err)
	}
	defer iter.Close()

	// Iterate through commits
	count := 0
	_ = iter.ForEach(func(c *object.Commit) error {
		fmt.Printf("%d. %s\n", count+1, c.Message)
		count++
		return nil
	})

}
Output:
1. Commit 4
2. Commit 3
3. Commit 2

func (*Repo) PullFFOnly

func (r *Repo) PullFFOnly(ctx context.Context, remote string) error

PullFFOnly performs a fast-forward only pull from the specified remote. It fetches changes and updates the current branch only if it's a fast-forward merge. Returns ErrNotFastForward if a merge commit would be required. Returns ErrAlreadyUpToDate if there are no changes to pull.

Context timeout/cancellation is honored during the pull operation.

func (*Repo) Push

func (r *Repo) Push(ctx context.Context, remote string, force bool) error

Push pushes the current branch to the specified remote. It supports force pushing when force is true. Returns ErrNotFastForward if the push would overwrite remote changes and force is false. Returns ErrAlreadyUpToDate if there are no changes to push.

Context timeout/cancellation is honored during the push operation.

Example

ExampleRepo_Push demonstrates pushing changes to a remote.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Assume repo with commits and remote configured
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
		// Auth: myAuthProvider, // Provide AuthProvider implementation
	})

	ctx := context.Background()

	// Push current branch to origin
	err := repo.Push(ctx, "origin", false)
	if err != nil {
		switch {
		case errors.Is(err, git.ErrNotFastForward):
			fmt.Println("Push rejected: not a fast-forward")
			// Could try with force: repo.Push(ctx, "origin", true)
		case errors.Is(err, git.ErrAuthRequired):
			fmt.Println("Authentication required")
		default:
			log.Fatal(err)
		}
	}

	fmt.Println("Push successful")
}

func (*Repo) Refs

func (r *Repo) Refs(ctx context.Context, kind RefKind, pattern string) ([]string, error)

Refs returns a list of references that match the specified kind and pattern. The kind parameter filters references by type (branch, remote branch, tag, etc.). The pattern parameter supports glob-style matching with * and ? wildcards. Results are sorted alphabetically.

Context timeout/cancellation is honored during the operation.

func (*Repo) Remove

func (r *Repo) Remove(ctx context.Context, paths ...string) error

Remove removes files from the index and worktree. It handles already-deleted files appropriately and supports glob patterns. Files that don't exist in the index are silently ignored.

Context timeout/cancellation is honored during the operation.

func (*Repo) Resolve

func (r *Repo) Resolve(ctx context.Context, rev string) (*ResolvedRef, error)

Resolve resolves a revision specification to a ResolvedRef containing the kind and hash. The revision can be any valid git revision syntax (commit hash, branch name, tag, HEAD, etc.). Returns a ResolvedRef with the reference kind, resolved hash, and canonical name.

Context timeout/cancellation is honored during the operation.

func (*Repo) Tags

func (r *Repo) Tags(ctx context.Context, filters ...TagFilter) ([]string, error)

Tags returns a list of tags that pass all the provided filters. If no filters are provided, all tags are returned. Filters are applied progressively - a tag must pass ALL filters to be included. Results are sorted alphabetically.

Context timeout/cancellation is honored during the operation.

Example

ExampleRepo_Tags demonstrates tag management.

package main

import (
	"context"
	"fmt"
	"log"

	billyfs "github.com/input-output-hk/catalyst-forge-libs/fs/billy"

	"github.com/input-output-hk/catalyst-forge-libs/git"
)

func main() {
	// Setup repository
	fs := billyfs.NewInMemoryFS()
	repo, _ := git.Init(context.Background(), &git.Options{
		FS:      fs,
		Workdir: ".",
	})

	ctx := context.Background()

	// Create initial commit
	_ = fs.WriteFile("version", []byte("1.0.0"), 0o644)
	_ = repo.Add(ctx, "version")
	sha, _ := repo.Commit(ctx, "Initial version", git.Signature{
		Name:  "Test",
		Email: "test@example.com",
	}, git.CommitOpts{})

	// Create annotated tag
	err := repo.CreateTag(ctx, "v1.0.0", sha, "Release version 1.0.0", true)
	if err != nil {
		log.Fatal(err)
	}

	// Create lightweight tag
	err = repo.CreateTag(ctx, "latest", "HEAD", "", false)
	if err != nil {
		log.Fatal(err)
	}

	// List all tags
	tags, err := repo.Tags(ctx)
	if err != nil {
		log.Fatal(err)
	}

	for _, tag := range tags {
		fmt.Printf("Tag: %s\n", tag)
	}
}
Output:
Tag: latest
Tag: v1.0.0

func (*Repo) Unstage

func (r *Repo) Unstage(ctx context.Context, paths ...string) error

Unstage unstages files from the index without modifying the worktree. It uses Reset (mixed) to reset the index to HEAD for specified paths. Files that aren't staged are silently ignored.

Context timeout/cancellation is honored during the operation.

type ResolvedRef

type ResolvedRef struct {
	// Kind indicates the type of reference (branch, tag, commit, etc.).
	Kind RefKind

	// Hash is the resolved commit hash in full SHA-1 format.
	Hash string

	// CanonicalName is the canonical reference name (e.g., "refs/heads/main").
	// For commit hashes, this may be the same as Hash.
	CanonicalName string
}

ResolvedRef represents a resolved reference with its kind and hash. This is returned when resolving revision specifiers like branch names, tags, or commit SHAs.

type Signature

type Signature struct {
	// Name is the author's or committer's name.
	Name string

	// Email is the author's or committer's email address.
	Email string

	// When is the timestamp for the signature.
	When time.Time
}

Signature represents an author/committer signature for commits and tags. This is used when creating commits and annotated tags to identify the author.

type TagFilter

type TagFilter func(name string, ref *plumbing.Reference) bool

TagFilter is a predicate function for filtering tags. It returns true if the tag should be included in the results. Filters are applied progressively - if any filter returns false, the tag is excluded.

func TagExcludeFilter

func TagExcludeFilter(pattern string) TagFilter

TagExcludeFilter returns a filter that excludes tags matching the given pattern. This is useful for filtering out certain tags while keeping all others. For example: TagExcludeFilter("*-rc") excludes all release candidates.

func TagPatternFilter

func TagPatternFilter(pattern string) TagFilter

TagPatternFilter returns a filter that matches tags against a glob pattern. Supports * (matches any number of characters) and ? (matches single character). For example: "v1.*" matches "v1.0", "v1.1", etc.

func TagPrefixFilter

func TagPrefixFilter(prefix string) TagFilter

TagPrefixFilter returns a filter that matches tags with the given prefix. For example: "v" matches "v1.0", "v2.0", etc.

func TagSuffixFilter

func TagSuffixFilter(suffix string) TagFilter

TagSuffixFilter returns a filter that matches tags with the given suffix. For example: "-rc" matches "v1.0-rc", "v2.0-rc", etc.

Directories

Path Synopsis
internal
auth
Package auth provides composite authentication provider implementation.
Package auth provides composite authentication provider implementation.
diff
Package diff provides utilities for analyzing diff output.
Package diff provides utilities for analyzing diff output.
fsbridge
Package fsbridge provides adapters between fs.Filesystem and billy.Filesystem.
Package fsbridge provides adapters between fs.Filesystem and billy.Filesystem.
refs
Package refs provides reference normalization and filtering utilities.
Package refs provides reference normalization and filtering utilities.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL