Branch selection in Codex Desktop should be scoped to the selected git worktree/project root

Open 💬 5 comments Opened Apr 26, 2026 by bnfaf
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

0.124.0-alpha.2

What subscription do you have?

ChatGPT Business

What platform is your computer?

Darwin 24.1.0 arm64 arm

What issue are you seeing?

Codex Desktop does not clearly isolate branch selection by git worktree/project root.

I use Codex Desktop as a single developer working on multiple feature requests in parallel. Each feature request has its own git branch and git worktree. Because Codex tasks can take time to inspect code, run tests, build services, or resolve merge conflicts, I often need multiple Codex conversations running in parallel.

In this workflow, the Desktop app requires selecting a branch when starting a conversation. That branch selection appears to be scoped to the repository/main checkout rather than clearly scoped to the selected physical worktree/project root.

This makes parallel Codex conversations fragile. A conversation intended for one task/worktree can affect or confuse another workspace, especially the main checkout. In practice this leads to accidental branch switching, wrong-worktree edits, and repeated manual checks to recover the correct state.

What steps can reproduce the bug?

  1. Create a repo with two feature branches and two git worktrees.

Run these commands:

mkdir /tmp/codex-worktree-demo
cd /tmp/codex-worktree-demo
git init

echo "main" > file.txt
git add file.txt
git commit -m "init"

git checkout -b feature-a
echo "feature-a" > feature-a.txt
git add feature-a.txt
git commit -m "feature a"

git checkout main
git checkout -b feature-b
echo "feature-b" > feature-b.txt
git add feature-b.txt
git commit -m "feature b"

git checkout main
git worktree add /tmp/codex-worktree-demo.a feature-a
git worktree add /tmp/codex-worktree-demo.b feature-b

  1. Open /tmp/codex-worktree-demo in Codex Desktop.
  1. Open /tmp/codex-worktree-demo.a and /tmp/codex-worktree-demo.b as separate Desktop projects or conversations.
  1. Start a conversation for /tmp/codex-worktree-demo.a. When Codex Desktop requires selecting a branch, select feature-a.
  1. Start another conversation for /tmp/codex-worktree-demo.b. When Codex Desktop requires selecting a branch, select feature-b.
  1. Check the active branches and worktrees.

Run:

git -C /tmp/codex-worktree-demo branch --show-current
git -C /tmp/codex-worktree-demo.a branch --show-current
git -C /tmp/codex-worktree-demo.b branch --show-current
git -C /tmp/codex-worktree-demo worktree list

Actual behavior: branch selection in Codex Desktop is not clearly scoped to the selected physical worktree/project root. In multi-worktree usage, it can affect or confuse the main checkout or another worktree-backed conversation, which makes parallel Codex tasks fragile.

Session id: not applicable.
Token/context usage: not relevant.

What is the expected behavior?

Codex Desktop should treat each physical git worktree path as an independent project root.

Expected behavior:

  • One Codex Desktop conversation is bound to one selected project root/worktree.
  • Branch selection is scoped only to that selected worktree.
  • Selecting a branch for one conversation must not affect the main checkout or another worktree-backed conversation.
  • Branch switching should behave like: git -C <selected-worktree-path> checkout <branch>.
  • The UI should show the physical project root, for example the result of git rev-parse --show-toplevel.
  • If a branch action would affect a directory other than the selected project root, Codex Desktop should warn or block it.

Desired workflow:

  • One feature request = one git worktree.
  • One Codex Desktop conversation = one worktree/project root.
  • Branch selection = scoped only to that worktree.

Additional information

_No response_

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #19541

Powered by Codex Action

bnfaf · 4 months ago

Thanks for the duplicate detection. This is related to #19541, but my case adds a git worktree dimension.

#19541 describes branch selection leaking between threads in the same project. My issue is about the same class of problem, but in a single-developer workflow where each parallel feature request uses a separate git worktree.

Expected model:

  • one feature request = one git worktree
  • one Codex Desktop conversation = one physical worktree/project root
  • branch selection should be scoped to that worktree only

