Integrated repository, worktree, git stacker, and project manager
0

Configure Feed

Select the types of activity you want to include in your feed.

Rename pm-git-guard zsh helpers to __ prefix for Claude Code compatibility

Claude Code captures a zsh shell snapshot at session start and replays
it in every Bash tool subprocess (non-interactive). Before v2.1.47 the
capture logic dropped function names beginning with __ (double
underscore); with v2.1.47+ it does capture `__`-prefixed functions
but still drops single-underscore names like `_pm_git_guard_parse`.

Result in Claude's shell: the top-level `git()` wrapper came through
fine, but its helpers did not. Every `git …` call printed two
`command not found` warnings before the real git ran. Functionally
harmless but noisy on every tool call, with the guard silently failing
open.

Fix: rename the helpers and the sentinel variable to double-underscore:

_pm_git_guard_parse -> __pm_git_guard_parse
_pm_git_guard_should_block -> __pm_git_guard_should_block
_pm_git_guard_check -> __pm_git_guard_check
_pm_git_guard_cwd -> __pm_git_guard_cwd
_pm_git_guard_subcommand -> __pm_git_guard_subcommand
_PM_GIT_GUARD_LOADED -> __PM_GIT_GUARD_LOADED

Verified: after a session reload the fresh snapshot captures all 11
references, and `git …` runs with no stderr warnings. Interactive
shell behavior is unchanged.

Jordan Isaacs (Apr 23, 2026, 9:22 AM UTC) 11aabbff 1a827afd

+13 -13
+13 -13
integrations/pm-git-guard.zsh
··· 7 7 # `pm stacker guard no-rebase` whether the current branch is tracked by pm 8 8 # stacker. If so, the command is blocked with a guidance message. 9 9 10 - if [[ -n "${_PM_GIT_GUARD_LOADED:-}" ]]; then 10 + if [[ -n "${__PM_GIT_GUARD_LOADED:-}" ]]; then 11 11 return 0 12 12 fi 13 - typeset -g _PM_GIT_GUARD_LOADED=1 13 + typeset -g __PM_GIT_GUARD_LOADED=1 14 14 15 - _pm_git_guard_parse() { 16 - typeset -g _pm_git_guard_cwd="$PWD" 17 - typeset -g _pm_git_guard_subcommand="" 15 + __pm_git_guard_parse() { 16 + typeset -g __pm_git_guard_cwd="$PWD" 17 + typeset -g __pm_git_guard_subcommand="" 18 18 19 19 local cwd="$PWD" 20 20 local i=1 ··· 48 48 --) 49 49 (( i += 1 )) 50 50 if (( i <= $# )); then 51 - typeset -g _pm_git_guard_subcommand="${@[i]}" 51 + typeset -g __pm_git_guard_subcommand="${@[i]}" 52 52 fi 53 53 break 54 54 ;; ··· 56 56 (( i += 1 )) 57 57 ;; 58 58 *) 59 - typeset -g _pm_git_guard_subcommand="$arg" 59 + typeset -g __pm_git_guard_subcommand="$arg" 60 60 break 61 61 ;; 62 62 esac 63 63 done 64 64 65 - typeset -g _pm_git_guard_cwd="$cwd" 65 + typeset -g __pm_git_guard_cwd="$cwd" 66 66 } 67 67 68 - _pm_git_guard_should_block() { 68 + __pm_git_guard_should_block() { 69 69 case "$1" in 70 70 pull|rebase) 71 71 return 0 ··· 76 76 esac 77 77 } 78 78 79 - _pm_git_guard_check() { 79 + __pm_git_guard_check() { 80 80 local guard_cwd="$1" 81 81 82 82 command -v pm >/dev/null 2>&1 || return 0 ··· 98 98 } 99 99 100 100 git() { 101 - _pm_git_guard_parse "$@" 102 - if _pm_git_guard_should_block "$_pm_git_guard_subcommand"; then 103 - _pm_git_guard_check "$_pm_git_guard_cwd" || return $? 101 + __pm_git_guard_parse "$@" 102 + if __pm_git_guard_should_block "$__pm_git_guard_subcommand"; then 103 + __pm_git_guard_check "$__pm_git_guard_cwd" || return $? 104 104 fi 105 105 command git "$@" 106 106 }