Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build GitScope Pro using JBR 21
name: Build IntelliJ Plugin with JBR 21
# Build GitScope Pro using JBR 25
name: Build IntelliJ Plugin with JBR 25

on:
push:
Expand All @@ -15,13 +15,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Download JetBrains Runtime (JBR 21)
- name: Download JetBrains Runtime (JBR 25)
run: |
wget https://cache-redirector.jetbrains.com/intellij-jbr/jbr_jcef-21.0.10-linux-x64-b1163.110.tar.gz -O jbr.tar.gz
wget https://cache-redirector.jetbrains.com/intellij-jbr/jbr_jcef-25.0.3-linux-x64-b508.16.tar.gz -O jbr.tar.gz
mkdir -p jbr
tar -xzf jbr.tar.gz -C jbr --strip-components=1

- name: Set JAVA_HOME to JBR 21
- name: Set JAVA_HOME to JBR 25
run: echo "JAVA_HOME=${{ github.workspace }}/jbr" >> $GITHUB_ENV

- name: Verify Java version
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ gradle-app.setting
# End of https://www.gitignore.io/api/java,gradle

gradle.properties
.intellijPlatform
.intellijPlatform
.kotlin/
32 changes: 26 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## [2026.2]

Remote Development support, built on a split of the plugin into separate frontend and backend modules. Local IDE
behavior, scope tabs and settings are unchanged. Given the size of the refactoring,
please [report any regression](https://github.com/comod/git-scope-pro/issues) with your IDE version and whether you run
locally or over Remote Development.

### Added

- Added [support for remote development](https://github.com/comod/git-scope-pro/issues/91)
- Git access, scope resolution and change collection run on the host; the client handles gutter markers, the diff
popup and change navigation.
- Only the computed line ranges cross the network, so gutter markers stay responsive, and the client re-syncs
automatically after a dropped connection.
- Added [actions/shortcuts to step between files and scope](https://github.com/comod/git-scope-pro/issues/99)

### Fixes

- Fixed [Right-click -> Show in Project doesn't switch to Project window](https://github.com/comod/git-scope-pro/issues/100)
- Fixed [Right-click -> Show in Project for folder selects the first changed file rather than the folder](https://github.com/comod/git-scope-pro/issues/101)

## [2026.1.4]

### Added
Expand Down Expand Up @@ -27,12 +48,11 @@

## [2026.1]

This release replaces the previous approach of hooking into the IDE's native gutter system — which
caused several unwanted side-effects and interfered with standard IDE functionality — with a
fully plugin-native gutter rendering system. The new markers can be placed either to the left of
the line numbers on their own, or inline with the IDE's native gutter markers, in which case both
work side by side. Clicking a marker opens a popup with navigation (prev/next), inline diff,
rollback, and copy actions.
This release replaces the previous approach of hooking into the IDE's native gutter system — which caused several
unwanted side-effects and interfered with standard IDE functionality — with a fully plugin-native gutter rendering
system. The new markers can be placed either to the left of the line numbers on their own, or inline with the IDE's
native gutter markers, in which case both work side by side. Clicking a marker opens a popup with navigation
(prev/next), inline diff, rollback, and copy actions.

### Added

Expand Down
143 changes: 105 additions & 38 deletions CLASSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@
This document lists all plugin classes to search for when analyzing heap dumps to identify memory leaks after plugin
unload. All classes should have **count = 0** after successful plugin unload.

## Services
Classes are organized by module: **backend**, **frontend**, and **shared**.

---

## Backend Module

### Services

*Expected: 1 instance per project, or 0 after unload*

- `service.ViewService`
- `service.ToolWindowService`
- `service.ToolWindowServiceInterface` *(interface - unlikely to leak but check if implemented by plugin classes)*
- `service.ToolWindowServiceInterface` *(interface)*
- `service.StatusBarService`
- `service.GitService`
- `service.TargetBranchService`
- `implementation.compare.ChangesService`

## State/Persistence
### State/Persistence

- `state.State`
- `state.MyModelConverter`
- `state.WindowPositionTracker`

## Listeners
### Listeners

*Expected: 0 after unload*

Expand All @@ -37,9 +43,9 @@ unload. All classes should have **count = 0** after successful plugin unload.
- `listener.ToggleHeadAction`
- `listener.VcsContextMenuAction`

## UI Components
### UI Components

### Main Components
#### Main Components

- `toolwindow.ToolWindowView`
- `toolwindow.ToolWindowUIFactory`
Expand All @@ -48,13 +54,14 @@ unload. All classes should have **count = 0** after successful plugin unload.
- `toolwindow.VcsTreeActions`

#### Actions

- `toolwindow.actions.TabMoveActions`
- `toolwindow.actions.TabMoveActions$MoveTabLeft`
- `toolwindow.actions.TabMoveActions$MoveTabRight`
- `toolwindow.actions.RenameTabAction`
- `toolwindow.actions.ResetTabNameAction`

### UI Elements
#### UI Elements

- `toolwindow.elements.VcsTree`
- `toolwindow.elements.BranchTree`
Expand All @@ -63,71 +70,125 @@ unload. All classes should have **count = 0** after successful plugin unload.
- `toolwindow.elements.CurrentBranch`
- `toolwindow.elements.TargetBranch`

## Status Bar
### Status Bar

- `statusBar.MyStatusBarWidget`
- `statusBar.MyStatusBarWidgetFactory`
- `statusBar.MyStatusBarPanel`

## Models
### Models

- `model.MyModel`
- `model.MyModel$field` *(enum - check for RxJava subscription leaks)*
- `model.MyModel$field` *(enum)*
- `model.MyModelBase`
- `model.TargetBranchMap`
- `model.Debounce`

## Implementation Classes
### Implementation Classes

### Line Status Tracker
#### Line Status Tracker

- `implementation.lineStatusTracker.MyLineStatusTrackerImpl`

### Gutter Rendering

- `implementation.gutter.Range`
- `implementation.gutter.RangesBuilder`
- `implementation.gutter.LineStatusGutterMarkerRenderer`
- `implementation.gutter.ScopeLineStatusMarkerRenderer`
- `implementation.gutter.ScopeOverviewMarkerRenderer`
- `implementation.gutter.ScopeDiffViewer`

### Scope
#### Scope

- `implementation.scope.MyScope`
- `implementation.scope.MyPackageSet` *(registered with NamedScopeManager - critical leak if not unregistered)*
- `implementation.scope.MyScopeInTarget`
- `implementation.scope.MyScopeNameSupplier`

### File Status
#### File Status

- `implementation.fileStatus.GitScopeFileStatusProvider`

## Settings
### Settings (Backend UI)

- `settings.GitScopeSettings`
- `settings.GitScopeSettingsComponent`
- `settings.GitScopeSettingsConfigurable`

## Utility Classes
### RPC

- `rpc.BackendGutterRpcImpl`
- `rpc.BackendGutterRpcProvider`

### Utility Classes

- `utils.CustomRollback`
- `utils.GitUtil`
- `utils.Notification`
- `utils.PlatformApiReflection`

---

## Frontend Module

### Services

- `gitscope.frontend.GutterRenderingService`
- `gitscope.frontend.GutterRenderingStartup`

### Gutter Rendering

- `implementation.gutter.LineStatusGutterMarkerRenderer`
- `implementation.gutter.ScopeLineStatusMarkerRenderer`
- `implementation.gutter.ScopeDiffViewer`
- `implementation.gutter.ScopeGutterHighlighterManager`
- `implementation.gutter.ScopeGutterPopupPanel`

### RPC

- `rpc.FrontendGutterSubscriptions`
- `rpc.FrontendGutterSubscriptionsStartup`

---

## Shared Module

### Services

- `service.GutterDataService`
- `service.GutterDataService$GutterFileData`
- `service.GutterDataService$Listener` *(interface)*

### Gutter Data Model

- `implementation.gutter.Range`
- `implementation.gutter.RangesBuilder`

### RPC Interface & DTOs

- `rpc.GutterRpcApi`
- `rpc.GutterUpdateEvent`
- `rpc.GutterUpdateEvent$DataUpdated`
- `rpc.GutterUpdateEvent$DataCleared`
- `rpc.GutterUpdateEvent$AllCleared`
- `rpc.GutterFileDataDto`
- `rpc.GutterRangeDto`

### Settings

- `settings.GitScopeSettings`

### System

- `system.Defs`

### Utility Classes

- `utils.SharedReflection`
- `utils.Notification`

---

## Anonymous/Inner Classes to Look For

*These are patterns - search for classes matching these names:*

- `TabOperations$1` *(rename action)*
- `TabOperations$2` *(reset action)*
- `TabOperations$3` *(move left action)*
- `TabOperations$4` *(move right action)*
- `VcsTree$$Lambda` *(any lambda from VcsTree)*
- `ToolWindowView$listener` *(Consumer<MyModel.field> stored as field)*
- `ViewService$modelListeners` *(HashMap of model → Consumer listeners)*
- `MyLineStatusTrackerImpl$$Lambda` *(lambdas from line status tracker)*
- `ScopeLineStatusMarkerRenderer$$Lambda` *(lambdas from gutter renderer)*
- `GutterRenderingService$$Lambda` *(lambdas from rendering service)*
- `BackendGutterRpcImpl$$Lambda` *(callbackFlow listener)*
- `MySimpleChangesBrowser$1` *(anonymous MouseAdapter)*
- `BranchTree$MyColoredTreeCellRenderer`
- Any class ending with `$$Lambda$...`
Expand All @@ -149,6 +210,9 @@ Filter the HPROF classes view using these prefixes:
- `statusBar.`
- `settings.`
- `utils.`
- `rpc.`
- `gitscope.frontend.`
- `system.`

### 2. Filter the Classes View

Expand All @@ -161,12 +225,15 @@ Filter the HPROF classes view using these prefixes:
*Most likely to leak:*

1. **All listeners** - Must be unregistered
2. **TabOperations and its anonymous classes** - Actions must be unregistered
3. **ToolWindowView** - UI components must be disposed
4. **ViewService** - RxJava subscriptions must be disposed
5. **MyLineStatusTrackerImpl** - Background tasks must be cancelled
6. **ScopeLineStatusMarkerRenderer** - Highlighters and mouse listeners must be removed
7. **Any class with `$` in the name** - Anonymous/inner classes often capture outer references
2. **ToolWindowView** - UI components must be disposed, model listener removed
3. **ViewService** - Model listeners must be removed in dispose()
4. **MyLineStatusTrackerImpl** - Background tasks must be cancelled
5. **ScopeLineStatusMarkerRenderer** - Highlighters and mouse listeners must be removed
6. **GutterRenderingService** - Must remove itself from GutterDataService listeners
7. **BackendGutterRpcImpl** - callbackFlow listener removed on awaitClose
8. **FrontendGutterSubscriptions** - Coroutine scope cancelled on service dispose
9. **GutterDataService** - Listener list and file data map cleared on dispose
10. **Any class with `$` in the name** - Anonymous/inner classes often capture outer references

---

Expand Down
Loading