Skip to content

Add preRemove hooks for cleanup before worktree deletion #47

@damianlewis

Description

@damianlewis

Summary

Add support for preRemove hooks that execute before a worktree directory is deleted, complementing the existing postRemove hooks.

Use Case

The current hook system only supports postRemove hooks, which run after the worktree directory has been deleted. This creates a limitation for cleanup tasks that require access to the worktree directory or need the directory to exist for external tool integration.

Common use cases that require the directory to still exist:

  • Unlinking the directory from web servers or development tools
  • Reading configuration files from the worktree before removal
  • Gracefully stopping services that are bound to the worktree path
  • Cleaning up symlinks or mounts that reference the worktree
  • Notifying external systems that track directory paths

Proposed Solution

New Configuration Option

gtr.hook.preRemove       Pre-remove hooks (multi-valued)

Usage

# Add a pre-remove hook
git gtr config add gtr.hook.preRemove '$REPO_ROOT/scripts/cleanup.sh'

# Multiple hooks (executed in order)
git gtr config add gtr.hook.preRemove '$REPO_ROOT/scripts/stop-services.sh'
git gtr config add gtr.hook.preRemove '$REPO_ROOT/scripts/unlink-sites.sh'

Execution Order for git gtr rm

  1. Validate worktree exists
  2. Run preRemove hooks (directory exists, hooks can access files)
  3. Remove worktree directory
  4. Run postRemove hooks (directory gone, for notifications/logging)

Environment Variables

Same as postRemove hooks:

Variable Description
WORKTREE_PATH Absolute path to the worktree directory
BRANCH Branch name of the worktree
REPO_ROOT Path to the main repository

Error Handling

Default behavior: If a preRemove hook exits with a non-zero status, the removal should be aborted to prevent data loss or inconsistent state (similar to git's pre-commit hooks).

$ git gtr rm my-feature
Running pre-remove hook: /path/to/cleanup.sh
Hook failed with exit code 1
Worktree removal aborted. Use --force to override.

Force flag: The existing --force flag should bypass hook failures:

$ git gtr rm my-feature --force
Running pre-remove hook: /path/to/cleanup.sh
Hook failed with exit code 1 (ignored due to --force)
Removing worktree...

Example Use Cases

# Stop a development server before removal
#!/bin/bash
if [ -f "$WORKTREE_PATH/.pid" ]; then
    kill $(cat "$WORKTREE_PATH/.pid") 2>/dev/null
fi

# Unlink from a local web server
#!/bin/bash
my-webserver unlink "$WORKTREE_PATH"

# Archive logs before deletion
#!/bin/bash
if [ -d "$WORKTREE_PATH/logs" ]; then
    tar -czf "$REPO_ROOT/.archives/${BRANCH}-logs.tar.gz" \
        -C "$WORKTREE_PATH" logs
fi

Backwards Compatibility

This is a purely additive change. Existing configurations and workflows are unaffected. Users who don't configure preRemove hooks will see no change in behavior.

Cross-Platform Support

Uses the existing hook execution system (run_hooks in lib/hooks.sh), which already handles cross-platform concerns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions