Skip to content

fix: resolve real git in test shims instead of hardcoding /usr/bin/git - #19

Open
felipelalli wants to merge 1 commit into
igorhvr:mainfrom
felipelalli:portable-git-shims-in-tests
Open

fix: resolve real git in test shims instead of hardcoding /usr/bin/git#19
felipelalli wants to merge 1 commit into
igorhvr:mainfrom
felipelalli:portable-git-shims-in-tests

Conversation

@felipelalli

Copy link
Copy Markdown

The mock git shims in merge-branch-cli.test.ts and run.test.ts install a script named git into a temp dir, prepend that dir to PATH, and delegate the non-mocked commands to /usr/bin/git.

That hardcoded path is not portable, and it fails in two different ways:

  • Where /usr/bin is an envfs mount — the default on NixOS with programs.nix-ld or envfs enabled — a lookup of /usr/bin/git is resolved against the caller's PATH. The caller here is the shim, whose own directory sits at the front of PATH, so /usr/bin/git resolves back to the shim and the delegation recurses without bound. On the machine this was found on, npm test never finished: the serial lane sat on run.test.ts for over an hour and the recursion had spawned ~71k processes before it was killed.
  • Where /usr/bin/git is simply absent (non-FHS systems generally) the failure is quicker but still wrong — two merge-branch-cli tests fail with ENOENT from the delegating spawn.

The fix resolves the real git once, via command -v git evaluated in the test process (whose PATH has not been shadowed), and bakes that absolute path into the generated shims. The resolved path points outside /usr/bin, so the delegation can no longer re-enter the shim on any system. On FHS systems this resolves to /usr/bin/git and behaviour is unchanged.

Results on the affected machine:

  • merge-branch-cli.test.ts: 13 pass / 2 fail → 15 pass
  • run.test.ts: hung indefinitely → 39 pass in 8.2s

The mock git shims in merge-branch-cli.test.ts and run.test.ts install a
script named `git` into a temp dir, prepend that dir to PATH, and delegate
the non-mocked commands to /usr/bin/git.

That hardcoded path is not portable. On systems where /usr/bin is an envfs
mount — the default on NixOS with programs.nix-ld or envfs enabled — a
lookup of /usr/bin/git is resolved against the *caller's* PATH. The caller
here is the shim, whose own directory sits at the front of PATH, so
/usr/bin/git resolves back to the shim and the delegation recurses without
bound. On this machine `npm test` never finished: the serial lane sat on
run.test.ts for over an hour and the recursion had spawned ~71k processes
before it was killed. On systems where /usr/bin/git is simply absent the
failure is quicker but still wrong — two merge-branch-cli tests fail with
ENOENT from the delegating spawn.

Resolve the real git once, via `command -v git` evaluated in the test
process (whose PATH has not been shadowed), and bake that absolute path
into the generated shims. The resolved path points outside /usr/bin, so
the delegation can no longer re-enter the shim on any system.

merge-branch-cli.test.ts: 13 pass / 2 fail -> 15 pass.
run.test.ts: hung indefinitely -> 39 pass in 8.2s.
Copilot AI review requested due to automatic review settings July 27, 2026 18:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a portability and correctness issue in test-only Git shims by resolving the real git binary once (before the shim shadows PATH) and delegating to that absolute path, rather than hardcoding /usr/bin/git. This prevents infinite recursion on envfs-mounted /usr/bin setups (e.g., NixOS) and avoids ENOENT failures on non-FHS systems.

Changes:

  • Add resolveRealGit() and a module-level REAL_GIT constant in two test files to capture an absolute git path from the unmodified PATH.
  • Update the generated shim scripts to delegate to ${REAL_GIT} instead of /usr/bin/git.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/installer/run.test.ts Resolve the real git once and update bash shim delegation to avoid /usr/bin/git recursion/absence.
src/cli/merge-branch-cli.test.ts Resolve the real git once and update the Node-based shim to spawn the resolved absolute path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants