Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/js-git-status-detached-substring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"e2b": patch
---

Fix `parseGitStatus` so a branch or upstream whose name merely contains the substring `detached` (for example `main` tracking `origin/detached-work`) is no longer misreported as a detached HEAD. Detached-HEAD detection now keys off the `HEAD (detached at <sha>)` / `HEAD (no branch)` porcelain forms only, so `currentBranch` and `upstream` are preserved. This mirrors the Python SDK fix for the same defect (#1373).
4 changes: 1 addition & 3 deletions packages/js-sdk/src/sandbox/git/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,7 @@ export function parseGitStatus(output: string): GitStatus {
aheadStart === -1 ? undefined : branchInfo.slice(aheadStart + 2, -1)
const normalizedBranch = normalizeBranchName(branchPart)
const rawBranch = branchPart
const isDetached =
rawBranch.startsWith('HEAD (detached at ') ||
rawBranch.includes('detached')
const isDetached = rawBranch.startsWith('HEAD (detached at ')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply the detached-status fix to the Python SDK too

Because this commit changes an SDK package, the root AGENTS.md requires equivalent JS and Python SDK changes. This line fixes only the JS parser, but packages/python-sdk/e2b/sandbox/_git/parse.py still has "detached" in raw_branch, and both sync and async Python git.status() paths call that parser, so Python users on a normal branch/upstream like main...origin/detached-work will still get detached=True with branch/upstream dropped while the changeset claims the defect is fixed.

Useful? React with 👍 / 👎.


if (isDetached || normalizedBranch.startsWith('HEAD')) {
detached = true
Expand Down
31 changes: 31 additions & 0 deletions packages/js-sdk/tests/git.parseStatus.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect, test } from 'vitest'

import { parseGitStatus } from '../src/sandbox/git/utils'

// Twin of the Python fix in PR #1374 (issue #1373): `parseGitStatus` used to flag
// `detached: true` for any branch/upstream name merely containing the substring
// "detached", dropping `currentBranch`/`upstream` for ordinary branches.

test('upstream whose name contains "detached" is not a detached HEAD', () => {
// Branch 'main' tracking 'origin/detached-work': NOT a detached HEAD.
const status = parseGitStatus('## main...origin/detached-work\n')
expect(status.detached).toBe(false)
expect(status.currentBranch).toBe('main')
expect(status.upstream).toBe('origin/detached-work')
})

test('local branch whose name contains "detached" is not a detached HEAD', () => {
const status = parseGitStatus('## feature/detached-session-fix\n')
expect(status.detached).toBe(false)
expect(status.currentBranch).toBe('feature/detached-session-fix')
})

test('real detached HEAD ("## HEAD (no branch)") is still detected', () => {
const status = parseGitStatus('## HEAD (no branch)\n')
expect(status.detached).toBe(true)
})

test('real detached HEAD ("## HEAD (detached at <sha>)") is still detected', () => {
const status = parseGitStatus('## HEAD (detached at 1a2b3c4)\n')
expect(status.detached).toBe(true)
})