Skip to content

Instantly share code, notes, and snippets.

@muratkeremozcan
Last active July 9, 2026 16:58
Show Gist options
  • Select an option

  • Save muratkeremozcan/e4b21950529152811caafdff8df00f98 to your computer and use it in GitHub Desktop.

Select an option

Save muratkeremozcan/e4b21950529152811caafdff8df00f98 to your computer and use it in GitHub Desktop.
treehouse config
# User-level treehouse config (applies to every repo's pool).
# Repo-level treehouse.toml hooks are ignored for safety, so this is the
# only place hooks can live.
[hooks]
# Runs after a worktree is provisioned/reset, right before it's handed to you.
# `treehouse get` already runs `git fetch origin` before this point, so refs
# are fresh; these hooks only need to act on them. Both resolve the source
# repo via git's worktree->common-dir link, so they work for any repo.
# 1. Copy the source repo's gitignored .env (if any) into the fresh worktree.
post_create = ['repo_root=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)"); if [ -f "$repo_root/.env" ]; then cp "$repo_root/.env" .; fi',
# 2. Detach onto whatever branch is currently checked out in the source
# repo (the branch your agent is actively working on), switch Node to
# whatever .nvmrc asks for (some repos enforce this and fail install
# otherwise), then install deps with whichever package manager the repo
# uses. nvm has to be sourced + used in this same shell invocation so its
# PATH change actually applies to the install command right after it.
'repo_root=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)"); if [ -n "$TREEHOUSE_BASE_REF" ]; then git checkout "$TREEHOUSE_BASE_REF" -q 2>/dev/null || true; else branch=$(git -C "$repo_root" branch --show-current); if [ -n "$branch" ]; then if git rev-parse --verify -q "origin/$branch" >/dev/null 2>&1; then git checkout "origin/$branch" -q 2>/dev/null || true; else local_ref=$(git -C "$repo_root" rev-parse "$branch" 2>/dev/null); if [ -n "$local_ref" ]; then git checkout "$local_ref" -q 2>/dev/null || true; fi; fi; fi; fi; export NVM_DIR="$HOME/.nvm"; if [ -s "$NVM_DIR/nvm.sh" ]; then . "$NVM_DIR/nvm.sh"; fi; if [ -f .nvmrc ] && command -v nvm >/dev/null 2>&1; then nvm install "$(cat .nvmrc)" >/dev/null 2>&1; nvm use "$(cat .nvmrc)" >/dev/null 2>&1; fi; if [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile; elif [ -f yarn.lock ]; then yarn install --frozen-lockfile; elif [ -f package-lock.json ]; then npm ci; elif [ -f package.json ]; then npm install; fi',
# 3. Some tools assume sibling repos are checked out next to the source repo
# (e.g. this bot's supplementary-repo lookup). Generic, repo-agnostic fix:
# mirror every sibling directory of the source repo as a symlink in the
# worktree slot, whatever it/they may be. No knowledge of any specific
# repo's config or schema.
'repo_root=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)"); parent=$(dirname "$repo_root"); me=$(basename "$repo_root"); for d in "$parent"/*/; do name=$(basename "$d"); if [ "$name" != "$me" ] && [ ! -e "../$name" ]; then ln -sfn "${d%/}" "../$name"; fi; done']
@muratkeremozcan

muratkeremozcan commented Jul 9, 2026

Copy link
Copy Markdown
Author

Why treehouse?

A plain git worktree gives you isolation, but nothing else.

A fresh worktree drops you in detached HEAD on the wrong branch, with no .env, no dependencies installed, and none of the sibling repos your tooling might expect next door.

For my usecases, this is only for repetitive, disposable work off a single branch; e.g. spinning up many agent sessions against the same base.
Imho, for juggling arbitrary branches/PRs, a plain clone is still simpler, without the usability challenges.


post_create` hook of treehouse, can be used to improve the DX and hand-off a ready environment:

  1. copies .env over (because by default gitignored files never travel with a checkout)
  2. checks out whatever branch you're actually working on, then npm ci, not npm install, which may be quietly rewriting the lockfile and marking every worktree "dirty" for no reason
  3. symlinks every sibling folder next to your repo into the worktree, so anything expecting sibling checkouts still finds them

After installing treehouse, copy the above over to ~/.config/treehouse/config.toml

treehouse                                         # get worktree, on your branch, deps ready
treehouse status                              # see what's out there
exit                                                     # done, returns to pool
treehouse destroy <path> --yes     # nuke one
treehouse destroy . --all --yes        # nuke all disposable ones

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment