wtdetach

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2026 License: BSD-2-Clause Imports: 6 Imported by: 0

README

git-wt-detach

A Git subcommand that temporarily detaches a branch checked out in another worktree, making it available for checkout in the current repository.

Overview

This tool works around Git's limitation that prevents the same branch from being checked out in multiple worktrees simultaneously.

Use Cases
  1. You want to checkout a branch in the main repository while preserving Bazel cache, but the branch is currently used in another worktree
  2. You need to temporarily move a branch between worktrees in a multi-worktree setup

Installation

go install github.com/Konboi/git-wt-detach/cmd/git-wt-detach@latest

Or build from source:

git clone https://github.com/Konboi/git-wt-detach.git
cd git-wt-detach
go build -o git-wt-detach ./cmd/git-wt-detach

# Place in your PATH
mv git-wt-detach /usr/local/bin/

Usage

Detach a branch
git wt-detach <branch>

When the specified branch is checked out in another worktree:

  1. Creates a temporary branch (<branch>__wt_detach)
  2. Switches the target worktree to the temporary branch
  3. Makes the original branch available for checkout
Revert the detach
git wt-detach <branch> --revert
  1. Switches the target worktree back to the original branch
  2. Deletes the temporary branch
Options
Option Description
--dry-run Show what would be done without making changes
--force Force execution even with uncommitted changes
--yes Skip confirmation prompt
--revert Revert the temporary detach
--checkout Checkout the branch after detaching
--init Output shell completion script (bash, zsh, fish)
--version Show version

Shell Integration

Enable tab completion for branch names:

Zsh:

eval "$(git-wt-detach --init zsh)"

Add to your ~/.zshrc for persistent completion.

Bash:

eval "$(git-wt-detach --init bash)"

Add to your ~/.bashrc for persistent completion.

Fish:

git-wt-detach --init fish | source

Add to your ~/.config/fish/config.fish for persistent completion.

Example

# feature-x is checked out in another worktree
$ git wt-detach feature-x
✔ Found worktree: ../repo-wt-feature
Branch 'feature-x' is currently checked out in:
  ../repo-wt-feature

It will be temporarily replaced by:
  feature-x__wt_detach

Proceed? [y/N] y
✔ Created temp branch: feature-x__wt_detach
✔ Switched worktree branch
✔ Branch detached: feature-x

# Now you can checkout feature-x in the current repository
$ git checkout feature-x

# Or use --checkout (-c) to detach and checkout in one step
$ git wt-detach feature-x -c
✔ Found worktree: ../repo-wt-feature
✔ Created temp branch: feature-x__wt_detach
✔ Switched worktree branch
✔ Branch detached: feature-x
✔ Checked out: feature-x

# When done, revert to original state
$ git wt-detach feature-x --revert
✔ Found worktree with temp branch: ../repo-wt-feature
✔ Switched worktree to: feature-x
✔ Deleted temp branch: feature-x__wt_detach
✔ Branch restored: feature-x

Configuration

Custom suffix for temporary branches

The default suffix is __wt_detach. You can change it via git config:

git config wt-detach.suffix "__tmp"

Safety Features

  • Fails if the target worktree has uncommitted changes (use --force to override)
    • Shows up to 10 uncommitted files in the error message
    • Shows "N files or more" when there are more than 10 uncommitted files
  • Fails if the temporary branch already exists
  • Use --dry-run to preview changes before execution

Requirements

  • Git 2.20+
  • Go 1.21+ (for building)

License

MIT

Documentation

Index

Constants

View Source
const (
	// DefaultSuffix is the default suffix for temporary branches
	DefaultSuffix = "__wt_detach"
)

Variables

This section is empty.

Functions

func CompletionScript added in v0.1.1

func CompletionScript(shell string) (string, error)

CompletionScript returns the shell completion script for the specified shell

Types

type CLI added in v0.1.1

