commit - 4a9d1c555f6ed4615c6b891e5d20aa1c6b4644a0
commit + 7479a8a7b30eb85db1b28e9dd920a4f13791a563
blob - 433791abb5e6f61c2e92d3464a74c7e6b9489db3
blob + 013a80906f0cc310c026f4a16fa95ce921844391
--- build.gradle.kts
+++ build.gradle.kts
intellijIdea("2026.1.4")
}
bundledModule("com.intellij.modules.vcs")
+ // Repository/RepositoryManager and the DVCS status widget base
+ // classes live here, not under com.intellij.modules.vcs.
+ bundledModule("intellij.platform.vcs.dvcs")
+ bundledModule("intellij.platform.vcs.dvcs.impl")
}
}
blob - abc3903426b56dde246cb7d78df9fa3e99f74036
blob + 061b30b9cccd625922be97ff4080fa8d96371d65
--- src/main/kotlin/dev/nezzontli/gotvcs/cli/GotCommandLineWrapper.kt
+++ src/main/kotlin/dev/nezzontli/gotvcs/cli/GotCommandLineWrapper.kt
return line.substringAfter("work tree base commit:").trim()
}
+ /** Current branch name (e.g. "main"), parsed from `got info`'s "work tree branch reference" line. */
@Throws(VcsException::class)
+ fun currentBranch(workDir: File): String? {
+ val output = run(workDir, "info")
+ val line = output.lineSequence().firstOrNull { it.trimStart().startsWith("work tree branch reference:") }
+ ?: return null
+ return line.substringAfter("work tree branch reference:").trim().removePrefix("refs/heads/")
+ }
+
+ @Throws(VcsException::class)
fun commit(workDir: File, message: String, paths: List<String>) {
if (paths.isEmpty()) return
run(workDir, *(arrayOf("commit", "-m", message) + paths))
blob - /dev/null
blob + 5cfb8547432e834d0bab37bc6130158b86a1ac21 (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/repo/GotBranchWidget.kt
+package dev.nezzontli.gotvcs.repo
+
+import com.intellij.dvcs.ui.DvcsStatusWidget
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.openapi.wm.StatusBarWidget
+import com.intellij.openapi.wm.StatusBarWidgetFactory
+
+private const val WIDGET_ID = "got.branch.widget"
+
+class GotBranchWidget(project: Project) : DvcsStatusWidget<GotRepository>(project, "got") {
+
+ override fun ID(): String = WIDGET_ID
+
+ override fun copy(): StatusBarWidget = GotBranchWidget(project)
+
+ override fun guessCurrentRepository(project: Project, selectedFile: VirtualFile?): GotRepository? {
+ val manager = project.getService(GotRepositoryManager::class.java)
+ selectedFile?.let { manager.getRepositoryForFileQuick(it) }?.let { return it }
+ return manager.repositories.firstOrNull()
+ }
+
+ override fun getFullBranchName(repository: GotRepository): String = repository.currentBranchName ?: "got"
+
+ override fun isMultiRoot(project: Project): Boolean = project.getService(GotRepositoryManager::class.java).moreThanOneRoot()
+
+ override fun rememberRecentRoot(path: String) = Unit
+
+ class Factory : StatusBarWidgetFactory {
+ override fun getId(): String = WIDGET_ID
+
+ override fun getDisplayName(): String = "got Branch Widget"
+
+ override fun isAvailable(project: Project): Boolean =
+ project.getService(GotRepositoryManager::class.java).repositories.isNotEmpty()
+
+ override fun createWidget(project: Project): StatusBarWidget = GotBranchWidget(project)
+
+ override fun isEnabledByDefault(): Boolean = true
+ }
+}
blob - /dev/null
blob + 47adf6a68fa6f4aaa132832d08eb15c65b970ba4 (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/repo/GotRepository.kt
+package dev.nezzontli.gotvcs.repo
+
+import com.intellij.dvcs.repo.Repository
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.Disposer
+import com.intellij.openapi.vcs.AbstractVcs
+import com.intellij.openapi.vcs.ProjectLevelVcsManager
+import com.intellij.openapi.vcs.VcsException
+import com.intellij.openapi.vfs.VirtualFile
+import dev.nezzontli.gotvcs.GotVcs
+import dev.nezzontli.gotvcs.cli.GotCommandLineWrapper
+import java.io.File
+
+class GotRepository(
+ private val project: Project,
+ private val root: VirtualFile,
+ private val commandLine: GotCommandLineWrapper,
+ parentDisposable: Disposable,
+) : Repository {
+
+ private var disposed = false
+
+ init {
+ Disposer.register(parentDisposable, this)
+ }
+
+ override fun getRoot(): VirtualFile = root
+
+ override fun getPresentableUrl(): String = root.presentableUrl
+
+ override fun getProject(): Project = project
+
+ override fun getState(): Repository.State = Repository.State.NORMAL
+
+ override fun getCurrentBranchName(): String? = try {
+ commandLine.currentBranch(File(root.path))
+ } catch (e: VcsException) {
+ null
+ }
+
+ 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 isFresh(): Boolean = false
+
+ override fun update() = Unit
+
+ override fun toLogString(): String = "GotRepository{root=$root}"
+
+ override fun dispose() {
+ disposed = true
+ }
+
+ override fun isDisposed(): Boolean = disposed
+}
blob - /dev/null
blob + 9531ed74274324eda46a8ba44e3fd3847bf6e157 (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/repo/GotRepositoryManager.kt
+package dev.nezzontli.gotvcs.repo
+
+import com.intellij.dvcs.repo.AbstractRepositoryManager
+import com.intellij.openapi.project.Project
+import dev.nezzontli.gotvcs.GotVcs
+
+class GotRepositoryManager(project: Project) :
+ AbstractRepositoryManager<GotRepository>(project, GotVcs.getKey(), "got.repository.sync") {
+
+ override fun getRepositories(): List<GotRepository> = getRepositories(GotRepository::class.java)
+
+ override fun isSyncEnabled(): Boolean = false
+}
blob - /dev/null
blob + 82d0707f568ac22de03dc0b540174b5beabf26ae (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/repo/GotVcsRepositoryCreator.kt
+package dev.nezzontli.gotvcs.repo
+
+import com.intellij.dvcs.repo.Repository
+import com.intellij.dvcs.repo.VcsRepositoryCreator
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.vcs.VcsKey
+import com.intellij.openapi.vfs.VirtualFile
+import dev.nezzontli.gotvcs.GotVcs
+import dev.nezzontli.gotvcs.cli.GotCommandLineWrapper
+import java.io.File
+
+class GotVcsRepositoryCreator : VcsRepositoryCreator {
+
+ override fun getVcsKey(): VcsKey = GotVcs.getKey()
+
+ override fun createRepositoryIfValid(project: Project, root: VirtualFile, parentDisposable: Disposable): Repository? {
+ if (!File(root.path, ".got").isDirectory) return null
+ return GotRepository(project, root, GotCommandLineWrapper(), parentDisposable)
+ }
+}
blob - 2e3aa6efb3c254a6db025a06c9d04e04bccf1533
blob + 22f036062dac0b0f2971b4e5d54c5738836fd31b
--- src/main/resources/META-INF/plugin.xml
+++ src/main/resources/META-INF/plugin.xml
displayName="got"
administrativeAreaName=".got"/>
<vcsRootChecker implementation="dev.nezzontli.gotvcs.roots.GotVcsRootChecker"/>
+ <vcsRepositoryCreator implementation="dev.nezzontli.gotvcs.repo.GotVcsRepositoryCreator"/>
<applicationService serviceImplementation="dev.nezzontli.gotvcs.settings.GotSettingsState"/>
<applicationConfigurable instance="dev.nezzontli.gotvcs.settings.GotConfigurable" displayName="got" parentId="vcs"/>
<notificationGroup id="got" displayType="BALLOON"/>
+ <projectService serviceImplementation="dev.nezzontli.gotvcs.repo.GotRepositoryManager"/>
+ <statusBarWidgetFactory id="got.branch.widget"
+ implementation="dev.nezzontli.gotvcs.repo.GotBranchWidget$Factory"
+ order="after CodeStyleStatusBarWidget"/>
</extensions>
<actions>