Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,13 @@ Run `git gtr help` for full documentation.
Create a new git worktree. Folder is named after the branch.

```bash
git gtr new my-feature # Creates folder: my-feature
git gtr new hotfix --from v1.2.3 # Create from specific ref
git gtr new variant-1 --from-current # Create from current branch
git gtr new feature/auth # Creates folder: feature-auth
git gtr new feature-auth --name backend --force # Same branch, custom name
git gtr new my-feature --name descriptive-variant # Optional: custom name without --force
git gtr new my-feature # Creates folder: my-feature
git gtr new hotfix --from v1.2.3 # Create from specific ref
git gtr new variant-1 --from-current # Create from current branch
git gtr new feature/auth # Creates folder: feature-auth
git gtr new feature/implement-user-authentication-with-oauth2-integration --folder auth # Custom folder name
git gtr new feature-auth --name backend --force # Same branch, custom name
git gtr new my-feature --name descriptive-variant # Optional: custom name without --force
```

**Options:**
Expand All @@ -170,8 +171,9 @@ git gtr new my-feature --name descriptive-variant # Optional: custom name with
- `--track <mode>`: Tracking mode (auto|remote|local|none)
- `--no-copy`: Skip file copying
- `--no-fetch`: Skip git fetch
- `--force`: Allow same branch in multiple worktrees (**requires --name**)
- `--force`: Allow same branch in multiple worktrees (**requires --name or --folder**)
- `--name <suffix>`: Custom folder name suffix (optional, required with --force)
- `--folder <name>`: Custom folder name (replaces default, useful for long branch names)
- `--editor`, `-e`: Open in editor after creation
- `--ai`, `-a`: Start AI tool after creation
- `--yes`: Non-interactive mode
Expand Down
40 changes: 32 additions & 8 deletions bin/gtr
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ cmd_create() {
local yes_mode=0
local force=0
local custom_name=""
local folder_override=""
local open_editor=0
local start_ai=0

Expand Down Expand Up @@ -168,6 +169,10 @@ cmd_create() {
custom_name="$2"
shift 2
;;
--folder)
folder_override="$2"
shift 2
;;
--editor|-e)
open_editor=1
shift
Expand All @@ -191,12 +196,19 @@ cmd_create() {
done

# Validate flag combinations
if [ "$force" -eq 1 ] && [ -z "$custom_name" ]; then
log_error "--force requires --name to distinguish worktrees"
if [ -n "$folder_override" ] && [ -n "$custom_name" ]; then
log_error "--folder and --name cannot be used together"
exit 1
fi

if [ "$force" -eq 1 ] && [ -z "$custom_name" ] && [ -z "$folder_override" ]; then
log_error "--force requires --name or --folder to distinguish worktrees"
if [ -n "$branch_name" ]; then
echo "Example: git gtr new $branch_name --force --name backend" >&2
echo " or: git gtr new $branch_name --force --folder my-folder" >&2
else
echo "Example: git gtr new feature-auth --force --name backend" >&2
echo " or: git gtr new feature-auth --force --folder my-folder" >&2
fi
exit 1
fi
Expand Down Expand Up @@ -245,7 +257,9 @@ cmd_create() {

# Construct folder name for display
local folder_name
if [ -n "$custom_name" ]; then
if [ -n "$folder_override" ]; then
folder_name=$(sanitize_branch_name "$folder_override")
elif [ -n "$custom_name" ]; then
folder_name="$(sanitize_branch_name "$branch_name")-${custom_name}"
else
folder_name=$(sanitize_branch_name "$branch_name")
Expand All @@ -256,7 +270,7 @@ cmd_create() {
echo "Branch: $branch_name"

# Create the worktree
if ! worktree_path=$(create_worktree "$base_dir" "$prefix" "$branch_name" "$from_ref" "$track_mode" "$skip_fetch" "$force" "$custom_name"); then
if ! worktree_path=$(create_worktree "$base_dir" "$prefix" "$branch_name" "$from_ref" "$track_mode" "$skip_fetch" "$force" "$custom_name" "$folder_override"); then
exit 1
fi

Expand Down Expand Up @@ -336,11 +350,20 @@ cmd_create() {

# Show next steps only if no auto-launch flags were used
if [ "$open_editor" -eq 0 ] && [ "$start_ai" -eq 0 ]; then
# Determine identifier to show in next steps
# Use custom folder when --folder specified, otherwise use original branch name
local next_steps_id
if [ -n "$folder_override" ]; then
next_steps_id="$folder_name"
else
next_steps_id="$branch_name"
fi

echo ""
echo "Next steps:"
echo " git gtr editor $branch_name # Open in editor"
echo " git gtr ai $branch_name # Start AI tool"
echo " cd \"\$(git gtr go $branch_name)\" # Navigate to worktree"
echo " git gtr editor $next_steps_id # Open in editor"
echo " git gtr ai $next_steps_id # Start AI tool"
echo " cd \"\$(git gtr go $next_steps_id)\" # Navigate to worktree"
fi
}

Expand Down Expand Up @@ -1440,8 +1463,9 @@ CORE COMMANDS (daily workflow):
--track <mode>: tracking mode (auto|remote|local|none)
--no-copy: skip file copying
--no-fetch: skip git fetch
--force: allow same branch in multiple worktrees (requires --name)
--force: allow same branch in multiple worktrees (requires --name or --folder)
--name <suffix>: custom folder name suffix (e.g., backend, frontend)
--folder <name>: custom folder name (replaces default, useful for long branches)
--yes: non-interactive mode
-e, --editor: open in editor after creation
-a, --ai: start AI tool after creation
Expand Down
1 change: 1 addition & 0 deletions completions/_git-gtr
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ _git-gtr() {
'--no-fetch[Skip git fetch]' \
'--force[Allow same branch in multiple worktrees]' \
'--name[Custom folder name suffix]:name:' \
'--folder[Custom folder name (replaces default)]:folder:' \
'--yes[Non-interactive mode]' \
'--editor[Open in editor after creation]' \
'-e[Open in editor after creation]' \
Expand Down
1 change: 1 addition & 0 deletions completions/git-gtr.fish
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ complete -c git -n '__fish_git_gtr_using_command new' -l no-copy -d 'Skip file c
complete -c git -n '__fish_git_gtr_using_command new' -l no-fetch -d 'Skip git fetch'
complete -c git -n '__fish_git_gtr_using_command new' -l force -d 'Allow same branch in multiple worktrees'
complete -c git -n '__fish_git_gtr_using_command new' -l name -d 'Custom folder name suffix' -r
complete -c git -n '__fish_git_gtr_using_command new' -l folder -d 'Custom folder name (replaces default)' -r
complete -c git -n '__fish_git_gtr_using_command new' -l yes -d 'Non-interactive mode'
complete -c git -n '__fish_git_gtr_using_command new' -s e -l editor -d 'Open in editor after creation'
complete -c git -n '__fish_git_gtr_using_command new' -s a -l ai -d 'Start AI tool after creation'
Expand Down
2 changes: 1 addition & 1 deletion completions/gtr.bash
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ _git_gtr() {
new)
# Complete flags
if [[ "$cur" == -* ]]; then
COMPREPLY=($(compgen -W "--id --from --from-current --track --no-copy --no-fetch --force --name --yes --editor -e --ai -a" -- "$cur"))
COMPREPLY=($(compgen -W "--id --from --from-current --track --no-copy --no-fetch --force --name --folder --yes --editor -e --ai -a" -- "$cur"))
elif [ "$prev" = "--track" ]; then
COMPREPLY=($(compgen -W "auto remote local none" -- "$cur"))
fi
Expand Down
8 changes: 6 additions & 2 deletions lib/core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,12 @@ resolve_target() {
}

# Create a new git worktree
# Usage: create_worktree base_dir prefix branch_name from_ref track_mode [skip_fetch] [force] [custom_name]
# Usage: create_worktree base_dir prefix branch_name from_ref track_mode [skip_fetch] [force] [custom_name] [folder_override]
# track_mode: auto, remote, local, or none
# skip_fetch: 0 (default, fetch) or 1 (skip)
# force: 0 (default, check branch) or 1 (allow same branch in multiple worktrees)
# custom_name: optional custom name suffix (e.g., "backend" creates "feature-auth-backend")
# folder_override: optional complete folder name override (replaces default naming)
create_worktree() {
local base_dir="$1"
local prefix="$2"
Expand All @@ -286,10 +287,13 @@ create_worktree() {
local skip_fetch="${6:-0}"
local force="${7:-0}"
local custom_name="${8:-}"
local folder_override="${9:-}"
local sanitized_name worktree_path

# Construct folder name
if [ -n "$custom_name" ]; then
if [ -n "$folder_override" ]; then
sanitized_name=$(sanitize_branch_name "$folder_override")
elif [ -n "$custom_name" ]; then
sanitized_name="$(sanitize_branch_name "$branch_name")-${custom_name}"
else
sanitized_name=$(sanitize_branch_name "$branch_name")
Expand Down