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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [2026.1.4]

### Added

- Added [support for unversioned and deleted files](https://github.com/comod/git-scope-pro/pull/96) (thanks to [@nmeylan](https://github.com/nmeylan))
- Added [Create Patch action](https://github.com/comod/git-scope-pro/issues/97) to create a patch file from selected

## [2026.1.3]

### Fixes
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,27 @@ In the "New*" tab you get a few different options to define the scope:
![](docs/icon.svg) **Change Browser:**

Whenever the scope selection is done, the tab will turn into a "change browser" (similar to version control) that
displays the current diff of the **Git Scope**.
displays the current diff of the **Git Scope**. The change browser supports searching/filtering by file name using the
built-in speed search — just start typing to narrow down the list.

![](docs/toolwindow.png)

Right click on any file will present a number of actions:

![](docs/show_in_project.png)
![](docs/context_menu.png)

- **Show Diff**: Opens a diff window showing the diff of the selected file(s) `<selected-scope>..HEAD`
- **Show in Project**: Highlight this file in the Project tool window
- **Create Patch...**: Opens a dialog to save the selected file(s) scope diff as a `.patch` file
- **Copy as Patch to Clipboard**: Copies the selected file(s) scope diff as a unified patch directly to the clipboard
- **Rollback...**: Rollback the selected files(s) to `<selected-scope>` version. Note that this will checkout the
selected scope version of the file(s), and will in many cases leave you with a modified file that no longer show up in
the Git Scope window since it is identical to the version pointed to by the scope. Commit the files using the
standard Commit tool window.

**Create Patch...**, **Copy as Patch to Clipboard**, and **Rollback...** all apply to the current selection,
so you can select multiple files (or all files via **Ctrl+A**) and the action will apply to all of them at once.

![](docs/icon.svg) **Line Status Gutter:**

Git Scope uses its own plugin-native gutter rendering system to show scope-aware diff markers directly
Expand Down Expand Up @@ -163,6 +169,8 @@ Plugin settings are available under **Settings → Tools → Git Scope**:
|-------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Separate Git Scope and IDE gutter rendering** | When enabled, Git Scope gutter markers are rendered in a dedicated column to the left of the line numbers, separate from the IDE's native markers. When disabled (default), both sets of markers share the same gutter column. |
| **Color files based on Git Scope** | When enabled (default), file colors in the project tree and editor tabs reflect the active Git Scope status. Disable to use the IDE's default HEAD-based file coloring. |
| **Show untracked files** | When enabled, untracked (unversioned) files appear in the Git Scope view. Disabled by default. |
| **Show deleted files** | When enabled, locally deleted files appear in the Git Scope view. Disabled by default. |

## Shortcuts (Added by this Plugin)

Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ val platformType = properties("platformType")
plugins {
id("java")
id("org.jetbrains.kotlin.jvm") version "2.3.20"
id("org.jetbrains.intellij.platform") version "2.13.1"
id("org.jetbrains.intellij.platform") version "2.16.0"
id("org.jetbrains.changelog") version "2.5.0"
}

Expand Down Expand Up @@ -148,6 +148,6 @@ listOf("build", "buildPlugin").forEach { taskName ->
}

dependencies {
implementation("com.google.code.gson:gson:2.13.2")
implementation("com.google.code.gson:gson:2.14.0")
implementation("io.reactivex.rxjava3:rxjava:3.1.12")
}
Binary file added docs/context_menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
pluginGroup=org.woelkit.plugins
pluginName=Git Scope
pluginRepositoryUrl=https://github.com/comod/git-scope-pro
pluginVersion=2026.1.3
pluginVersion=2026.1.4
pluginSinceBuild=243

platformType=IU
#platformVersion=LATEST-EAP-SNAPSHOT
platformVersion=2026.1

platformBundledPlugins=Git4Idea
gradleVersion=9.4.1
gradleVersion=9.5.1
kotlin.stdlib.default.dependency=false
org.gradle.configuration-cache=true
org.gradle.caching = true
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 3 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 10 additions & 21 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 56 additions & 2 deletions src/main/java/toolwindow/VcsTreeActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.actions.CreatePatchFromChangesAction;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ide.projectView.ProjectView;
import model.MyModel;
Expand All @@ -14,10 +15,13 @@
import service.ViewService;
import utils.CustomRollback;

import java.util.Arrays;
import java.util.List;

public class VcsTreeActions {
public static class ShowInProjectAction extends AnAction {
public ShowInProjectAction() {
super("Show in Project");
super("Show in Project", "Locate file in the Project view", AllIcons.General.Locate);
}

@Override
Expand Down Expand Up @@ -55,7 +59,7 @@ public void update(@NotNull AnActionEvent e) {

public static class RollbackAction extends AnAction {
public RollbackAction() {
super("Rollback...");
super("Rollback...", "Rollback selected changes", AllIcons.Actions.Rollback);
}

@Override
Expand All @@ -82,6 +86,56 @@ public void update(@NotNull AnActionEvent e) {
}
}

public static class CreatePatchAction extends AnAction {
public CreatePatchAction() {
super("Create Patch...", "Create a patch file from selected changes", AllIcons.Vcs.Patch);
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
Change[] changes = e.getData(VcsDataKeys.CHANGES);
if (project == null || changes == null || changes.length == 0) return;
CreatePatchFromChangesAction.createPatch(project, null, Arrays.asList(changes));
}

@Override
public void update(@NotNull AnActionEvent e) {
Change[] changes = e.getData(VcsDataKeys.CHANGES);
e.getPresentation().setEnabledAndVisible(changes != null && changes.length > 0);
}
}

public static class CopyAsPatchAction extends AnAction {
public CopyAsPatchAction() {
super("Copy as Patch to Clipboard", "Copy selected changes as a patch to the clipboard", null);
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
Change[] changes = e.getData(VcsDataKeys.CHANGES);
if (project == null || changes == null || changes.length == 0) return;
CreatePatchFromChangesAction.createPatch(project, null, Arrays.asList(changes), true);
}

@Override
public void update(@NotNull AnActionEvent e) {
Change[] changes = e.getData(VcsDataKeys.CHANGES);
e.getPresentation().setEnabledAndVisible(changes != null && changes.length > 0);
}
}

public static class SelectOpenedFileAction extends AnAction {
public SelectOpenedFileAction() {
super("Select Opened File", "Select the file currently open in the editor", AllIcons.General.Locate);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/toolwindow/elements/MySimpleChangesBrowser.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,17 @@ public class MySimpleChangesBrowser extends SimpleAsyncChangesBrowser {
private AnAction selectOpenedFileAction;
private AnAction showInProjectAction;
private AnAction rollbackAction;
private AnAction createPatchAction;
private AnAction copyAsPatchAction;
private List<AnAction> toolbarActions;

private void initializeActions() {
if (selectOpenedFileAction == null) {
selectOpenedFileAction = new VcsTreeActions.SelectOpenedFileAction();
showInProjectAction = new VcsTreeActions.ShowInProjectAction();
rollbackAction = new VcsTreeActions.RollbackAction();
createPatchAction = new VcsTreeActions.CreatePatchAction();
copyAsPatchAction = new VcsTreeActions.CopyAsPatchAction();
toolbarActions = Collections.singletonList(selectOpenedFileAction);
}
}
Expand All @@ -76,6 +80,8 @@ private MySimpleChangesBrowser(@NotNull Project project, @NotNull Collection<? e
// Include parent actions (which provide diff functionality) plus our custom actions
List<AnAction> actions = new ArrayList<>(super.createPopupMenuActions());
actions.add(showInProjectAction);
actions.add(createPatchAction);
actions.add(copyAsPatchAction);
actions.add(rollbackAction);
return actions;
}
Expand Down