etz 0.1.0

CLI for coordinating git worktrees across multi-repo parent directories.
Documentation

etz

etz is a CLI for managing multi-repo workspaces where the parent folder is not a git repo and each direct child folder is an independent git repo.

It creates coordinated git worktrees under:

  • parent/.etz/workspaces/<workspace>/<repo>

Commands

  • etz init
  • etz add <workspace> --branch <branch> [--no-copy-root]
  • etz list
  • etz refresh [--check] [--json]
  • etz status [workspace] [--changed] [--summary] [--json]
  • etz commit [workspace] -m "msg" [--all] [--dry-run] [--json]
  • etz push [workspace] [--dry-run] [--json]
  • etz remove <workspace> [--force]
  • etz prune
  • etz doctor [--fix] [--json]

Behavior Highlights

  • Repo discovery is direct children only.
  • Missing branch on add is auto-created from each repo's detected default branch.
  • refresh re-discovers direct-child repos and updates the manifest lock file.
  • refresh --check reports drift and exits non-zero without mutating files.
  • add copies non-repo files/directories from the parent root into the workspace root by default.
  • Use --no-copy-root to disable that copy behavior.
  • Optional .etzcopy and .etzignore patterns let you include/exclude root files copied into a workspace.
  • add and remove are fail-fast and attempt rollback on partial failures.
  • If you run etz from inside .etz/workspaces/<workspace>/..., status, commit, and push infer the workspace automatically.
  • status includes per-repo staged/unstaged/untracked counts.
  • status --changed filters to changed repos; status --summary prints condensed totals.
  • commit works across repos in one workspace:
    • default: commits only repos with staged changes
    • smart fallback: if nothing is staged but tracked files changed, it auto-stages tracked changes (git add -u) and commits
    • --all: stages all tracked + untracked changes (git add -A) first
    • --dry-run: shows what would be committed and what would be auto-staged, without changing any repo
    • on failure in later repos, previously created commits from this run are rolled back with git reset --soft HEAD~1
  • push pushes repos that are ahead of upstream; --dry-run previews push candidates.
  • doctor --fix can prune stale workspace state entries and attempt branch realignment where safe.
  • State is persisted in:
    • .etz/config.toml
    • .etz/manifest.lock.toml
    • .etz/state.toml

Quick Start

# inside parent folder that contains git child repos
etz init
etz add feat-auth --branch feat-auth
etz status feat-auth

# after making/staging changes
etz commit feat-auth -m "feat: implement auth flow"

# cleanup
etz remove feat-auth

Publishing (crates.io + Homebrew)

Tagged releases are automated by .github/workflows/release.yml.

One-time setup

  1. Create a crates.io API token with publish scope and add it to repo secrets as CARGO_REGISTRY_TOKEN.
  2. Create a GitHub token that can push to snipeship/homebrew-tap and add it as HOMEBREW_TAP_GITHUB_TOKEN.
  3. Ensure snipeship/homebrew-tap exists and contains a Formula/ directory.

Release flow

  1. Bump [package].version in Cargo.toml.
  2. Commit and push to main.
  3. Tag the commit with the same version prefixed by v (for example v0.2.0) and push the tag.
git tag v0.2.0
git push origin v0.2.0

The workflow will:

  • run tests
  • build etz binaries for Linux x86_64, macOS x86_64, and macOS arm64
  • create a GitHub Release with tarballs + SHA256SUMS
  • publish the crate to crates.io
  • update snipeship/homebrew-tap/Formula/etz.rb

After release, users can install with:

cargo install etz
brew install snipeship/tap/etz