Skip to content

Clone, fetch, pull and push hang with no log line when git or ssh prompts for credentials on the terminal #519

Open

Description

@matt-edmondson

What's wrong

Every git command goes through GitCli.Run (ProjectDirector/GitCli.cs:91-107). It calls RunCommand.Execute("git", arguments, handler) with default options. Nothing sets GIT_TERMINAL_PROMPT=0, nothing makes ssh non-interactive (BatchMode), stdin isn't closed, and there's no timeout.

git's HTTPS credential prompt (Username for 'https://github.com':) reads from /dev/tty directly, wherever stdin and stdout point. ssh does the same when it asks to confirm a host key or for a key passphrase. If ProjectDirector is started from a terminal (dotnet run, as CLAUDE.md documents), the child git process inherits that controlling terminal. It then blocks on a prompt the user probably can't see, because the app window is in front. The background task never finishes. Its result reaches the log only after git exits (QueueGitLog, ProjectDirector.cs:264-271), so the log shows nothing.

Effects:

  • Clone: MakeClone (ProjectDirector.cs:831-832) clones the Octokit CloneUrl, which is HTTPS. CloneTracker keeps the path in flight until the action returns (CloneTracker.cs:63-82). The Clone button is drawn only when !Clones.IsInFlight(repo.LocalPath) (ProjectDirector.cs:737-739). A clone stuck on a prompt therefore hides the button for the rest of the session, and nothing is logged.
  • Fetch / pull / push (ProjectDirector.cs:458-468, 520-529, 654-660): these tasks never complete.

Failure scenario

  1. On Linux or macOS, have no credential.helper configured, or an expired cached token.
  2. Run dotnet run --project ProjectDirector from a terminal.
  3. Add an owner with a token so its private repositories are listed, then click Clone on a private repository.

The terminal shows Username for 'https://github.com':. The Clone button disappears and the log panel stays empty until someone answers the prompt or kills git. The same happens with an SSH remote whose host isn't in known_hosts, or with a key that has a passphrase and no agent.

Suggested fix

Pass a CommandOptions from GitCli.Run. ktsu.RunCommand, which is already referenced, supports EnvironmentVariables and StandardInput. Set:

  • GIT_TERMINAL_PROMPT=0. Missing HTTPS credentials then fail fast with terminal prompts disabled, and that message reaches the log.
  • GIT_SSH_COMMAND=ssh -o BatchMode=yes, but only when the user hasn't set GIT_SSH_COMMAND or core.sshCommand themselves.
  • StandardInput = StandardInputMode.Closed.

GUI credential helpers such as Git Credential Manager keep working, because they don't use the terminal.

Optionally, give clone, fetch, pull and push a generous cancellation timeout, so a stalled transfer is reported rather than held forever.

Acceptance criteria

  • Cloning or fetching a private HTTPS repository with no credential helper, from a terminal-launched app, ends within seconds.
  • The log shows the failure, including git's terminal prompts disabled message.
  • The Clone button reappears afterwards.
  • A GitCliTests case runs a network git command that would otherwise prompt, and asserts that it returns rather than blocks.

Related

Activity

  1. matt-edmondson commented on Oct 31, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions