-
Notifications
You must be signed in to change notification settings - Fork 44
feat: add copy command for syncing files between worktrees #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds a new git-gtr "copy" subcommand to copy files between worktrees, with --from, -n/--dry-run, -a/--all options; implements per-target copying (dry-run supported), worktree listing helper, updated shell completions, and documentation/examples. Changes
Sequence DiagramsequenceDiagram
actor User
participant CLI as bin/gtr (cmd_copy)
participant Core as lib/core.sh (list_worktree_branches)
participant Copy as lib/copy.sh (copy_patterns)
User->>CLI: git gtr copy --from <src> [-n] [-a] [targets...]
CLI->>CLI: parse flags, load include/exclude patterns
alt --all present
CLI->>Core: list_worktree_branches(repo_root, prefix)
Core-->>CLI: branch list
else targets provided
CLI->>CLI: validate/resolve targets
end
CLI->>CLI: build final target list
loop for each target
CLI->>Copy: copy_patterns(src, dst, patterns, dry_run?)
Copy-->>CLI: per-target logs / copied_count
CLI->>CLI: report per-target status
end
CLI-->>User: aggregated summary (and warnings if nothing copied)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–30 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (5)lib/**/*.sh📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.sh📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{bash,fish,sh}📄 CodeRabbit inference engine (.github/instructions/sh.instructions.md)
Files:
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)
Files:
bin/gtr📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🔇 Additional comments (4)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
lib/core.sh (1)
440-456: Minor cleanup inlist_worktree_branchesand note on semantics
repo_rootis currently unused; either drop it from the signature or rename to_repo_rootto avoid confusion / shellcheck noise.- The helper returns only branch names, which is fine given
resolve_targetis branch‑based, but it also meanscmd_copy --allinherits the existing limitation that you can’t distinguish multiple worktrees sharing the same branch. If you ever add per‑worktree identifiers, this function will likely need to return paths (or path+branch) instead of just names.bin/gtr (1)
81-83:cmd_copyimplementation and wiring look solid
- Dispatcher correctly adds
copy→cmd_copyand the help text matches the implemented flags and examples.- Argument parsing in
cmd_copyis consistent with existing commands:
--from,-n/--dry-run,-a/--all, and--for patterns are handled clearly.- Targets are required unless
--allis set, and repo context / source worktree resolution are guarded with|| exit 1, which is good under globalset -e.- Pattern resolution honors precedence as documented:
- CLI
-- <pattern>...wins overgtr.copy.includeand.worktreeinclude.- Excludes are taken from
gtr.copy.exclude.--allis implemented vialist_worktree_branches, then each target goes throughresolve_target, with source==destination safely skipped and a final warning when nothing is processed.- Dry‑run is correctly plumbed through to
copy_patternsvia the extra boolean parameter, and the logs clearly distinguish real copies from previews.If you later introduce a notion of multiple managed worktrees per branch, note that
cmd_copy --all(likego/run/rm) is inherently branch‑centric viaresolve_targetand would need revisiting to operate per physical worktree instead of per branch.Also applies to: 473-595, 1192-1205
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
bin/gtr(3 hunks)completions/_git-gtr(3 hunks)completions/gtr.bash(2 hunks)completions/gtr.fish(3 hunks)lib/copy.sh(4 hunks)lib/core.sh(1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
lib/**/*.sh
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
lib/**/*.sh: Core libraries (lib/core.sh,lib/config.sh,lib/ui.sh,lib/copy.sh,lib/hooks.sh,lib/platform.sh) must be sourced at startup and implement specific functionality
Maintain backwards compatibility with Git <2.22 by using fallbackrev-parse --abbrev-ref HEADinstead ofbranch --show-current
lib/**/*.sh: Maintain backwards compatibility with existing configs in shell scripts
Quote all paths to support spaces in directory names
Uselog_error/log_infofromlib/ui.shfor user messages
Implement Git version fallbacks (e.g., Git 2.22+--show-currentvs olderrev-parse); checklib/core.sh:97-100for example
Add new config keys withgtr.<name>prefix to avoid collisions
For performance-sensitive loops (e.g., directory scans), prefer built-ins (find,grep) with minimal subshells
For any new Git command, add fallback for older versions or guard with detection
Files:
lib/core.shlib/copy.sh
**/*.sh
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.sh: Always quote paths to handle spaces and special characters; avoid unguarded globbing
Keepset -eactive in shell scripts; ensure non-critical failures are guarded withcommand || true
**/*.sh: Use shebang#!/usr/bin/env bash(not/bin/bashor/bin/sh) for all Bash scripts
Use snake_case naming for functions in Bash scripts
Use snake_case for local variables and UPPER_CASE for constants/environment variables in Bash scripts
Use 2-space indentation in Bash scripts (no tabs)
Always quote variables and paths in Bash scripts to prevent word splitting
Check return codes in Bash scripts using|| exit 1or|| return 1for error handling
Uselocalkeyword for function-scoped variables in Bash scripts
Target Bash 3.2+ for compatibility with older systems like older macOS versions
Useset -efor error handling in Bash scripts to ensure failures are caught
Include fallback code for different Git versions (Git 2.5-2.21 compatibility fallbacks for modern Git 2.22+ commands)
Files:
lib/core.shlib/copy.sh
**/*.{bash,fish,sh}
📄 CodeRabbit inference engine (.github/instructions/sh.instructions.md)
**/*.{bash,fish,sh}: Bash 3.2+ compatible (macOS default), but 4.0+ features allowed where appropriate
Always quote variables: use"$var"not$var
Use function-scoped variables:local var="value"
Check return codes; functions return 1 on failure
Usesnake_casefor functions and variables,UPPER_CASEfor constants
Prefer[ ]over[[ ]]for POSIX portability; use[[only when needed
Always quote glob inputs; disable unintended globbing withset -ftemporarily if required
Avoid associative arrays in shell scripts; use simple string/loop constructs for Bash 3.2+ compatibility
Avoidreadarrayand process substitution unsupported in older Bash
Debug withbash -x ./bin/gtr <cmd>or wrap suspicious blocks withset -x/set +x
Check function presence withdeclare -f create_worktreeordeclare -f resolve_target
Use stderr for variable inspection:echo "DEBUG var=$var" >&2to keep stdout clean for command substitution
Keep dependencies minimal: only usegit,sed,awk,find,grep; avoid jq/curl unless justified
Check availability of external commands before use when adding new tools
Use"${var}"for variable expansion; for line loops usewhile IFS= read -r line; do ... doneto preserve spaces
Sanitize branch names viasanitize_branch_namefunction; do NOT duplicate logic elsewhere
Everything is sourced at startup withset -eenabled; functions call each other directly; no subshells except for hooks and AI tools
Files:
lib/core.shlib/copy.shcompletions/gtr.fishcompletions/gtr.bash
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}
📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}: All commands must exit 0 (except intentional failures) and produce expected side-effects
No unquoted path errors; spaces must be handled in file paths
Hooks must run only once per creation/removal event
Files:
lib/core.shlib/copy.shbin/gtr
bin/gtr
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
bin/gtr: Dispatch commands throughcmd_*functions inbin/gtr(case block lines 36‑77)
UpdateGTR_VERSIONon line 8 ofbin/gtrwhen releasing; this affectsgtr version/--versionoutputGlobal
set -einbin/gtr: guard non-critical commands with|| true
list --porcelainoutput must remain stable for scripting purposesVersion number in
bin/gtr(line 8) must be updated when releasing a new version
Files:
bin/gtr
completions/*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Shell completion files must be updated for bash, zsh, and fish when commands or adapters are added
Files:
completions/gtr.fishcompletions/gtr.bashcompletions/_git-gtr
completions/{gtr.bash,_git-gtr,gtr.fish}
📄 CodeRabbit inference engine (.github/instructions/completions.instructions.md)
completions/{gtr.bash,_git-gtr,gtr.fish}: Always update all three completion files (gtr.bash, _git-gtr, gtr.fish) when adding new commands, flags, editors, or AI adapters
Implement command completion in all three completion files to support top-level commands (new, rm, editor, ai, list, etc.) with appropriate tab-completion
Implement flag completion in all three completion files to support command-specific flags (e.g., --from, --force, --editor) with appropriate tab-completion
Implement adapter name completion in all three completion files, listing available editor names (cursor, vscode, zed) and AI tool names (aider, claude, codex) for --editor and --ai flags
Files:
completions/gtr.fishcompletions/gtr.bashcompletions/_git-gtr
completions/gtr.fish
📄 CodeRabbit inference engine (.github/instructions/completions.instructions.md)
completions/gtr.fish: In completions/gtr.fish, use custom predicates (__fish_git_gtr_needs_command, __fish_git_gtr_using_command) to handle git subcommand context and detect 'git gtr' usage
In completions/gtr.fish, support dynamic branch completion using 'git branch --format='%(refname:short)' and include special ID '1' for main repo
Files:
completions/gtr.fish
completions/**
📄 CodeRabbit inference engine (CLAUDE.md)
Update all three shell completion files when adding new commands or flags:
completions/gtr.bash,completions/_git-gtr(Zsh), andcompletions/gtr.fish(Fish)
Files:
completions/gtr.fishcompletions/gtr.bashcompletions/_git-gtr
completions/gtr.bash
📄 CodeRabbit inference engine (.github/instructions/completions.instructions.md)
completions/gtr.bash: In completions/gtr.bash, implement command completion using COMPREPLY array and compgen filtering for the current word ($cur)
In completions/gtr.bash, support dynamic branch completion using 'git branch --format='%(refname:short)' and include special ID '1' for main repo
Files:
completions/gtr.bash
completions/_git-gtr
📄 CodeRabbit inference engine (.github/instructions/completions.instructions.md)
completions/_git-gtr: In completions/_git-gtr, use Zsh completion framework with _arguments and _describe/_values for sophisticated completion logic with descriptions and grouping
In completions/_git-gtr, support dynamic branch completion using 'git branch --format='%(refname:short)' and include special ID '1' for main repo
Files:
completions/_git-gtr
🪛 Shellcheck (0.11.0)
completions/gtr.bash
[warning] 25-25: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 50-50: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
[warning] 56-56: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
(SC2207)
🔇 Additional comments (4)
completions/gtr.bash (1)
25-25: Copy completions and config keys look consistentThe new
copysubcommand is correctly wired into bash completion:
- Top‑level command list now includes
copy.copy)case offers-n/--dry-run,-a/--all, and--fromwhen completing flags, and1+ branch names otherwise.configkey completion includes the newgtr.copy.*keys, matching the help text and config usage.No issues from the ShellCheck SC2207 hints here; the existing
COMPREPLY=($(compgen ...))pattern is standard for bash completion in this project.Also applies to: 48-58, 68-72
completions/gtr.fish (1)
38-48: Fish completion forcopymatches CLI behavior
copyis added to the top‑level command list with an appropriate description.- Short/long flags for the copy command (
-n/--dry-run,-a/--all,--from) are exposed with clear descriptions.- Branch completion for
copyreuses__gtr_worktree_branches, giving1plus local branches, consistent with other commands.gtr.copy.*config keys are present in the config completion block.Looks good and aligned with the other shells.
Also applies to: 65-69, 86-92, 95-99
lib/copy.sh (1)
19-24: Dry‑run support incopy_patternsis backward‑compatible and side‑effect free
- The extra
[dry_run]parameter is optional and defaults to"false", so existing callers (likecmd_create) retain their behavior.- When
dry_runis"true", the function:
- Skips
mkdir -pandcpentirely.- Logs
[dry-run] Would copy: <file>per match and a final[dry-run] Would copy N file(s)summary.- Real copies still create parent directories and log per‑file success/failure, with the same counting and overall summary as before.
- All new logic keeps paths quoted and respects the existing safety checks on patterns.
This is a clean extension and fits the new
cmd_copyusage well.Also applies to: 30-31, 106-123, 164-181, 192-197
completions/_git-gtr (1)
18-34: Zsh completion forcopyis wired correctly
copyis added to the subcommand list with a clear description.- First positional argument after
copynow completes to1plus branch names, matching other branch‑oriented commands (go,run,rm).- Subsequent arguments for
copyuse_argumentsto expose:
-n/--dry-run,-a/--all, and--from(with worktree‑aware completion),- Positional targets completed from the same branch/
1set.This matches the new CLI and stays consistent with the existing Zsh completion style.
Also applies to: 63-71, 97-107
Pull Request
Description
Motivation
Fixes # (issue)
Type of Change
Testing
Manual Testing Checklist
Tested on:
Core functionality tested:
git gtr new <branch>- Create worktreegit gtr go <branch>- Navigate to worktreegit gtr editor <branch>- Open in editor (if applicable)git gtr ai <branch>- Start AI tool (if applicable)git gtr rm <branch>- Remove worktreegit gtr list- List worktreesgit gtr config- Configuration commands (if applicable)Test Steps
Expected behavior:
Actual behavior:
Breaking Changes
Checklist
Before submitting this PR, please check:
git gtr(production) and./bin/gtr(development)Additional Context
License Acknowledgment
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache License 2.0.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.