Skip to content

feat: add daft rename / git worktree-rename command#256

Merged
avihut merged 13 commits intomasterfrom
refactor/rename
Feb 23, 2026
Merged

feat: add daft rename / git worktree-rename command#256
avihut merged 13 commits intomasterfrom
refactor/rename

Conversation

@avihut
Copy link
Owner

@avihut avihut commented Feb 23, 2026

Summary

  • Add daft rename / git worktree-rename command that atomically renames a local branch, moves its worktree directory, and optionally renames the remote branch
  • Support source as branch name or worktree path (absolute/relative), --dry-run, --no-remote, and automatic empty parent directory cleanup
  • Include shell completions (bash/zsh/fish/fig), shortcut (gwtrn), man pages, CLI docs, docs site sidebar entries, and 12 integration tests

Test plan

  • mise run fmt -- clean
  • mise run clippy -- zero warnings
  • mise run test:unit -- 368 tests pass
  • cargo test --package xtask -- 12 tests pass
  • mise run man:verify -- man pages up to date
  • mise run docs:cli:verify -- CLI docs up to date
  • cargo run -- rename --help -- shows correct usage
  • cargo run -- --help -- rename appears in help output
  • mise run test:integration -- run integration tests including new rename tests

🤖 Generated with Claude Code

@avihut avihut force-pushed the refactor/rename branch 4 times, most recently from cbdd2c6 to ce9dea7 Compare February 23, 2026 21:42
@avihut avihut closed this Feb 23, 2026
@avihut avihut deleted the refactor/rename branch February 23, 2026 22:13
@avihut avihut restored the refactor/rename branch February 23, 2026 22:20
@avihut avihut reopened this Feb 23, 2026
@avihut avihut modified the milestone: v1.1.0 Feb 23, 2026
@avihut avihut added feat New feature labels Feb 23, 2026
@avihut avihut self-assigned this Feb 23, 2026
avihut and others added 13 commits February 24, 2026 00:55
The move command only works with multi-remote mode enabled, so having it
under `daft branch` was confusing. Since move was the only subcommand,
this removes `daft branch` entirely and adds move as a subcommand of
`daft multi-remote` where it logically belongs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renames a local branch and moves its associated worktree directory
atomically. Optionally renames the remote branch (push new name,
delete old name). Supports source as branch name or worktree path,
dry-run mode, and automatic empty parent directory cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this, `daft rename` falls through to `command daft` without
the `__daft_wrapper`, so DAFT_CD_FILE is never set. When renaming
from inside the worktree, the directory moves but the shell's CWD
is never updated, leaving the user in a stale path. This causes
p10k/gitstatus to fail to detect the git repo until the shell is
restarted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rename functionality was a standalone `git-worktree-rename` command,
but `-m` (move/rename) belongs alongside `-d`/`-D` in `git worktree-branch`,
mirroring how `git branch -m` sits next to `git branch -d`. The core logic
in `src/core/worktree/rename.rs` is unchanged -- only the command-layer
routing changes.

- Add `-m`/`--move`, `--no-remote`, `--dry-run` flags to worktree-branch
- Route `daft rename` through `worktree_branch::run_rename()` (injects `-m`)
- Delete `src/commands/rename.rs` and all `git-worktree-rename` routes
- Update shell wrappers: `gwtrn` and `daft rename` route via `-m` flag
- Remove `gwtrn` from symlink shortcuts (needs flag injection)
- Remove `git-worktree-rename` from completions, suggestions, xtask, docs
- Update integration tests to use `git-worktree-branch -m`
- Regenerate man pages and CLI docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rename case in bash/zsh daft completions was delegating to
_git_worktree_rename / __git_worktree_rename_impl which no longer exist
after consolidating rename into git-worktree-branch -m. Use inline
branch completion instead, matching the pattern used by the remove case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
run_remove() unconditionally injected -d, so `daft remove -D` passed
both -d and -D to clap, failing the mutual-exclusivity check. Now only
injects -d when -D/--force is not already present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate the daft CLI from git symlink conventions: `daft remove -f`
uses standard CLI-style -f/--force, while `git worktree-branch -D` keeps
git-style -D. The run_remove() entry point translates -f to -D before
clap parsing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Give `daft remove` its own clap Args struct (RemoveArgs) so that help
output shows only deletion-relevant flags with daft-style -f/--force
instead of git-style -D. The git-worktree-branch command retains -D.

- `daft remove -h` now shows clean, focused help
- Man page (daft-remove.1) generated from RemoveArgs
- xtask verb loop checks for dedicated command before deriving from source

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route daft verbs through the binary instead of translating to git flags
in the shell wrapper. This lets each verb have its own Args struct with
dedicated help, flags, and completions.

- Add RenameArgs struct with source, new_branch, --no-remote, --dry-run
- Shell wrappers now call `daft remove`/`daft rename` directly
- Register daft-remove and daft-rename in completion system
- Add dynamic branch completions for both commands
- Guard git subcommand registration to skip daft-* prefixed commands
- Regenerate man page for daft-rename with correct flags

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
__daft_find_bin() used lazy resolution — command -v daft was called on
first use, by which time the daft() shell function was already defined.
In bash/zsh, command -v returns the function name when a function shadows
the binary, causing __daft_wrapper to exec the function recursively until
stack overflow (SIGSEGV, exit 139).

Resolve __daft_bin eagerly at eval time, before the daft() function is
defined, so command -v finds the real binary on PATH.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The shell wrappers used `__daft_wrapper daft remove "$@"` which failed
because the `daft` shell function shadowed the binary name, causing
infinite recursion (SIGSEGV). Switch to `__daft_wrapper daft-remove`
using the multicall binary pattern with dedicated symlinks, matching how
all other commands (git-worktree-*) already work.

Adds daft-remove and daft-rename symlinks across all packaging,
CI, doctor checks, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Have run_remove() and run_rename() call the inner functions directly
instead of converting their args into the git-worktree-branch Args
struct and going through run_with_args(). Each entry point now does
its own setup independently, eliminating the fragile modal flag
conversion that caused interface mismatches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@avihut avihut merged commit 099478a into master Feb 23, 2026
6 checks passed
@avihut avihut deleted the refactor/rename branch February 23, 2026 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant