{"id":47871520,"url":"https://github.com/just-sultanov/xfeat","last_synced_at":"2026-04-07T00:01:18.831Z","repository":{"id":348587136,"uuid":"1197803659","full_name":"just-sultanov/xfeat","owner":"just-sultanov","description":"CLI utility for managing git worktrees across multiple repositories","archived":false,"fork":false,"pushed_at":"2026-04-03T20:16:01.000Z","size":146,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T00:53:36.868Z","etag":null,"topics":["cli","devtools","git","git-worktree","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/just-sultanov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-31T22:45:01.000Z","updated_at":"2026-04-03T21:59:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/just-sultanov/xfeat","commit_stats":null,"previous_names":["just-sultanov/xfeat"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/just-sultanov/xfeat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just-sultanov%2Fxfeat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just-sultanov%2Fxfeat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just-sultanov%2Fxfeat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just-sultanov%2Fxfeat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/just-sultanov","download_url":"https://codeload.github.com/just-sultanov/xfeat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just-sultanov%2Fxfeat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31494177,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","devtools","git","git-worktree","rust"],"created_at":"2026-04-04T00:53:34.404Z","updated_at":"2026-04-07T00:01:18.818Z","avatar_url":"https://github.com/just-sultanov.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xfeat\n\nCLI utility for managing git worktrees across multiple repositories.\n\n## Rationale\n\nWhy? I work on several large products simultaneously.\nIn total, that's 90+ repositories, and a feature often touches multiple products at once.\nThis used to be a pain: constant branch switching, stashing, and a mess of open folders.\n\n`xfeat` fixes this — each feature gets its own isolated workspace via git worktrees.\nNo context switching. No stashing. Perfect for parallel work with AI coding agents.\n\n## Overview\n\n`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.\n\nBy 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.\n\n## Installation\n\n```bash\n# via mise\nmise install github:just-sultanov/xfeat\n\n# via cargo\ncargo install xfeat  # soon\n```\n\n## Quick Start\n\nSet up your project workspace and start developing features in parallel:\n\n```bash\ncd ~/projects/store\nexport XF_REPOS_DIR=~/projects/store/repos\nexport XF_FEATURES_DIR=~/projects/store/features\n```\n\n```\n~/projects/store/\n├── repos/\n│   ├── payment-service/\n│   ├── checkout-api/\n│   └── frontend/\n└── features/           # empty\n```\n\n**1. Create a new feature and add worktrees:**\n\n```bash\nxf new checkout-v2\nxf add checkout-v2 payment-service checkout-api\n```\n\n```\n~/projects/store/\n├── repos/\n│   ├── payment-service/\n│   ├── checkout-api/\n│   └── frontend/\n└── features/\n    └── checkout-v2/\n        ├── payment-service/  # worktree on branch checkout-v2\n        └── checkout-api/     # worktree on branch checkout-v2\n```\n\n**2. Work on your feature** — each worktree is a fully independent git checkout:\n\n```bash\nxf switch checkout-v2\ncd payment-service\n# make changes, commit, push — no stashing, no branch switching\n```\n\n**3. Stay in sync with main:**\n\n```bash\nxf sync checkout-v2\n```\n\n**4. List all active features:**\n\n```bash\nxf list\n```\n\n```\n├── checkout-v2\n│   ├── payment-service (checkout-v2)\n│   └── checkout-api (checkout-v2)\n└── payment-refactor (empty)\n```\n\n**5. Done? Clean up:**\n\n```bash\nxf remove checkout-v2\n```\n\nEach feature gets its own git worktrees, so you can switch between projects and features instantly without stashing or switching branches.\n\n## Workflows\n\n### AI-assisted development\n\nRun 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:\n\n```bash\n# Start two features in parallel\nxf new ai-payment-fix\nxf add ai-payment-fix payment-service --from develop\n\nxf new ai-checkout-v3\nxf add ai-checkout-v3 checkout-api frontend --from develop\n```\n\nNow launch AI agents in separate terminals:\n\n```bash\n# Terminal 1 — Claude Code working on payment fix\nxf switch ai-payment-fix\ncd payment-service\nclaude\n\n# Terminal 2 — Codex working on checkout redesign\nxf switch ai-checkout-v3\ncd checkout-api\ncodex\n```\n\nBoth agents work independently on their own branches. Before merging, sync each feature with the latest `main`:\n\n```bash\nxf sync ai-payment-fix\nxf sync ai-checkout-v3\n```\n\n### Multiple projects \u0026 features simultaneously\n\nSwitch between projects and juggle multiple features without losing context:\n\n```bash\n# Project A — e-commerce\ncd ~/projects/store\nexport XF_REPOS_DIR=~/projects/store/repos\nexport XF_FEATURES_DIR=~/projects/store/features\n\nxf new checkout-v2\nxf add checkout-v2 payment-service checkout-api\n\n# Project B — analytics dashboard\ncd ~/projects/analytics\nexport XF_REPOS_DIR=~/projects/analytics/repos\nexport XF_FEATURES_DIR=~/projects/analytics/features\n\nxf new dashboard-redesign\nxf add dashboard-redesign frontend backend\n```\n\nUse `xf switch` to jump between features instantly:\n\n```bash\nxf switch checkout-v2        # cd to features/checkout-v2\n# work on checkout...\n\nxf switch dashboard-redesign # cd to features/dashboard-redesign (in analytics project)\n# work on dashboard...\n```\n\nView everything at a glance:\n\n```bash\nxf list\n```\n\n```\n├── checkout-v2\n│   ├── payment-service (checkout-v2)\n│   └── checkout-api (checkout-v2)\n├── payment-refactor\n│   └── payment-service (payment-refactor)\n└── dashboard-redesign\n    ├── frontend (dashboard-redesign)\n    └── backend (dashboard-redesign)\n```\n\n\u003e **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:\n\u003e\n\u003e ```bash\n\u003e export XF_REPOS_DIR=~/projects/store/repos\n\u003e export XF_FEATURES_DIR=~/projects/store/features\n\u003e ```\n\n## Commands\n\n### `xfeat new`\n\nCreate a new empty feature directory:\n\n```bash\nxf new \u003cfeature-name\u003e\n```\n\n**Example:**\n\n```bash\nxf new JIRA-123-fix-issue\n```\n\nThis creates an empty directory. Add worktrees with `xf add`:\n\n```bash\nxf add JIRA-123-fix-issue service-1 service-2 lib-1\n```\n\n### `xfeat add`\n\nAdd worktrees for repositories to an existing feature:\n\n```bash\nxf add \u003cfeature-name\u003e \u003crepos...\u003e\nxf add \u003cfeature-name\u003e \u003crepos...\u003e --from \u003cbranch\u003e\nxf add \u003cfeature-name\u003e \u003crepos...\u003e --branch \u003cbranch-name\u003e\nxf add \u003cfeature-name\u003e \u003crepos...\u003e --from \u003cbranch\u003e --branch \u003cbranch-name\u003e\n```\n\n**Examples:**\n\n```bash\n# Add repos — branches named after the feature\nxf add JIRA-123 payment-service checkout-api\n\n# Add repos, branching from a specific source branch\nxf add JIRA-123 payment-service --from develop\n\n# Add repos with a custom branch name\nxf add JIRA-123 payment-service --branch bugfix/JIRA-123\n\n# Combine: branch from 'develop' with a custom name\nxf add JIRA-123 payment-service --from develop --branch bugfix/JIRA-123\n```\n\nSkips repositories that already have worktrees in the feature.\n\n### `xfeat list`\n\nList all features with their worktrees and current branches:\n\n```bash\nxf list\n```\n\n**Example output:**\n\n```\n├── JIRA-123\n│   ├── service-1 (JIRA-123)\n│   └── service-2 (JIRA-123)\n├── JIRA-456\n│   └── service-1 (JIRA-456)\n└── JIRA-789 (empty)\n```\n\nEmpty features (created with `xf new` but without worktrees yet) are shown with `(empty)`.\n\n### `xfeat sync`\n\nSync a feature with the latest main branch from source repos:\n\n```bash\nxf sync \u003cfeature-name\u003e\n```\n\nFor each worktree in the feature:\n\n1. Fetches latest changes from remote\n2. Rebases the feature branch onto `origin/main` (auto-detected)\n3. Stops on first conflict with an error message\n\n**Example:**\n\n```bash\nxf sync JIRA-123-fix-issue\n```\n\n**Typical workflow before merging:**\n\n```bash\nxf sync JIRA-123-fix-issue   # rebase onto latest main\n# resolve any conflicts if needed\nxf sync JIRA-123-fix-issue   # verify clean sync\n# merge or create PR\n```\n\n### `xfeat remove`\n\nRemove a feature and its worktrees. Prompts for confirmation by default:\n\n```bash\nxf remove \u003cfeature-name\u003e\nxf remove \u003cfeature-name\u003e --yes   # skip confirmation (for scripts)\n```\n\n**Example output:**\n\n```\nFeature 'JIRA-123' contains:\n  - service-1 (JIRA-123)\n  - service-2 (JIRA-123) ⚠ has uncommitted changes\n\nRemove feature 'JIRA-123'? [y/N] y\nFeature 'JIRA-123' removed.\n```\n\n### `xfeat init`\n\nGenerate shell initialization code with autocompletion and `xf` wrapper function:\n\n```bash\neval \"$(xfeat init zsh)\"\n```\n\n**Supported shells:** `zsh`\n\nThe `xf` wrapper:\n\n- `xf new \u003cfeature\u003e` — creates an empty feature directory\n- `xf add \u003cfeature\u003e \u003crepos...\u003e` — adds worktrees to a feature\n- `xf switch \u003cfeature\u003e` — `cd` into a feature directory\n- `xf remove \u003cfeature\u003e` — removes feature (with confirmation) and `cd`s out if needed\n- `xf sync \u003cfeature\u003e` — syncs feature with main\n- `xf list` and other commands — proxied to `xfeat`\n- Tab completion for repository names (`xf add \u003cTAB\u003e`), feature names (`xf new \u003cTAB\u003e`, `xf remove \u003cTAB\u003e`, `xf sync \u003cTAB\u003e`, `xf switch \u003cTAB\u003e`)\n\nShell 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.\n\n## Configuration\n\nSet environment variables per-project:\n\n```bash\nexport XF_REPOS_DIR=~/projects/project-x/repos\nexport XF_FEATURES_DIR=~/projects/project-x/features\n```\n\n| Variable          | Description                                   | Default                |\n| ----------------- | --------------------------------------------- | ---------------------- |\n| `XF_REPOS_DIR`    | Directory containing source git repositories  | `~/workspace/repos`    |\n| `XF_FEATURES_DIR` | Directory where feature worktrees are created | `~/workspace/features` |\n\nPaths can be absolute (`/tmp/repos`), relative (`./repos`), or tilde-based (`~/repos`). All are resolved correctly.\n\n## License\n\nMIT — see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjust-sultanov%2Fxfeat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjust-sultanov%2Fxfeat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjust-sultanov%2Fxfeat/lists"}