Skip to content

Feature request: post-cd hook support (gtr.hook.postCd) #108

@echarrod

Description

@echarrod

Summary

When using gtr cd to switch between worktrees, there's no mechanism to run commands automatically after entering the worktree directory. This is needed for projects where environment variables must be re-sourced relative to the worktree root.

Use case

Our monorepo has a vars.sh script at the root that sets up the development environment. It resolves key variables relative to the script's own location:

export MY_CUSTOM_PATH="${0:a:h}"  # resolves to the directory of vars.sh

When sourced once in ~/.zshrc, these variables permanently point to the main checkout. After gtr cd-ing into a worktree, the environment is stale — tools, paths, and hooks all reference the wrong directory.

We need a way to automatically re-source vars.sh (or run arbitrary commands) when entering a worktree via gtr cd.

Proposal

Add a gtr.hook.postCd configuration option (consistent with the existing gtr.hook.postCreate / gtr.hook.preRemove / gtr.hook.postRemove pattern):

git gtr config set gtr.hook.postCd "source ./vars.sh"

The shell integration wrapper generated by git gtr init zsh|bash|fish would then execute the configured hook(s) after the cd succeeds:

# Rough idea for the zsh wrapper
gtr() {
  if [ "$#" -gt 0 ] && [ "$1" = "cd" ]; then
    shift
    local dir
    dir="$(command git gtr go "$@")" && cd "$dir" && <run postCd hooks>
  else
    command git gtr "$@"
  fi
}

This keeps the hook configurable per-repo (via --local) and doesn't require overriding the shell wrapper.

Why not alternatives?

  • direnv: Only exports environment variables — shell functions and other side-effects from sourced scripts are lost. Also requires separate tooling installation.
  • Overriding the gtr wrapper: Works but fragile — breaks on upgrades and can't be shared via source control.
  • gtr.hook.postCreate: Only runs at worktree creation, not on subsequent cds.

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