You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
postCreate hooks silently stop if a hook reads from stdin #164
If a postCreate hook runs a command that reads from stdin, all subsequent hooks are silently skipped.
Root cause
run_hooks iterates over hooks using a heredoc:
while IFS= read -r hook;do
( eval"$hook" ) # subshell inherits stdin = the heredocdone<<EOF$hooksEOF
Each hook's subshell inherits the parent's stdin, which is the heredoc itself. A command that reads stdin drains the remaining lines, so subsequent read -r hook calls get nothing and the loop exits early.
Minimal reproduction
.gtrconfig:
[hooks]postCreate = "echo 'hook 1: before stdin read'"postCreate = "cat"postCreate = "echo 'hook 3: this should run but does not'"
Output of gtr new test-branch:
[OK] Hook 1: echo 'hook 1: before stdin read'
hook 1: before stdin read
[OK] Hook 1 completed successfully
[OK] Hook 2: cat
echo 'hook 3: this should run but does not'
[OK] Hook 2 completed successfully
[OK] Worktree created: ...
Hook 3 never runs. Its command text is visibly consumed and printed by cat.
# Run hook in subshell with properly quoted environment exportsif (
# Export each KEY=VALUE exactly as passed, safely quotedforkvin"${envs[@]}";do# shellcheck disable=SC2163export"$kv"done# Execute the hookeval"$hook"
);then
After:
# Run hook in subshell with properly quoted environment exportsif (
# Export each KEY=VALUE exactly as passed, safely quotedforkvin"${envs[@]}";do# shellcheck disable=SC2163export"$kv"done# Execute the hookeval"$hook"
) </dev/null;then
Workaround
Add </dev/null to any hook that may read from stdin:
Activity
fix(hooks): prevent stdin drain from skipping subsequent hooks
fix(hooks): prevent stdin drain from skipping subsequent hooks (#165)