{"id":44602644,"url":"https://github.com/mocyuto/zgt","last_synced_at":"2026-03-01T08:00:43.331Z","repository":{"id":336616689,"uuid":"1150410163","full_name":"mocyuto/zgt","owner":"mocyuto","description":"A simple CLI tool for parallel git worktree development","archived":false,"fork":false,"pushed_at":"2026-02-24T15:00:21.000Z","size":224,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-24T16:28:47.252Z","etag":null,"topics":["cli","git","golang","worktree"],"latest_commit_sha":null,"homepage":"","language":"Go","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/mocyuto.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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-02-05T08:44:54.000Z","updated_at":"2026-02-24T15:01:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mocyuto/zgt","commit_stats":null,"previous_names":["mocyuto/git-wt","mocyuto/zgt"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/mocyuto/zgt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocyuto%2Fzgt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocyuto%2Fzgt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocyuto%2Fzgt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocyuto%2Fzgt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mocyuto","download_url":"https://codeload.github.com/mocyuto/zgt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocyuto%2Fzgt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29964203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T06:55:38.174Z","status":"ssl_error","status_checked_at":"2026-03-01T06:53:04.810Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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","git","golang","worktree"],"created_at":"2026-02-14T10:05:08.077Z","updated_at":"2026-03-01T08:00:43.278Z","avatar_url":"https://github.com/mocyuto.png","language":"Go","readme":"# zgt (formerly `git-wt`)\n\nEnglish | [日本語](./README_ja.md)\n\nA CLI tool that extends `git worktree add` by automatically copying ignored configuration files (like `.env`) to the new directory.\n\n## Overview\n\n- [Migration Guide (from `git-wt`)](./MIGRATION.md)\n\nGit's `worktree` feature is powerful,\nbut files ignored by `.gitignore` (such as `.env` or local configs) are not included in the newly created worktree. `zgt` automates the process of copying these files, allowing you to start development and testing immediately.\n\n## Features\n\n- **Standard Wrapper**: Works as a wrapper for `git worktree add`.\n- **Auto-Discovery**: Automatically identifies and copies \"ignored files\" specified in `.gitignore`.\n- **Structural Integrity**: Maintains directory structure during copy (e.g., config files inside `node_modules`).\n- **Flexible Interface**: Powered by the Cobra framework for robust flag handling.\n- **Path Automation**: Automatically generates worktree paths based on branch names (`{project}-{branch}`) adjacent to the repository root.\n- **Lifecycle Management**: Support for listing (`list`/`ls`) and removing (`remove`/`rm`) worktrees.\n- **Port Management**: Automatically assigns unique port indexes to each worktree to prevent port collisions.\n- **Custom Hooks**: Execute multiple shell commands naturally after creating (`add`) or removing (`rm`) worktrees.\n- **Configuration Visibility**: `config` subcommand to inspect the final merged configuration and validate syntax.\n- **Bi-directional Sync**: `sync` subcommand to synchronize ignored files from worktree back to the project root.\n- **Agent Skills**: Distribute and install expert skills for AI agents.\n\n## Badges\n\n[![Release](https://img.shields.io/github/release/mocyuto/zgt.svg?style=for-the-badge)](https://github.com/mocyuto/zgt/releases/latest)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](/LICENSE.md)\n[![Build status](https://img.shields.io/github/actions/workflow/status/mocyuto/zgt/ci.yml?style=for-the-badge\u0026branch=main)](https://github.com/mocyuto/zgt/actions?workflow=ci)\n\n## Installation\n\n### Homebrew\n\nThe easiest way to install on macOS is via Homebrew:\n\n```bash\nbrew install mocyuto/tap/zgt\n```\n\n### Build\n\n```bash\ngo build -o zgt .\n```\n\n### Move to PATH\n\nPlace the binary in a directory included in your `PATH`.\n\n```bash\n# Example for macOS / Linux\nsudo mv zgt /usr/local/bin/zgt\n```\n\n## Development Workflow \u0026 Behavior\n\n`zgt` is designed to make context switching seamless for developers by automating the repetitive parts of managing worktrees.\n\n### 1. Starting a New Feature (`add`)\n\nRunning `git worktree add` usually leaves you with a fresh directory missing essential local files like `.env`. `zgt` automates the entire setup:\n\n1. **Worktree Creation**: Creates the directory and checks out the branch.\n2. **Auto-Path Generation**: Provide just the branch name, and it will be placed as `{project}-{branch}` at the same level as your repository root automatically.\n3. **Config Synchronization**: Identifies \"ignored files\" (like `.env`) in your main tree and copies them over, maintaining the directory structure.\n4. **Port Reservation**: Reserves a unique \"Port Index\" for this specific worktree.\n5. **Automated Setup**: If you define hooks like `npm install` in `hooks.add`, they run immediately after creation.\n\n```bash\n# Start a new feature in a fresh worktree\nzgt add feature-login\n```\n\n### 2. Running Multiple Projects Simultaneously (`env` / `ports`)\n\nWhen running multiple servers across different worktrees, port collisions are a common pain point. `zgt` solves this:\n\n- **Behavior**: Every worktree is assigned a stable index (`0, 1, 2...`).\n- **Dynamic Calculation**: Port numbers are calculated by adding the index to the base port defined in the `zgt.config.yml` of the worktree's project root. This ensures correct calculation even with different base ports across projects.\n- **Usage**: Define base ports (e.g., `api: 8080`) in your config. `zgt env` generates environment variables (e.g., `8080`, `8081`...) specific to that worktree.\n\n```bash\n# Move to a worktree and load its specific environment\ncd ../my-project-feature-login\neval \"$(zgt env)\"\n\n# $API_PORT is now 8081, preventing collision with other worktrees\nnpm start\n```\n\n### 3. Cleaning Up (`remove`)\n\nWhen a feature is finished, `zgt` handles the teardown in one go.\n\n- **Behavior**: Deletes the worktree directory and its associated local branch simultaneously (configurable).\n- **Cleanup**: The Port Index is released and becomes available for future worktrees. You can also trigger cleanup scripts via `hooks.rm`.\n\n```bash\n# Done with the feature. Delete both directory and branch.\nzgt rm feature-login\n```\n\n### 4. Synchronizing Ignored Files (`sync`)\n\nIf you've made changes to ignored configuration files (like `.env`) within your worktree and want to reflect those changes back to the main project root:\n\n- **Interactive Mode**: Run `zgt sync` to open a TUI (powered by `rivo/tview`) where you can selectively choose which files to sync.\n- **Bulk Sync**: Use `-a` / `--all` (or `--force`) to sync all ignored files immediately.\n\n```bash\n# Selectively sync changes back to root\nzgt sync\n```\n\n### 5. Monitoring Assignments (`list` / `ports`)\n\n- `list`: Shows which worktrees are active, their branch status, GitHub PR details, assigned ports, and whether they have uncommitted changes (`[DIRTY]`).\n- `tmux ls`: Shows tmux sessions, windows, and panes status (Running/Waiting) in a hierarchical tree structure.\n- `tmux open`: Opens or activates the tmux window for the specified worktree. If the window exists, it switches to it; otherwise, it creates it according to the configuration.\n- `ports`: Shows the mapping of worktree paths to their assigned port indexes and actual port numbers. Use `-a` / `--all` to see assignments across all projects.\n- `ports update`: Synchronizes port assignments for the current project with the latest configuration. It adds missing port assignments and removes those no longer present in the configuration.\n- `config`: Displays the final merged configuration (global + project + flags) in YAML format. Use `--check` to validate configuration syntax, or `--raw` to skip placeholder replacement.\n- `config edit`: Edits the configuration file using the system editor. Defaults to editing the local project configuration.\n- `version`: Prints the version number of `zgt`.\n- `skill install`: Installs skills from the current repository's `skills/` directory to the global agent skills directory (`~/.claude/skills/`).\n\n## Configuration\n\nYou can configure `zgt` globally (`~/.config/zgt/config.yaml`) or locally (`zgt.config.yml` in project root).\n\n```yaml\n# Examples of available configuration options\nadd:\n  from_default: true # Always base new worktrees on the default branch (e.g., main)\n  auto_pull: true # Pull updates on the default branch before creating a new worktree\n\nignore:\n  - .env\n```\n\n`zgt` loads configuration from three sources in this priority:\n\n1. Local project configuration (`zgt.config.yaml` or `zgt.config.yml` in project root)\n2. Global configuration (`~/.config/zgt/config.yaml`)\n3. Explicit configuration path provided via `--config` flag\n\n### Initializing Configuration (`init`)\n\nYou can generate a default configuration file (`zgt.config.yml`) in your project's root directory:\n\n```bash\nzgt init\n```\n\nThis command performs the following:\n\n1.  Creates a `zgt.config.yml` with sensible defaults for port management, environment templates, and sample hooks.\n2.  Automatically appends `zgt.config.yml` and `zgt.config.yaml` to your `.gitignore` file to ensure they are not accidentally committed.\n\nIf `zgt.config.yml` or `zgt.config.yaml` already exists, the command will skip creation to prevent overwriting your existing settings.\n\n### Customizing Configuration (`config edit`)\n\nYou can edit your configuration files directly from the CLI using your preferred editor (defined by `$EDITOR` or `vi`):\n\n```bash\n# Edit local configuration\nzgt config edit --local\n\n# Edit global configuration\nzgt config edit --global\n```\n\n`zgt` will validate the YAML syntax before saving your changes.\n\n### Project-Specific Configuration\n\nYou can create a `zgt.config.yaml` (or `.yml`) in your project's root directory to define settings specific to that project. Local settings for `hooks` and `ignore` will be **appended** to the global settings.\n\n```yaml\n# zgt.config.yaml\nignore:\n  - \"*.tmp\"\n  - \"local-debug.log\"\n\nhooks:\n  add:\n    - \"npm install\"\n\nports:\n  api: 8080\n  web: 3000\n\ntmux:\n  enabled: true\n  panes:\n    - id: main\n      commands: [\"yarn\"]\n    - id: dev\n      target: main\n      split: horizontal\n      size: 50%\n      commands: [\"yarn dev\"]\n```\n\n- `WEB_PORT=3001`\n\n### Custom Environment Variables\n\nYou can define custom environment variables in the `env` section. These variables support placeholders and automatically exported via `zgt env`.\n\n```yaml\nenv:\n  COMPOSE_PROJECT_NAME: \"zgt-{{.Repo}}\"\n  DEBUG: \"true\"\n```\n\nIn your terminal:\n\n```bash\neval \"$(zgt env)\"\necho $COMPOSE_PROJECT_NAME # zgt-myrepo\n```\n\nThese variables are also available during [Custom Hooks](#custom-hooks) execution.\n\n### Custom Ignore Patterns\n\nYou can specify additional file patterns to be ignored during the copy process. These patterns follow the same format as `.gitignore` (using `filepath.Match`).\n\n```yaml\nignore:\n  - \".env.production\"\n  - \"secrets/*\"\n```\n\n### Pull Default Branch After Removal\n\nYou can automatically pull the default branch from the remote repository after removing a worktree by adding a git command to your `rm` hooks.\n\n```yaml\nhooks:\n  rm:\n    - \"git pull origin main:main\"\n```\n\n### Custom Hooks\n\nHooks allow you to run automated shell commands when worktrees are managed.\n\n```yaml\nhooks:\n  # Commands to run after 'add'\n  add:\n    - \"tmux new-window -n [{{.Repo}}]{{.Branch}} -c {{.Path}}\"\n    - \"echo 'Welcome to {{.Repo}}'\"\n  # Commands to run after 'remove'\n  rm:\n    - \"echo 'Cleanup for {{.Branch}}'\"\n```\n\n#### Available Placeholders\n\nPlaceholders can be used in `hooks`, `env`, and `tmux.window_name` values.\n\n| Placeholder          | Description                                                   |\n| :------------------- | :------------------------------------------------------------ |\n| `{{.Path}}`          | Absolute path of the worktree directory.                      |\n| `{{.Repo}}`          | Name of the main project root directory.                      |\n| `{{.CurrentDir}}`    | Name of the current working directory.                        |\n| `{{.Branch}}`        | Name of the target branch (provided as argument).             |\n| `{{.TargetBranch}}`  | Alias for `{{.Branch}}`.                                      |\n| `{{.CurrentBranch}}` | Name of the branch you are currently on when executing `zgt`. |\n\n#### Template Functions\n\nYou can use functions to transform placeholder values.\n\n| Function   | Description                                              | Example                                |\n| :--------- | :------------------------------------------------------- | :------------------------------------- |\n| `hostname` | Replaces hostname-unsafe characters (`_`, `/`) with `-`. | `{{.Branch \\| hostname}}`-\u003e`feat-test` |\n\n### Tmux Integration\n\n`zgt` can automatically set up a tmux window with multiple panes and execute commands in each when you run `add`. You can explicitly target panes for splitting using IDs.\n\n```yaml\ntmux:\n  enabled: true\n  panes:\n    - id: main\n      commands: [\"yarn\"]\n    - id: side\n      target: main\n      split: horizontal\n      size: 50%\n      commands: [\"yarn dev\"]\n    - target: side\n      split: vertical\n      commands: [\"yarn watch\"]\n    - target: main\n      split: vertical\n      commands: [\"tail -f logs/app.log\"]\n```\n\n#### Pane Properties\n\n| Property      | Description                                                                   |\n| :------------ | :---------------------------------------------------------------------------- |\n| `window_name` | (Optional) Template for the tmux window name.                                 |\n| `id`          | (Optional) Unique ID for the pane to be referenced as a `target`.             |\n| `target`      | (Optional) ID of the pane to split. If omitted, splits the last created pane. |\n| `commands`    | List of commands to execute in the pane.                                      |\n| `split`       | Split direction: `horizontal` (h) or `vertical` (v).                          |\n| `size`        | Pane size (e.g., `20%` for percentage or `20` for lines/columns).             |\n\nIf `enabled` is `true`, `zgt` will:\n\n1. Create a new tmux window named as specified in `window_name` (defaults to `[repo]branch`).\n2. Follow the `panes` list to create splits. Each split targets the specified `target` or the last created pane.\n3. Execute the `commands` in each pane and keep the shell open.\n\n#### Note\n\n- Requires `tmux` to be installed and a tmux session to be running.\n\n#### Note\n\n- If you only need a single command, you can use a string instead of a list: `add: \"echo hello\"`.\n- Commands are executed via `/bin/sh -c`, allowing for pipes and status checks.\n\n## Agent Skill Management\n\n`zgt` provides a way to manage \"Expert Skills\" for AI agents. Skills are sets of instructions and resources that extend an agent's capabilities.\n\n### Installing Skills (`skill install`)\n\nTo install the skills from the current repository so that your AI collaborator (like Claude) can use them:\n\n```bash\nzgt skill install\n```\n\nThis will open an interactive TUI to choose from 4 installation targets:\n\n- **Local .claude**: `./.claude/skills/`\n- **Local .agents**: `./.agents/skills/`\n- **Global .claude**: `~/.claude/skills/`\n- **Global .agents**: `~/.agents/skills/`\n\nUse `-a` or `--all` to install to all targets immediately.\n\n## Requirements\n\n- `git` and `gh` must be installed and available in your environment.\n\n## Development \u0026 Testing\n\n```bash\n# Run tests\ngo test -v ./...\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocyuto%2Fzgt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmocyuto%2Fzgt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocyuto%2Fzgt/lists"}