On Windows, Cursor keeps an open handle on .git/HEAD, which prevents Git from updating the current branch pointer. Any git switch / git checkout fails with:
error: couldn’t set ‘HEAD’ fatal: unable to update HEAD
This happens even when:
terminal.integrated.shellIntegration.enabled is set to false (global)
Those processes are Cursor’s Node.js helper services (extension hosts, the terminal host, file watchers, and similar). They all share that exact command line, so the last step is to map each PID to its role using Cursor’s built-in process viewer:
Reproduce the failure (Cursor open, git switch failing).
Re-run your handle check so you have a current list of the PIDs holding .git\HEAD.
In Cursor, press Ctrl+Shift+P to open the Command Palette.
Type Process Explorer and press Enter. A separate window opens listing every Cursor process with its PID and a name such as extensionHost, fileWatcher, ptyHost, or shared-process.
Find each PID from step 2 in that window and note the name shown for it. A screenshot of the Process Explorer window is also fine.
Reply with that PID-to-name mapping.
Also helpful: how many Cursor windows you had open at the time, and which extensions you have installed (especially git related ones).
If the holders turn out to be extension host processes, one more test would tell us a lot: close all Cursor windows except the one with this repo, run “Developer: Reload With Extensions Disabled” from the Command Palette, then try git switch again and let us know if it still fails.