gitwork

package
v0.0.41 Latest Latest
Warning

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

Go to latest
Published: May 5, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package gitwork wraps the git-work CLI for worktree management.

This package provides a Go client for the git-work CLI tool, enabling programmatic management of git worktrees. It handles workspace discovery, worktree creation/removal, and parsing of git-work's JSON output.

git-work CLI Requirements

This package requires git-work to be installed and available in PATH. The git-work CLI must support:

  • list --format=json: Output worktree information as JSON to stderr
  • checkout -b <branch>: Create a new worktree for the branch (path to stdout)
  • rm --yes <branch>: Remove a worktree without confirmation

JSON Format

The git-work list --format=json command outputs JSON to stderr:

{
  "data": {
    "worktrees": [
      {"dir": "main", "branch": "main", "current": false}
    ]
  },
  "messages": [
    {"level": "info", "text": "  main  main\n"}
  ]
}

The "dir" field contains the directory name (not the full path). This package constructs the full path using filepath.Join(repoDir, dir). If git-work is updated to return absolute paths, the code handles that gracefully.

Workspace Discovery

A Substrate workspace is a directory containing a .substrate-workspace file (YAML with ULID, name, timestamp). Workspaces contain git-work repositories, identified by the presence of a .bare/ subdirectory.

Example Usage

client := gitwork.NewClient("")

// List worktrees
worktrees, err := client.List(ctx, repoDir)
if err != nil {
	// handle error
}

// Create a new worktree
path, err := client.Checkout(ctx, repoDir, "feature-branch")
if err != nil {
	// handle error
}

// Remove a worktree
err = client.Remove(ctx, repoDir, "feature-branch")
if err != nil {
	// handle error
}

Index

Constants

View Source
const (
	// WorkspaceFileName is the name of the workspace marker file.
	WorkspaceFileName = ".substrate-workspace"
)

Variables

View Source
var (
	// ErrNotInWorkspace is returned when no workspace file is found.
	ErrNotInWorkspace = errors.New("not in a substrate workspace")
	// ErrWorkspaceExists is returned when trying to initialize an existing workspace.
	ErrWorkspaceExists = errors.New("workspace already exists")
)

Functions

func DiscoverPlainRepos

func DiscoverPlainRepos(workspaceDir string) ([]string, error)

DiscoverPlainRepos scans the workspace directory for plain git repositories. A plain git repository has a .git entry but no .bare/ subdirectory.

func DiscoverRepos

func DiscoverRepos(workspaceDir string) ([]string, error)

DiscoverRepos scans the workspace directory for git-work repositories. A git-work repository is identified by the presence of a .bare/ subdirectory.

func IsGitWorkRepo

func IsGitWorkRepo(dir string) bool

IsGitWorkRepo checks if the given directory is a git-work repository by looking for a .bare subdirectory.

func IsNotInWorkspace

func IsNotInWorkspace(err error) bool

IsNotInWorkspace returns true if err is ErrNotInWorkspace.

func IsPlainGitRepo

func IsPlainGitRepo(dir string) bool

IsPlainGitRepo checks if the given directory is a plain git repository. Plain git repositories have a .git entry and do not yet use the git-work .bare layout.

func IsWorkspaceExists

func IsWorkspaceExists(err error) bool

IsWorkspaceExists returns true if err is ErrWorkspaceExists.

func ValidateWorkspaceID

func ValidateWorkspaceID(id string) error

ValidateWorkspaceID checks if the given string is a valid ULID.

func WriteWorkspaceFile

func WriteWorkspaceFile(dir string, ws *WorkspaceFile) error

WriteWorkspaceFile writes the workspace file to the given directory.

Types

type Client

type Client struct {
	// BinPath is the path to the git-work binary.
	// If empty, "git-work" is looked up in PATH.
	BinPath string
}

Client wraps the git-work CLI for worktree management.

func NewClient

func NewClient(binPath string) *Client

NewClient creates a new git-work client.

func (*Client) CheckInstalled

func (c *Client) CheckInstalled() error

CheckInstalled verifies that git-work is available in PATH or at BinPath.

func (*Client) Checkout

