https://github.com/just-sultanov/xfeat
CLI utility for managing git worktrees across multiple repositories
https://github.com/just-sultanov/xfeat
cli devtools git git-worktree rust
Last synced: about 2 months ago
JSON representation
CLI utility for managing git worktrees across multiple repositories
- Host: GitHub
- URL: https://github.com/just-sultanov/xfeat
- Owner: just-sultanov
- License: mit
- Created: 2026-03-31T22:45:01.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-03T20:16:01.000Z (about 2 months ago)
- Last Synced: 2026-04-04T00:53:36.868Z (about 2 months ago)
- Topics: cli, devtools, git, git-worktree, rust
- Language: Rust
- Homepage:
- Size: 143 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# xfeat
CLI utility for managing git worktrees across multiple repositories.
## Rationale
Why? I work on several large products simultaneously.
In total, that's 90+ repositories, and a feature often touches multiple products at once.
This used to be a pain: constant branch switching, stashing, and a mess of open folders.
`xfeat` fixes this — each feature gets its own isolated workspace via git worktrees.
No context switching. No stashing. Perfect for parallel work with AI coding agents.
## Overview
`xfeat` is designed for developers working on multiple projects simultaneously. Each project has its own workspace with `repos` (source repositories) and `features` (worktree branches) directories. Environment variables `XF_REPOS_DIR` and `XF_FEATURES_DIR` are scoped per-project, allowing isolated feature development across multiple repositories within a single project context.
By leveraging git worktrees, `xfeat` enables parallel development on multiple features without the overhead of cloning repositories or switching branches. Each feature gets its own isolated workspace, making it ideal for AI-assisted development where multiple coding agents can work on different features simultaneously without conflicts.
## Installation
```bash
# via mise
mise install github:just-sultanov/xfeat
# via cargo
cargo install xfeat # soon
```
## Quick Start
Set up your project workspace and start developing features in parallel:
```bash
cd ~/projects/store
export XF_REPOS_DIR=~/projects/store/repos
export XF_FEATURES_DIR=~/projects/store/features
```
```
~/projects/store/
├── repos/
│ ├── payment-service/
│ ├── checkout-api/
│ └── frontend/
└── features/ # empty
```
**1. Create a new feature and add worktrees:**
```bash
xf new checkout-v2
xf add checkout-v2 payment-service checkout-api
```
```
~/projects/store/
├── repos/
│ ├── payment-service/
│ ├── checkout-api/
│ └── frontend/
└── features/
└── checkout-v2/
├── payment-service/ # worktree on branch checkout-v2
└── checkout-api/ # worktree on branch checkout-v2
```
**2. Work on your feature** — each worktree is a fully independent git checkout:
```bash
xf switch checkout-v2
cd payment-service
# make changes, commit, push — no stashing, no branch switching
```
**3. Stay in sync with main:**
```bash
xf sync checkout-v2
```
**4. List all active features:**
```bash
xf list
```
```
├── checkout-v2
│ ├── payment-service (checkout-v2)
│ └── checkout-api (checkout-v2)
└── payment-refactor (empty)
```
**5. Done? Clean up:**
```bash
xf remove checkout-v2
```
Each feature gets its own git worktrees, so you can switch between projects and features instantly without stashing or switching branches.
## Workflows
### AI-assisted development
Run multiple AI coding agents (Claude Code, Codex, Cursor, etc.) on different features simultaneously — each agent gets its own isolated workspace with no risk of conflicts:
```bash
# Start two features in parallel
xf new ai-payment-fix
xf add ai-payment-fix payment-service --from develop
xf new ai-checkout-v3
xf add ai-checkout-v3 checkout-api frontend --from develop
```
Now launch AI agents in separate terminals:
```bash
# Terminal 1 — Claude Code working on payment fix
xf switch ai-payment-fix
cd payment-service
claude
# Terminal 2 — Codex working on checkout redesign
xf switch ai-checkout-v3
cd checkout-api
codex
```
Both agents work independently on their own branches. Before merging, sync each feature with the latest `main`:
```bash
xf sync ai-payment-fix
xf sync ai-checkout-v3
```
### Multiple projects & features simultaneously
Switch between projects and juggle multiple features without losing context:
```bash
# Project A — e-commerce
cd ~/projects/store
export XF_REPOS_DIR=~/projects/store/repos
export XF_FEATURES_DIR=~/projects/store/features
xf new checkout-v2
xf add checkout-v2 payment-service checkout-api
# Project B — analytics dashboard
cd ~/projects/analytics
export XF_REPOS_DIR=~/projects/analytics/repos
export XF_FEATURES_DIR=~/projects/analytics/features
xf new dashboard-redesign
xf add dashboard-redesign frontend backend
```
Use `xf switch` to jump between features instantly:
```bash
xf switch checkout-v2 # cd to features/checkout-v2
# work on checkout...
xf switch dashboard-redesign # cd to features/dashboard-redesign (in analytics project)
# work on dashboard...
```
View everything at a glance:
```bash
xf list
```
```
├── checkout-v2
│ ├── payment-service (checkout-v2)
│ └── checkout-api (checkout-v2)
├── payment-refactor
│ └── payment-service (payment-refactor)
└── dashboard-redesign
├── frontend (dashboard-redesign)
└── backend (dashboard-redesign)
```
> **Tip:** Use `direnv` or `mise env` to automatically set `XF_REPOS_DIR` and `XF_FEATURES_DIR` when entering a project directory. Add an `.envrc` file:
>
> ```bash
> export XF_REPOS_DIR=~/projects/store/repos
> export XF_FEATURES_DIR=~/projects/store/features
> ```
## Commands
### `xfeat new`
Create a new empty feature directory:
```bash
xf new
```
**Example:**
```bash
xf new JIRA-123-fix-issue
```
This creates an empty directory. Add worktrees with `xf add`:
```bash
xf add JIRA-123-fix-issue service-1 service-2 lib-1
```
### `xfeat add`
Add worktrees for repositories to an existing feature:
```bash
xf add
xf add --from
xf add --branch
xf add --from --branch
```
**Examples:**
```bash
# Add repos — branches named after the feature
xf add JIRA-123 payment-service checkout-api
# Add repos, branching from a specific source branch
xf add JIRA-123 payment-service --from develop
# Add repos with a custom branch name
xf add JIRA-123 payment-service --branch bugfix/JIRA-123
# Combine: branch from 'develop' with a custom name
xf add JIRA-123 payment-service --from develop --branch bugfix/JIRA-123
```
Skips repositories that already have worktrees in the feature.
### `xfeat list`
List all features with their worktrees and current branches:
```bash
xf list
```
**Example output:**
```
├── JIRA-123
│ ├── service-1 (JIRA-123)
│ └── service-2 (JIRA-123)
├── JIRA-456
│ └── service-1 (JIRA-456)
└── JIRA-789 (empty)
```
Empty features (created with `xf new` but without worktrees yet) are shown with `(empty)`.
### `xfeat sync`
Sync a feature with the latest main branch from source repos:
```bash
xf sync
```
For each worktree in the feature:
1. Fetches latest changes from remote
2. Rebases the feature branch onto `origin/main` (auto-detected)
3. Stops on first conflict with an error message
**Example:**
```bash
xf sync JIRA-123-fix-issue
```
**Typical workflow before merging:**
```bash
xf sync JIRA-123-fix-issue # rebase onto latest main
# resolve any conflicts if needed
xf sync JIRA-123-fix-issue # verify clean sync
# merge or create PR
```
### `xfeat remove`
Remove a feature and its worktrees. Prompts for confirmation by default:
```bash
xf remove
xf remove --yes # skip confirmation (for scripts)
```
**Example output:**
```
Feature 'JIRA-123' contains:
- service-1 (JIRA-123)
- service-2 (JIRA-123) ⚠ has uncommitted changes
Remove feature 'JIRA-123'? [y/N] y
Feature 'JIRA-123' removed.
```
### `xfeat init`
Generate shell initialization code with autocompletion and `xf` wrapper function:
```bash
eval "$(xfeat init zsh)"
```
**Supported shells:** `zsh`
The `xf` wrapper:
- `xf new ` — creates an empty feature directory
- `xf add ` — adds worktrees to a feature
- `xf switch ` — `cd` into a feature directory
- `xf remove ` — removes feature (with confirmation) and `cd`s out if needed
- `xf sync ` — syncs feature with main
- `xf list` and other commands — proxied to `xfeat`
- Tab completion for repository names (`xf add `), feature names (`xf new `, `xf remove `, `xf sync `, `xf switch `)
Shell scripts are stored in `shell/` and embedded into the binary at compile time. They read `XF_REPOS_DIR` and `XF_FEATURES_DIR` from the environment on each invocation, making them compatible with tools like `direnv`. Tilde (`~`) in paths is expanded automatically.
## Configuration
Set environment variables per-project:
```bash
export XF_REPOS_DIR=~/projects/project-x/repos
export XF_FEATURES_DIR=~/projects/project-x/features
```
| Variable | Description | Default |
| ----------------- | --------------------------------------------- | ---------------------- |
| `XF_REPOS_DIR` | Directory containing source git repositories | `~/workspace/repos` |
| `XF_FEATURES_DIR` | Directory where feature worktrees are created | `~/workspace/features` |
Paths can be absolute (`/tmp/repos`), relative (`./repos`), or tilde-based (`~/repos`). All are resolved correctly.
## License
MIT — see [LICENSE](LICENSE) for details.