type CLI struct {
	Branch   string           `arg:"" optional:"" help:"Branch name to detach or revert."`
	DryRun   bool             `help:"Show what would be done without making changes." short:"n"`
	Revert   bool             `help:"Revert the temporary detach." short:"r"`
	Force    bool             `help:"Force execution even with uncommitted changes." short:"f"`
	Yes      bool             `help:"Skip confirmation prompt." short:"y"`
	Checkout bool             `help:"Checkout the branch after detaching." short:"c"`
	Init     string           `help:"Output shell completion script (bash, zsh, fish)." placeholder:"SHELL"`
	Version  kong.VersionFlag `help:"Show version."`
}

CLI defines the command-line interface

func (*CLI) Run added in v0.1.1

func (c *CLI) Run() error

Run executes the CLI command

type Detacher

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

Detacher handles the detach/revert operations

func NewDetacher

func NewDetacher() *Detacher

NewDetacher creates a new Detacher

func (*Detacher) BranchExists

func (d *Detacher) BranchExists(branch string) bool

BranchExists checks if a branch exists

func (*Detacher) Checkout

func (d *Detacher) Checkout(worktreePath, branch string) error

Checkout checks out a branch in a worktree

func (*Detacher) CreateBranch

func (d *Detacher) CreateBranch(branch, worktreePath string) error

CreateBranch creates a new branch at the current HEAD of a worktree

func (*Detacher) DeleteBranch

func (d *Detacher) DeleteBranch(branch string) error

DeleteBranch deletes a branch

func (*Detacher) Detach

func (d *Detacher) Detach(branch string, opts *Options) (*Result, error)

Detach performs the detach operation

func (*Detacher) FindWorktreeForBranch

func (d *Detacher) FindWorktreeForBranch(branch string) (*Worktree, error)

FindWorktreeForBranch finds a worktree that has the specified branch checked out It excludes the current worktree

func (*Detacher) GetCurrentWorktreePath

func (d *Detacher) GetCurrentWorktreePath() (string, error)

GetCurrentWorktreePath returns the path of the current worktree

func (*Detacher) GetSuffix

func (d *Detacher) GetSuffix() string

GetSuffix returns the current suffix

func (*Detacher) GetUncommittedFiles added in v0.1.3

func (d *Detacher) GetUncommittedFiles(worktreePath string) []string

GetUncommittedFiles returns a list of uncommitted files in a worktree

func (*Detacher) HasUncommittedChanges

func (d *Detacher) HasUncommittedChanges(worktreePath string) bool

HasUncommittedChanges checks if a worktree has uncommitted changes

func (*Detacher) ListWorktrees

func (d *Detacher) ListWorktrees() ([]Worktree, error)

ListWorktrees returns a list of all worktrees

func (*Detacher) LoadSuffixFromConfig

func (d *Detacher) LoadSuffixFromConfig()

LoadSuffixFromConfig loads the suffix from git config

func (*Detacher) Revert

func (d *Detacher) Revert(branch string, opts *Options) (*Result, error)

Revert performs the revert operation

func (*Detacher) SetSuffix

func (d *Detacher) SetSuffix(suffix string)

SetSuffix sets the suffix for temporary branches

func (*Detacher) TempBranchName

func (d *Detacher) TempBranchName(branch string) string

TempBranchName returns the temporary branch name for a given branch

type Git

type Git struct{}

Git provides methods to execute git commands

func (*Git) Run

func (g *Git) Run(args ...string) (string, error)

Run executes a git command and returns the output

func (*Git) RunInDir

func (g *Git) RunInDir(dir string, args ...string) (string, error)

RunInDir executes a git command in a specific directory and returns the output

type Options

type Options struct {
	DryRun bool
	Revert bool
	Force  bool
	Yes    bool
}

Options holds the command options

type Result

type Result struct {
	Success      bool
	Message      string
	WorktreePath string
	TempBranch   string
}

Result represents the result of an operation

type Worktree

type Worktree struct {
	Path   string
	Branch string
}

Worktree represents a git worktree

func FindWorktreeByBranch

func FindWorktreeByBranch(worktrees []Worktree, branch, excludePath string) *Worktree

FindWorktreeByBranch finds a worktree that has the specified branch checked out It excludes the worktree at excludePath

func ParseWorktreeList

func ParseWorktreeList(output string) []Worktree

ParseWorktreeList parses the output of `git worktree list --porcelain`

Directories

Path Synopsis
cmd
git-wt-detach command

Jump to

Keyboard shortcuts

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