diff --git a/CHANGELOG.md b/CHANGELOG.md index 71be73b..86aee39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index c501376..870c655 100644 --- a/README.md +++ b/README.md @@ -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) `..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 `` 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 @@ -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) diff --git a/build.gradle.kts b/build.gradle.kts index 1448a84..eaed095 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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" } @@ -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") } \ No newline at end of file diff --git a/docs/context_menu.png b/docs/context_menu.png new file mode 100644 index 0000000..fc16de6 Binary files /dev/null and b/docs/context_menu.png differ diff --git a/gradle.properties b/gradle.properties index cf36dd5..df1a77c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ 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 @@ -10,7 +10,7 @@ platformType=IU 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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d997cfc..b1b8ef5 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118..df6a6ad 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/gradlew b/gradlew index 739907d..b9bb139 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/gradlew.bat b/gradlew.bat index c4bdd3a..24c62d5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -23,8 +23,8 @@ @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,7 +65,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line @@ -73,21 +73,10 @@ goto fail @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/src/main/java/toolwindow/VcsTreeActions.java b/src/main/java/toolwindow/VcsTreeActions.java index 6c0dc61..7beb8ea 100644 --- a/src/main/java/toolwindow/VcsTreeActions.java +++ b/src/main/java/toolwindow/VcsTreeActions.java @@ -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; @@ -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 @@ -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 @@ -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); diff --git a/src/main/java/toolwindow/elements/MySimpleChangesBrowser.java b/src/main/java/toolwindow/elements/MySimpleChangesBrowser.java index db48fd5..6e95bad 100644 --- a/src/main/java/toolwindow/elements/MySimpleChangesBrowser.java +++ b/src/main/java/toolwindow/elements/MySimpleChangesBrowser.java @@ -45,6 +45,8 @@ public class MySimpleChangesBrowser extends SimpleAsyncChangesBrowser { private AnAction selectOpenedFileAction; private AnAction showInProjectAction; private AnAction rollbackAction; + private AnAction createPatchAction; + private AnAction copyAsPatchAction; private List toolbarActions; private void initializeActions() { @@ -52,6 +54,8 @@ private void initializeActions() { selectOpenedFileAction = new VcsTreeActions.SelectOpenedFileAction(); showInProjectAction = new VcsTreeActions.ShowInProjectAction(); rollbackAction = new VcsTreeActions.RollbackAction(); + createPatchAction = new VcsTreeActions.CreatePatchAction(); + copyAsPatchAction = new VcsTreeActions.CopyAsPatchAction(); toolbarActions = Collections.singletonList(selectOpenedFileAction); } } @@ -76,6 +80,8 @@ private MySimpleChangesBrowser(@NotNull Project project, @NotNull Collection actions = new ArrayList<>(super.createPopupMenuActions()); actions.add(showInProjectAction); + actions.add(createPatchAction); + actions.add(copyAsPatchAction); actions.add(rollbackAction); return actions; }