fix(openemr-cmd): avoid SIGPIPE in worktree validation under pipefail#784
Merged
kojiromike merged 3 commits intoJun 6, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a correctness issue in openemr-cmd worktree validation when running under set -o pipefail with many worktrees, by eliminating a git ... | grep -q pipeline that can trigger SIGPIPE and produce false negatives.
Changes:
- Replace
git worktree list --porcelain | grep -Fqx ...with a “capture then grep via herestring” approach inwt_validate_dirandwt_validate_dir_safe. - Add explanatory comments documenting the
SIGPIPE/pipefailfailure mode. - Bump script version to
1.0.40.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
wt_validate_dir and wt_validate_dir_safe piped 'git worktree list --porcelain' into 'grep -Fqx'. Under 'set -o pipefail', grep -q exits on the first match and closes the pipe; git, still writing the remaining entries, takes SIGPIPE and exits 141. pipefail then reports the whole pipeline as failed, so a path that IS a registered worktree is rejected. This only triggers once git's output exceeds the pipe buffer (~64KB), i.e. with many worktrees, which is why it stays latent on typical setups. The symptom is 'worktree list' showing "(no worktrees)" and 'worktree remove' aborting with "is not a registered git worktree". Capture the listing into a variable and match it with a herestring, eliminating the pipe (and the SIGPIPE) entirely. Assisted-by: Claude Code
… fix The pipefail/SIGPIPE fix added 7 net lines above the function-definition boundary, so sourcing head -n 1446 cut mid-function and every pure-helper test failed with "syntax error: unexpected end of file". Move the boundary to 1452, the closing brace of the last function before USAGE_EXIT_CODE. Assisted-by: Claude Code
06c7694 to
538e505
Compare
Splitting the 'git worktree list | grep' pipeline into a standalone command substitution changed its set -e behavior: previously git's exit status was masked inside the 'if ! ...' test, but a bare assignment now aborts the script if git fails. Restore the original contract — wt_die with a clear message in the fatal variant, 'return 1' in the safe one — by handling the substitution's exit explicitly. Bump OC_SCRIPT_FUNCS_END for the added continuation line. Assisted-by: Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
openemr-cmd worktree listandworktree removecan fail on setups with many git worktrees:listshows(no worktrees)even when entries exist, andremoveaborts withPath '...' is not a registered git worktree.Root cause
wt_validate_dirandwt_validate_dir_safevalidate a path by piping git's worktree listing intogrep:The script runs under
set -o pipefail.grep -qexits as soon as it finds a match and closes the read end of the pipe. If git is still writing (its output exceeds the ~64KB pipe buffer, which happens once you have many worktrees), git receivesSIGPIPEand exits 141. Underpipefailthe pipeline's exit status becomes that 141, so theif !branch fires and a path that is a registered worktree gets rejected.This stays latent on typical setups where git's output fits in the pipe buffer and git finishes writing before
grepexits — the SIGPIPE never happens.Fix
Capture the listing into a variable first, then match with a herestring. No pipe means no SIGPIPE:
Test plan
shellcheckclean under the repo's.shellcheckrc(enable=all)bash -npassespipefail(pipeline exits 141); the herestring form returns 0worktree listshows the entry andworktree removecompletes cleanly (both previously broken)Note
Found while verifying #783 (the macOS realpath fix). That fix let execution finally reach this validation code, surfacing this separate, platform-independent bug. The two are independent; this PR stands alone.