commit 1723d2ac5388915746d7cd9c84279116898690a1 from: ale date: Fri Jul 24 04:53:46 2026 UTC Fix EDT violation in GotRepository.getCurrentBranchName() Reported in vivo: the branch widget never showed anything, and opening the Push dialog hit 'Synchronous execution on EDT' (got info run directly from PushController.createTreeModel on the UI thread) -- the same category of bug fixed earlier for GotContentRevision. getCurrentBranchName()/getCurrentRevision() now return cached fields instead of shelling out to got info on every call. State is read once eagerly on construction and refreshed in update(), which the platform calls off the EDT during a repository refresh cycle. commit - 7ec62b12361bdec10782a2cd24c4125cf0585d98 commit + 1723d2ac5388915746d7cd9c84279116898690a1 blob - 4fb1f50fbdb4bf46e11a89b1330a03e41e92e66b blob + 5372625814924a4a0c2f9556c4ae58bbe4dda8f6 --- README.md +++ README.md @@ -29,17 +29,17 @@ There's no daemon and no cached repository model: ever the `got` binary for the relevant work tree and adapts its output to the corresponding IntelliJ Platform VCS API. -| IntelliJ feature | got command | -|--------------------|-----------------------------------| -| VCS root detection | presence of a `.got/` directory | -| File status | `got status` | -| Diff / gutter | `got cat -c :base` | -| Commit | `got commit -m ` | -| Rollback | `got revert -R ` | -| History | `got log` | -| Update Project | `got fetch` + `got update` | -| Branch widget | `got info` ("work tree branch reference") | -| Push | `got send` | +| IntelliJ feature | got command | +|--------------------|-------------------------------------------| +| VCS root detection | presence of a `.got/` directory | +| File status | `got status` | +| Diff / gutter | `got cat -c :base` | +| Commit | `got commit -m ` | +| Rollback | `got revert -R ` | +| History | `got log` | +| Update Project | `got fetch` + `got update` | +| Branch widget | `got info` ("work tree branch reference") | +| Push | `got send` | Source is organized by responsibility under `dev.nezzontli.gotvcs`: blob - 47adf6a68fa6f4aaa132832d08eb15c65b970ba4 blob + e2470fa0782c308ca8eb832b2d7afbb219786d40 --- src/main/kotlin/dev/nezzontli/gotvcs/repo/GotRepository.kt +++ src/main/kotlin/dev/nezzontli/gotvcs/repo/GotRepository.kt @@ -12,6 +12,14 @@ import dev.nezzontli.gotvcs.GotVcs import dev.nezzontli.gotvcs.cli.GotCommandLineWrapper import java.io.File +/** + * getCurrentBranchName()/getCurrentRevision() are called from UI code (the + * branch widget, the Push dialog's tree model) that runs on the EDT, so they + * cannot shell out to `got info` synchronously (IntelliJ's + * OSProcessHandler#checkEdtAndReadAction guard trips on that). State is + * read once eagerly and only re-read in update(), which the platform calls + * off the EDT during a repository refresh. + */ class GotRepository( private val project: Project, private val root: VirtualFile, @@ -21,10 +29,31 @@ class GotRepository( private var disposed = false + @Volatile + private var branch: String? = null + + @Volatile + private var revision: String? = null + init { Disposer.register(parentDisposable, this) + refreshState() } + private fun refreshState() { + val workDir = File(root.path) + branch = try { + commandLine.currentBranch(workDir) + } catch (e: VcsException) { + null + } + revision = try { + commandLine.baseCommit(workDir) + } catch (e: VcsException) { + null + } + } + override fun getRoot(): VirtualFile = root override fun getPresentableUrl(): String = root.presentableUrl @@ -33,23 +62,15 @@ class GotRepository( override fun getState(): Repository.State = Repository.State.NORMAL - override fun getCurrentBranchName(): String? = try { - commandLine.currentBranch(File(root.path)) - } catch (e: VcsException) { - null - } + override fun getCurrentBranchName(): String? = branch override fun getVcs(): AbstractVcs = ProjectLevelVcsManager.getInstance(project).findVcsByName(GotVcs.NAME)!! - override fun getCurrentRevision(): String? = try { - commandLine.baseCommit(File(root.path)) - } catch (e: VcsException) { - null - } + override fun getCurrentRevision(): String? = revision override fun isFresh(): Boolean = false - override fun update() = Unit + override fun update() = refreshState() override fun toLogString(): String = "GotRepository{root=$root}"