Skip to content

feat(git): fail-fast SSH and HTTP env for network fetch (PR C) - #23

Open
bschellenberger2600 wants to merge 12 commits into
cursor/run-cancel-signals-971dfrom
cursor/network-failfast-env-971d
Open

bschellenberger2600 wants to merge 12 commits into
cursor/run-cancel-signals-971dfrom
cursor/network-failfast-env-971d

Conversation

@bschellenberger2600

Copy link
Copy Markdown
Member

Stacked stall-review fix 3/3. Base: cursor/run-cancel-signals-971d (PR B).

Summary

  • Extend PrepareNetworkGit (git-rain wrapper) after git-harness GIT_TERMINAL_PROMPT=0:
    • Set GIT_SSH_COMMAND with -o BatchMode=yes -o ConnectTimeout=30 only when GIT_SSH_COMMAND is unset and the repo has no core.sshCommand.
    • Set GIT_HTTP_LOW_SPEED_LIMIT / GIT_HTTP_LOW_SPEED_TIME when unset.
  • Document fetch_timeout_sec, --fetch-timeout, GIT_RAIN_GLOBAL_FETCH_TIMEOUT_SEC, and fail-fast env behavior in README and AGENTS.md.

Tests

  • TestPrepareNetworkGit_SetsFailFastEnv
  • TestPrepareNetworkGit_PreservesUserGitSSHCommand
  • TestPrepareNetworkGit_PreservesCoreSSHCommand
  • TestPrepareNetworkGit_PreservesUserHTTPLowSpeed

Exit code policy

Unreachable remotes still exit 0 (frozen); only Ctrl-C / run interrupt exits non-zero from PR B.

Verification

Open in Web Open in Cursor 

Extend PrepareNetworkGit with batch-mode SSH (when GIT_SSH_COMMAND and
core.sshCommand are unset) and HTTP low-speed limits when unset. Document
fetch_timeout_sec, --fetch-timeout, and GIT_RAIN_GLOBAL_FETCH_TIMEOUT_SEC.

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: aaf107d1-3e25-4794-8bce-0a2e1ab0f097

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

…into cursor/network-failfast-env-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Fail-fast SSH overrides GIT_SSH
    • Skip GIT_SSH_COMMAND injection when GIT_SSH is already set so custom SSH wrappers are not overridden.
  • ✅ Fixed: Fail-fast test ignores global config
    • core.sshCommand probes now use cmd.Env, and tests null out global/system gitconfig so injection assertions stay deterministic.

Create PR

Or push these changes by commenting:

@cursor push 1edbefaa2b
Preview (1edbefaa2b)
diff --git a/internal/git/command.go b/internal/git/command.go
--- a/internal/git/command.go
+++ b/internal/git/command.go
@@ -9,7 +9,7 @@
 // PrepareNetworkGit configures cmd for fetch/push operations that may contact
 // a remote. Delegates to git-harness for GIT_TERMINAL_PROMPT=0, then adds
 // fail-fast SSH and HTTP env unless the user already set GIT_SSH_COMMAND,
-// GIT_HTTP_LOW_SPEED_*, or core.sshCommand in the repo.
+// GIT_SSH, GIT_HTTP_LOW_SPEED_*, or core.sshCommand.
 func PrepareNetworkGit(cmd *exec.Cmd) {
 	harnessgit.PrepareNetworkGit(cmd)
 	applyFailFastNetworkEnv(cmd)

diff --git a/internal/git/command_test.go b/internal/git/command_test.go
--- a/internal/git/command_test.go
+++ b/internal/git/command_test.go
@@ -18,10 +18,14 @@
 }
 
 func isolatedPrepareNetworkEnv(t *testing.T) []string {
+	t.Helper()
 	return []string{
 		"PATH=" + os.Getenv("PATH"),
 		"HOME=" + os.Getenv("HOME"),
 		"USER=" + os.Getenv("USER"),
+		// Keep core.sshCommand probes from picking up the developer's global config.
+		"GIT_CONFIG_GLOBAL=/dev/null",
+		"GIT_CONFIG_SYSTEM=/dev/null",
 	}
 }
 
@@ -60,6 +64,20 @@
 	}
 }
 