func (c *Client) Checkout(ctx context.Context, repoDir, branch string) (string, error)

Checkout creates a new worktree for the given branch and returns its path. The branch is created from the current HEAD if it doesn't exist. The worktree is created in a subdirectory named after the branch.

func (*Client) Clone

func (c *Client) Clone(ctx context.Context, parentDir, remoteURL string) (string, error)

Clone clones a remote repository into the workspace using git-work clone. It runs git-work clone <remoteURL> with cmd.Dir = parentDir. git-work clone creates <parentDir>/<repo-name>/.bare/ layout and a worktree for HEAD. It parses stdout for the directory path and validates the path is under parentDir. Returns the absolute path to the created repository root.

func (*Client) GetMainWorktree

func (c *Client) GetMainWorktree(ctx context.Context, repoDir string) (string, error)

GetMainWorktree returns the path to the main worktree for a repository.

func (*Client) Init

func (c *Client) Init(ctx context.Context, repoDir string) error

Init converts a plain git repository into the git-work layout.

func (*Client) List

func (c *Client) List(ctx context.Context, repoDir string) ([]Worktree, error)

Context cancellation is honored: if ctx is cancelled, the command will be terminated and an error returned. Partial JSON output on cancellation is handled by parseListJSON which returns an empty slice for empty input.

func (*Client) PullMainWorktree

func (c *Client) PullMainWorktree(ctx context.Context, repoDir string) (string, error)

PullMainWorktree runs git pull --ff-only in the main worktree of the given repo. It returns the output and any error. Unlike other methods, this does not wrap the error - the caller should handle it appropriately (as a warning, not a failure).

func (*Client) Remove

func (c *Client) Remove(ctx context.Context, repoDir, branch string) error

Remove deletes the worktree for the given branch.

func (*Client) Sync

func (c *Client) Sync(ctx context.Context, repoDir string) error

Sync synchronizes worktrees with remote state, pruning deleted branches.

type PullResult

type PullResult struct {
	RepoName string
	Success  bool
	Output   string
	Error    error
}

PullResult represents the result of pulling a single repo's main worktree.

type WorkspaceFile

type WorkspaceFile struct {
	// ID is a ULID identifying the workspace.
	ID string `yaml:"id"`
	// Name is a human-readable workspace name.
	Name string `yaml:"name"`
	// CreatedAt is the timestamp when the workspace was created.
	CreatedAt time.Time `yaml:"created_at"`
}

WorkspaceFile represents the content of .substrate-workspace file.

func FindWorkspace

func FindWorkspace(startDir string) (string, *WorkspaceFile, error)

FindWorkspace searches for a workspace file starting from the given directory and walking up the directory tree. Returns the workspace directory and file, or ErrNotInWorkspace if not found.

func InitWorkspace

func InitWorkspace(dir, name string) (*WorkspaceFile, error)

func ReadWorkspaceFile

func ReadWorkspaceFile(dir string) (*WorkspaceFile, error)

ReadWorkspaceFile reads the workspace file from the given directory. Returns ErrNotInWorkspace if no workspace file exists.

func ResolveWorkspacePath

func ResolveWorkspacePath(storedPath string) (string, *WorkspaceFile, error)

ResolveWorkspacePath attempts to read the workspace file from the given path and returns the absolute path. This is used for path reconciliation when a workspace directory may have been moved. Returns the absolute path, workspace file, and error if the workspace cannot be found.

type WorkspaceScan

type WorkspaceScan struct {
	GitWorkRepos  []string
	PlainGitRepos []string
}

WorkspaceScan classifies direct child directories in a workspace.

func ScanWorkspace

func ScanWorkspace(workspaceDir string) (WorkspaceScan, error)

ScanWorkspace scans the workspace directory for managed and plain git repositories.

type Worktree

type Worktree struct {
	// Path is the absolute path to the worktree directory.
	Path string
	// Branch is the branch name (without refs/heads/ prefix).
	Branch string
	// IsMain indicates whether this is the main worktree.
	IsMain bool
}

Worktree represents a git worktree entry.

Jump to

Keyboard shortcuts

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