Repository navigation
fix(extensions): stop the git extension's fetch from waiting on a credential prompt - #5201
Open
JakkulaVeerababu wants to merge 1 commit into
Open
JakkulaVeerababu wants to merge 1 commit into
JakkulaVeerababu wants to merge 1 commit into
Conversation
…dential prompt Before it numbers a new feature branch, the git extension runs `git fetch --all --prune` with its output redirected. Git writes credential prompts to the terminal, not to stdout or stderr, so an HTTPS remote without a usable credential helper makes the fetch wait for a username that nobody types. speckit.git.feature is the mandatory before_specify hook, so /speckit.specify appears to hang in agent sessions. The dry-run path already ran ls-remote with GIT_TERMINAL_PROMPT=0; the fetch path did not. Set GIT_TERMINAL_PROMPT=0 for that fetch in the Bash, PowerShell and Python scripts. The PowerShell script restores the caller's value (or removes the variable when it was unset). A failed fetch is still ignored, as before. Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JakkulaVeerababu
marked this pull request as ready for review
October 31, 2026 02:03
This branch has not been deployed
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.
Description
Fixes #5199
Before it numbers a new feature branch, the git extension runs
git fetch --all --prunewith its output redirected. Git writes credential prompts to the terminal, not to stdout or stderr. So when a remote uses HTTPS and has no usable credential helper, the fetch stops atUsername for 'https://github.com':and waits.speckit.git.featureis the mandatorybefore_specifyhook, so in an agent session/speckit.specifyappears to hang. The dry-run path already runsls-remotewithGIT_TERMINAL_PROMPT=0. The fetch path did not.This PR sets
GIT_TERMINAL_PROMPT=0for that fetch in all three scripts:GIT_TERMINAL_PROMPT=0 git fetch --all --prune >/dev/null 2>&1 || trueenv={**os.environ, "GIT_TERMINAL_PROMPT": "0"}on the fetchsubprocess.runtry/finally, then restores the caller's value (or removes the variable if it was unset), so nothing leaks into the calling session.A failed fetch is still ignored, as before. Numbering then uses local branches and
specs/.Out of scope: SSH passphrase prompts.
GIT_TERMINAL_PROMPTdoes not cover them, and forcingssh -o BatchMode=yeswould override a user's ownGIT_SSH_COMMANDorcore.sshCommand. That is the open question in the bug assessment, so I left it for a separate decision.Testing
The new tests use a probe remote. It is an
ssh://URL whosecore.sshCommandrecords theGIT_TERMINAL_PROMPTvalue it inherits from the fetch (orls-remote), then fails. No network is used.TestCreateFeatureBash::test_remote_lookup_disables_terminal_prompt[fetch|dry-run]TestCreateFeaturePowerShell::test_remote_lookup_disables_terminal_prompt[fetch|dry-run]TestCreateFeaturePowerShell::test_fetch_restores_caller_terminal_prompt[set|unset]TestCreateFeatureBranchParity::test_fetch_disables_terminal_prompt(Bash and Python twins)Results on Ubuntu 26.04 (WSL2), Python 3.13, bash 5.3, pwsh 7.6.8, git 2.53:
mainwith only the new tests: 5 failed, 2 passed. The probe sawunseton the fetch path. The two dry-run cases already passed.tests/extensions/git: 181 passed, 2 skipped.test_*_python_parity.py) also fail on unmodifiedmainin this environment. They do not touch the git extension.shellcheck --severity=erroron the changed Bash script: clean.Windows PowerShell 5.1 (5.1.26100, Desktop edition) with Git for Windows 2.55, same probe remote, non-dry-run:
GIT_TERMINAL_PROMPTseen by the fetchmainunset0101uv run specify --helpuv sync --extra test, then.venv/bin/python -m pytest, as AGENTS.md recommends)Manual test results
Agent: Claude Code (Claude Opus 5.5), autonomous | OS/Shell: Ubuntu 26.04 on WSL2 / bash 5.3, pwsh 7.6.8, python 3.13
Each project was scaffolded from the branch under test with
specify init <dir> --integration claude --script {sh,ps,py} --extension git. Its only remote washttps://github.com/github/spec-kit-issue-5199-does-not-exist.git(answers 401), with no credential helper. The agent ran the script line thatspeckit.git.featureinstructs it to run, under a pseudo-terminal whose stdin stays open and silent, like an agent terminal that nobody types into. The script lines were run directly, not from an interactive agent session.main/speckit.git.feature(Bash script)Username for 'https://github.com':, killed after 20 s, no branch001-probecreated/speckit.git.feature(PowerShell script)001-probecreated/speckit.git.feature(Python script)001-probecreatedTest selection reasoning
extensions/git/scripts/bash/create-new-feature-branch.sh/speckit.git.feature, and/speckit.specifythrough thebefore_specifyhookextensions/git/scripts/powershell/create-new-feature-branch.ps1extensions/git/scripts/python/create_new_feature_branch.pytests/extensions/git/*.pyRequired tests
/speckit.git.feature, once per script flavour. The rest of/speckit.specifyis unchanged; its only changed step is this hook.AI Disclosure
AI disclosure: Claude Code (model: Claude Opus 5.5, maximum reasoning effort) ran autonomously on behalf of the account owner, JakkulaVeerababu. It did the investigation, wrote the code change in all three scripts and the tests, ran the checks above, and wrote this description. The commit has an
Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous)trailer. The account owner had not reviewed the change line by line when this PR was opened. That is why it is a draft: they will review it and then mark it ready.🤖 Generated with Claude Code