Skip to content

fix(hooks): prevent stdin drain from skipping subsequent hooks#165

Merged
helizaga merged 7 commits intocoderabbitai:mainfrom
acevif:fix/hooks-stdin-drain
Apr 10, 2026
Merged

fix(hooks): prevent stdin drain from skipping subsequent hooks#165
helizaga merged 7 commits intocoderabbitai:mainfrom
acevif:fix/hooks-stdin-drain

Conversation

@acevif
Copy link
Copy Markdown
Contributor

@acevif acevif commented Apr 8, 2026

Summary

Fixes #164

All hook phases (postCreate, preRemove, postRemove, postCd) suffered from the same bug: a hook that reads from stdin (e.g. cat, read) drains the hook list input, causing all subsequent hooks to be silently skipped.

  • run_hooks: add </dev/null to the hook subshell (...) </dev/null
  • run_hooks_export: add </dev/null to the eval call (eval "$hook" </dev/null)
  • init shell integration (bash/zsh): add </dev/null to generated postCd hook execution so git gtr cd and git gtr new --cd are covered too

These changes prevent hook commands from inheriting the hook list as stdin while preserving existing behavior such as env var exports, exit code handling, and shell integration semantics.

Test plan

  • Regression tests for postCreate, preRemove, and postRemove verify cat between two hooks does not skip the third
  • Regression test for postCd via run_hooks_export
  • Regression tests for generated init bash/zsh wrappers verify gtr_run_post_cd_hooks continues after a stdin-reading hook
  • Targeted validation passes: bats tests/hooks.bats
  • Targeted validation passes: bats tests/init.bats

Summary by CodeRabbit

  • Bug Fixes

    • Hooks no longer consume the caller’s standard input; subsequent hooks reliably run even if an earlier hook reads stdin.
  • Tests

    • Added tests ensuring hook execution continues across stdin-reading hooks, including post-directory-change hooks for both Bash and Zsh.

acevif added 4 commits April 9, 2026 01:55
Add </dev/null to hook subshell to prevent commands that read stdin
(e.g. cat, read) from consuming the heredoc that feeds hook lines,
which caused all subsequent hooks to be silently skipped.

Fixes coderabbitai#164
Verify that a hook running `cat` (which reads stdin) does not
prevent subsequent hooks from executing.
Add </dev/null to eval in run_hooks_export so hooks that read stdin
(e.g. cat, read) do not consume the heredoc feeding hook lines,
which caused subsequent postCd hooks to be silently skipped.

Also adds a regression test for the postCd case.
@acevif acevif requested a review from NatoBoram as a code owner April 8, 2026 17:11
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d3ca5c6d-21c1-4212-b4e7-35e334d7cbd8

📥 Commits

Reviewing files that changed from the base of the PR and between ba4171e and e7c6ef1.

📒 Files selected for processing (1)
  • tests/init.bats

Walkthrough

Redirected stdin for hook execution to /dev/null so hooks that read stdin cannot consume the loop's input. Tests added to verify run_hooks, run_hooks_export, and generated postCd hooks continue executing subsequent hooks when an earlier hook reads from stdin.

Changes

Cohort / File(s) Summary
Hook runner core
lib/hooks.sh
Redirected stdin for each hook execution in run_hooks and run_hooks_export (eval "$hook" </dev/null) to prevent hooks from consuming the parent's heredoc/stdin.
Init hook invocation
lib/commands/init.sh
Added stdin redirection (</dev/null) to __FUNC___run_post_cd_hooks (Bash and Zsh) when evaling configured gtr.hook.postCd hooks.
Tests: run_hooks behavior
tests/hooks.bats
Added Bats tests asserting run_hooks and run_hooks_export continue running subsequent hooks when an earlier hook reads from stdin; verify ordering via a shared order file.
Tests: postCd generation
tests/init.bats
Added helper and tests for bash and zsh that run generated postCd hooks containing a stdin-consuming command and assert ordered output ORDER=first,third.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I munched the stdin, sly and small,
A hungry cat that trapped them all.
Now I hop past silence, neat and null,
Each hook awakens, one and full.
Hooray—no bites, just carrot-pull 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: fixing stdin drain issues that cause subsequent hooks to be skipped.
Linked Issues check ✅ Passed The pull request fully addresses issue #164 by implementing the suggested fix to redirect stdin from /dev/null in hooks, preventing stdin-consuming hooks from draining the heredoc and skipping subsequent hooks.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the stdin drain issue: modifications to run_hooks, run_hooks_export, and generated postCd hook execution, plus comprehensive regression tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@helizaga helizaga merged commit 025de7f into coderabbitai:main Apr 10, 2026
4 checks passed
@acevif acevif deleted the fix/hooks-stdin-drain branch April 10, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

postCreate hooks silently stop if a hook reads from stdin

2 participants