The current behavior makes it unclear whether branch selection is thread-scoped, project-scoped, or worktree-scoped. In a multi-worktree setup, this can cause a conversation intended for one worktree to affect or confuse another worktree/main checkout.

So I agree this is related to #19541, but I think worktree isolation should be explicitly covered as part of the fix.

nijanthan-dev · 3 months ago

Adding a concrete case from macOS where this caused real confusion.

Setup:

  • Primary checkout: /Users/niju/Developer/custom_apps/hybrid_apps/nen
  • Active branch there: fix/timer-idle-layout
  • Git status there: clean
  • Side Codex worktree: /Users/niju/.codex/worktrees/6d2d/nen
  • Old branch there: fix/live-activity-compact
  • That old branch had stale generated artifacts earlier and its remote branch had already been deleted

What the UI showed:
Codex Desktop branch picker still showed fix/live-activity-compact selected with Uncommitted: 4 files, even though the active work and verified git state were in the primary checkout on fix/timer-idle-layout.

Why this is confusing:
From the user point of view, the UI implies the current task still has uncommitted files or is on the wrong branch. In reality, the active worktree was clean and pushed. The dirty state belonged to a different or stale worktree context.

Expected behavior:

  • The branch picker should clearly show which physical worktree path it is reporting.
  • Dirty file counts should be scoped to that same path.
  • If the thread has stale association with an old Codex worktree, the UI should say that directly or offer to rebind.
  • A branch that has been deleted from remote should not look like the active branch for unrelated current work.

This is not just a branch preference issue. It makes users think Codex failed to commit, failed to switch branches, or is hiding uncommitted changes. It also pushes users into checking multiple worktrees manually to work out what is true.

Believorstudio · 10 days ago

Additional Windows Desktop evidence from version 26.810.7004.0:

During one active task bound to a single absolute local Git project root, repeated read-only checks returned three distinct branch/HEAD identities. The task had not issued a Git mutation before those changes were observed. While the same task was reading sources, the apparent Unity source root also changed between two layouts and a previously readable path disappeared. No data loss was observed, but evidence gathered earlier in the turn became invalid and the task was delayed while re-establishing source identity.

Sanitized observed sequence:

  1. project root -> branch A / commit A;
  2. same project root -> main / commit B;
  3. same project root -> branch C / commit C;
  4. only after explicit user instruction, the task itself switched back to main.

Expected behavior: an active task should remain bound to its selected physical checkout and branch/HEAD, or Desktop should explicitly signal and block when that binding changes. Tool calls in one turn should not silently project a different checkout. If another task or the branch selector would affect the same working directory, the app should fail closed or require confirmation.

Impact: risk of reading, validating, or editing the wrong source; previously collected evidence cannot safely be reused across the silent change. The local mitigation is to checkpoint repository/branch/HEAD at SessionStart and stop immediately on mismatch.

This report intentionally omits repository, organization, project, task, branch, commit, username, and absolute-path identifiers.

maxtalwar · 14 hours ago

Additional remote-session reproduction (2026-08-27):

  • Codex Desktop on a MacBook was connected to a separate Linux remote/app-server host.
  • Mac client: Codex App 26.820.60940.
  • In the branch picker, the remote repository branch main was shown as Uncommitted: 3 files.
  • Read-only checks against the exact remote project root showed a clean checkout:

git status --short --branch
## main...origin/main

git status --porcelain=v2 --untracked-files=all
(empty)

git diff --name-only
(empty)

git diff --cached --name-only
(empty)

  • Remote environment: codex-cli 0.147.0, Git 2.43.0, Linux x86_64 under WSL2.
  • The repository does use many linked worktrees. The primary checkout and the obvious feature worktrees checked were clean, so the count does not reflect actual changes in main.

This looks like the same worktree/path-scoping failure described here, with an important remote-session dimension: the Mac client branch picker appears to be using stale or incorrectly scoped dirty-state data from across the client/app-server boundary. The branch picker should query and display status for the exact physical worktree path bound to the task, and refresh after remote Git state changes. Related stale-cache issue: #31528.