Commit Diff


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 <message> <paths>` |
-| Rollback           | `got revert -R <paths>`           |
-| 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 <message> <paths>`         |
+| Rollback           | `got revert -R <paths>`                   |
+| 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}"