From f3da0e06ceb46427958c210c74991e41bb1cfcdc Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Tue, 10 Sep 2024 22:39:09 +0300 Subject: [PATCH] fix: include selected changes diff only --- .../GenerateGitCommitMessageAction.java | 88 ++++++++++--------- .../ee/carlrobert/codegpt/util/GitUtil.kt | 29 ++++-- 2 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java index b2fd5cf0..42924fcb 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsDataKeys; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase; import com.intellij.openapi.vcs.changes.ui.CommitDialogChangesBrowser; @@ -30,16 +31,14 @@ import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.completions.CompletionRequestService; import ee.carlrobert.codegpt.settings.configuration.CommitMessageTemplate; import ee.carlrobert.codegpt.ui.OverlayUtil; +import ee.carlrobert.codegpt.util.GitUtil; import ee.carlrobert.llm.client.openai.completion.ErrorDetails; import ee.carlrobert.llm.completion.CompletionEventListener; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.AbstractMap; -import java.util.ArrayList; +import git4idea.repo.GitRepositoryManager; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.concurrent.ExecutionException; import java.util.function.Function; import java.util.stream.Stream; import okhttp3.sse.EventSource; @@ -78,7 +77,8 @@ public class GenerateGitCommitMessageAction extends AnAction { return; } - var gitDiff = getGitDiff( + var gitDiff = getDiff( + event, project, getIncludedChangesFilePaths(event), getIncludedUnversionedFilePaths(event)); @@ -105,6 +105,44 @@ public class GenerateGitCommitMessageAction extends AnAction { return ActionUpdateThread.EDT; } + private String getDiff( + AnActionEvent event, + Project project, + List includedChangesFilePaths, + List includedUnversionedFilePaths) { + try { + return ApplicationManager.getApplication().executeOnPooledThread(() -> { + try { + var repository = GitRepositoryManager.getInstance(project) + .getRepositoryForFile(project.getWorkspaceFile()); + if (repository == null) { + return ""; + } + + var stagedGitDiff = String.join("\n", GitUtil.getStagedDiff( + project, + repository, + includedChangesFilePaths)); + var unstagedGitDiff = String.join("\n", GitUtil.getUnstagedDiff( + project, + repository, + includedUnversionedFilePaths)); + return Map.of( + "Unstaged git diff", unstagedGitDiff, + "Staged git diff", stagedGitDiff) + .entrySet().stream() + .filter(entry -> !entry.getValue().isEmpty()) + .map(entry -> "%s:%n%s".formatted(entry.getKey(), entry.getValue())) + .collect(joining("\n\n")); + } catch (VcsException e) { + throw new RuntimeException("Unable to get staged diff", e); + } + }).get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + private CompletionEventListener getEventListener( Project project, Document document) { @@ -139,42 +177,6 @@ public class GenerateGitCommitMessageAction extends AnAction { return commitMessage != null ? commitMessage.getEditorField().getEditor() : null; } - private String getGitDiff( - Project project, - List includedChangesFilePaths, - List includedUnversionedFilePaths) { - return Stream.of( - new AbstractMap.SimpleEntry<>(includedChangesFilePaths, true), - new AbstractMap.SimpleEntry<>(includedUnversionedFilePaths, false)) - .filter(entry -> !entry.getKey().isEmpty()) - .map(entry -> { - var process = - createGitDiffProcess(project.getBasePath(), entry.getKey(), entry.getValue()); - return new BufferedReader(new InputStreamReader(process.getInputStream())) - .lines() - .collect(joining("\n")); - }) - .collect(joining("\n")); - } - - private Process createGitDiffProcess(String projectPath, List filePaths, boolean cached) { - var command = new ArrayList(); - command.add("git"); - command.add("diff"); - if (cached) { - command.add("--cached"); - } - command.addAll(filePaths); - - var processBuilder = new ProcessBuilder(command); - processBuilder.directory(new File(projectPath)); - try { - return processBuilder.start(); - } catch (IOException ex) { - throw new RuntimeException("Unable to start git diff process", ex); - } - } - private @NotNull List getFilePaths( AnActionEvent event, Function> extractor) { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/util/GitUtil.kt b/src/main/kotlin/ee/carlrobert/codegpt/util/GitUtil.kt index 8212d55c..f05e70c9 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/util/GitUtil.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/util/GitUtil.kt @@ -11,19 +11,28 @@ object GitUtil { @Throws(VcsException::class) @JvmStatic - fun getStagedDiff(project: Project, gitRepository: GitRepository): List { - return getGitDiff(project, gitRepository, true) + fun getStagedDiff( + project: Project, + gitRepository: GitRepository, + includedVersionedFilePaths: List = emptyList() + ): List { + return getGitDiff(project, gitRepository, includedVersionedFilePaths, true) } @Throws(VcsException::class) @JvmStatic - fun getUnstagedDiff(project: Project, gitRepository: GitRepository): List { - return getGitDiff(project, gitRepository, false) + fun getUnstagedDiff( + project: Project, + gitRepository: GitRepository, + includedUnversionedFilePaths: List = emptyList() + ): List { + return getGitDiff(project, gitRepository, includedUnversionedFilePaths, false) } private fun getGitDiff( project: Project, gitRepository: GitRepository, + filePaths: List, staged: Boolean ): List { val handler = GitLineHandler(project, gitRepository.root, GitCommand.DIFF) @@ -37,9 +46,19 @@ object GitUtil { "--no-color", ) + filePaths.forEach { path -> + handler.addParameters(path) + } + val commandResult = Git.getInstance().runCommand(handler) return commandResult.output.filter { - listOf("diff --git", "index ", "---", "- ", "+++").none { prefix -> it.startsWith(prefix) } + listOf( + "diff --git", + "index ", + "---", + "- ", + "+++" + ).none { prefix -> it.startsWith(prefix) } } } }