+func TestPrepareNetworkGit_PreservesUserGitSSH(t *testing.T) {
+	repo := testutil.CreateTestRepo(t, testutil.RepoOptions{Name: "failfast-user-git-ssh"})
+	cmd := exec.Command("git", "fetch", "--all")
+	cmd.Dir = repo
+	cmd.Env = append(isolatedPrepareNetworkEnv(t), "GIT_SSH=/usr/bin/custom-ssh")
+	PrepareNetworkGit(cmd)
+
+	for _, e := range cmd.Env {
+		if strings.HasPrefix(e, "GIT_SSH_COMMAND=") {
+			t.Fatalf("should not set GIT_SSH_COMMAND when GIT_SSH is set, got %s", e)
+		}
+	}
+}
+
 func TestPrepareNetworkGit_PreservesCoreSSHCommand(t *testing.T) {
 	repo := testutil.CreateTestRepo(t, testutil.RepoOptions{Name: "failfast-core-ssh"})
 	runGit := exec.Command("git", "-C", repo, "config", "core.sshCommand", "ssh -o IdentityFile=/tmp/from-core")

diff --git a/internal/git/network_env.go b/internal/git/network_env.go
--- a/internal/git/network_env.go
+++ b/internal/git/network_env.go
@@ -21,7 +21,9 @@
 	env = setEnvIfUnset(env, "GIT_HTTP_LOW_SPEED_LIMIT", defaultHTTPLowSpeedLimit)
 	env = setEnvIfUnset(env, "GIT_HTTP_LOW_SPEED_TIME", defaultHTTPLowSpeedTimeSec)
 
-	if !envHasPrefix(env, "GIT_SSH_COMMAND=") && !repoHasCoreSSHCommand(cmd.Dir) {
+	// GIT_SSH_COMMAND overrides GIT_SSH; only inject when neither is set and
+	// core.sshCommand is unset (same preserve path as an explicit SSH wrapper).
+	if !envHasPrefix(env, "GIT_SSH_COMMAND=") && !envHasPrefix(env, "GIT_SSH=") && !repoHasCoreSSHCommand(cmd.Dir, env) {
 		sshCmd := fmt.Sprintf("ssh -o BatchMode=yes -o ConnectTimeout=%d", defaultSSHConnectTimeoutSec)
 		env = append(env, "GIT_SSH_COMMAND="+sshCmd)
 	}
@@ -47,10 +49,12 @@
 	return false
 }
 
-func repoHasCoreSSHCommand(repoDir string) bool {
+func repoHasCoreSSHCommand(repoDir string, env []string) bool {
 	if strings.TrimSpace(repoDir) == "" {
 		return false
 	}
-	out, err := exec.Command("git", "-C", repoDir, "config", "--get", "core.sshCommand").Output()
+	cmd := exec.Command("git", "-C", repoDir, "config", "--get", "core.sshCommand")
+	cmd.Env = env
+	out, err := cmd.Output()
 	return err == nil && strings.TrimSpace(string(out)) != ""
 }

You can send follow-ups to the cloud agent here.

Comment thread internal/git/network_env.go Resolved
Comment thread internal/git/command_test.go Resolved
cursoragent and others added 7 commits October 11, 2026 11:10
Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
…into cursor/network-failfast-env-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
…into cursor/network-failfast-env-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
… gitconfig

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
…-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
…-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: SSH probe ignores command environment
    • repoHasCoreSSHCommand now runs git config with the command Env so GIT_CONFIG isolation and custom environments are honored when deciding to inject GIT_SSH_COMMAND.

Create PR

Or push these changes by commenting:

@cursor push 09ca40a6f0
Preview (09ca40a6f0)
diff --git a/internal/git/network_env.go b/internal/git/network_env.go
--- a/internal/git/network_env.go
+++ b/internal/git/network_env.go
@@ -21,7 +21,7 @@
 	env = setEnvIfUnset(env, "GIT_HTTP_LOW_SPEED_LIMIT", defaultHTTPLowSpeedLimit)
 	env = setEnvIfUnset(env, "GIT_HTTP_LOW_SPEED_TIME", defaultHTTPLowSpeedTimeSec)
 
-	if !envHasPrefix(env, "GIT_SSH_COMMAND=") && !envHasPrefix(env, "GIT_SSH=") && !repoHasCoreSSHCommand(cmd.Dir) {
+	if !envHasPrefix(env, "GIT_SSH_COMMAND=") && !envHasPrefix(env, "GIT_SSH=") && !repoHasCoreSSHCommand(cmd.Dir, env) {
 		sshCmd := fmt.Sprintf("ssh -o BatchMode=yes -o ConnectTimeout=%d", defaultSSHConnectTimeoutSec)
 		env = append(env, "GIT_SSH_COMMAND="+sshCmd)
 	}
@@ -47,10 +47,12 @@
 	return false
 }
 
-func repoHasCoreSSHCommand(repoDir string) bool {
+func repoHasCoreSSHCommand(repoDir string, env []string) bool {
 	if strings.TrimSpace(repoDir) == "" {
 		return false
 	}
-	out, err := exec.Command("git", "-C", repoDir, "config", "--get", "core.sshCommand").Output()
+	probe := exec.Command("git", "-C", repoDir, "config", "--get", "core.sshCommand")
+	probe.Env = env
+	out, err := probe.Output()
 	return err == nil && strings.TrimSpace(string(out)) != ""
 }

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit b61bc2d. Configure here.

Comment thread internal/git/network_env.go Resolved
cursoragent and others added 3 commits October 13, 2026 12:23
…-971d

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
Skip BatchMode GIT_SSH_COMMAND injection when GIT_SSH is set, and run
core.sshCommand probes with the command env so tests can null out global
gitconfig via GIT_CONFIG_GLOBAL/SYSTEM.

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
Pass the prepared command environment into the SSH config probe so
GIT_CONFIG_* isolation (and any custom Env) is respected when deciding
whether to inject fail-fast GIT_SSH_COMMAND.

Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>
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