From 4abfbe60a321fbc2047dff2e26248c0670940800 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 2 Aug 2018 15:21:54 +0300 Subject: [PATCH] IDEA-196620 git: do not suggest rename with extra commit it is not available (actual fix disabled) Kotlin plugin erases its internal flags on `collectExplicitMovements` call. Thus, second call will return empty collection, and we can't use it to update checkbox state. But we can prepare API and enable registry key when fixed plugin version is available. --- .../util/resources/misc/registry.properties | 1 + .../checkin/GitCheckinEnvironment.java | 18 +++++++++++++-- .../GitCheckinExplicitMovementProvider.java | 22 ++++++++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index ecdeb961f81a..f28199e24185 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -1150,6 +1150,7 @@ git.refresh.vfs.total.description=If set to true, the whole Git repository root The option is needed to debug possible "incomplete VFS refresh" reports, if they appear. git.allow.explicit.commit.renames=true git.allow.explicit.commit.renames.description=Enable option to commit some "rename + modification" as two commits to help git track file history (ex: for files, converted from Java to Kotlin). +git.explicit.commit.renames.allow.multiple.calls=false git.force.commit.using.staging.area=true git.force.commit.using.staging.area.description=When enabled, perform all git commits by updating staging area. If disabled, use `git commit --only` when possible. git.clone.recurse.submodules=true diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java index 6e94b3a96c77..ae8cad72a79f 100644 --- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java +++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java @@ -524,7 +524,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment { Set movedPaths = new HashSet<>(); for (GitCheckinExplicitMovementProvider provider : GitCheckinExplicitMovementProvider.EP_NAME.getExtensions()) { - Collection providerMovements = provider.collectExplicitMovements(myProject, beforePaths, afterPaths); + Collection providerMovements = provider.collectExplicitMovements(myProject, beforePaths, afterPaths, true); if (!providerMovements.isEmpty()) { message = provider.getCommitMessage(message); movedPaths.addAll(providerMovements); @@ -1101,7 +1101,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment { GitCheckinOptions(@NotNull Project project, @NotNull CheckinProjectPanel panel) { - myExplicitMovementProviders = filter(GitCheckinExplicitMovementProvider.EP_NAME.getExtensions(), it -> it.isEnabled(myProject)); + myExplicitMovementProviders = collectActiveMovementProviders(myProject); myCheckinProjectPanel = panel; myAuthorField = createTextField(project, getAuthors(project)); @@ -1332,6 +1332,20 @@ public class GitCheckinEnvironment implements CheckinEnvironment { GitUserRegistry gitUserRegistry = GitUserRegistry.getInstance(myProject); return of(affectedGitRoots).map(vf -> gitUserRegistry.getUser(vf)).allMatch(user -> user != null && isSamePerson(author, user)); } + + @NotNull + private List collectActiveMovementProviders(@NotNull Project project) { + GitCheckinExplicitMovementProvider[] allProviders = GitCheckinExplicitMovementProvider.EP_NAME.getExtensions(); + List enabledProviders = filter(allProviders, it -> it.isEnabled(project)); + if (enabledProviders.isEmpty()) return Collections.emptyList(); + if (!Registry.is("git.explicit.commit.renames.allow.multiple.calls")) return enabledProviders; + + Collection changes = ChangeListManager.getInstance(project).getAllChanges(); + List beforePaths = mapNotNull(changes, ChangesUtil::getBeforePath); + List afterPaths = mapNotNull(changes, ChangesUtil::getAfterPath); + + return filter(enabledProviders, it -> !it.collectExplicitMovements(project, beforePaths, afterPaths, false).isEmpty()); + } } public void setNextCommitIsPushed(Boolean nextCommitIsPushed) { diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinExplicitMovementProvider.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinExplicitMovementProvider.java index 43c63ebfaeb4..5e393d944876 100644 --- a/plugins/git4idea/src/git4idea/checkin/GitCheckinExplicitMovementProvider.java +++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinExplicitMovementProvider.java @@ -4,6 +4,7 @@ package git4idea.checkin; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -18,6 +19,7 @@ import java.util.Objects; * This will create two commits: commit with explicit file movements, * and commit with content modifications in these files and the rest of affected files */ +@ApiStatus.Experimental public abstract class GitCheckinExplicitMovementProvider { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("Git4Idea.GitCheckinExplicitMovementProvider"); @@ -36,13 +38,27 @@ public abstract class GitCheckinExplicitMovementProvider { @NotNull public abstract String getCommitMessage(@NotNull String originalCommitMessage); + + @Deprecated + @NotNull + public Collection collectExplicitMovements(@NotNull Project project, + @NotNull List beforePaths, + @NotNull List afterPaths) { + throw new UnsupportedOperationException(); + } + /** + * @param isActualCommit Whether actual commit will be performed or it's an intermediate check to update UI + * * @return file movements, that should be committed explicitly */ @NotNull - public abstract Collection collectExplicitMovements(@NotNull Project project, - @NotNull List beforePaths, - @NotNull List afterPaths); + public Collection collectExplicitMovements(@NotNull Project project, + @NotNull List beforePaths, + @NotNull List afterPaths, + boolean isActualCommit) { + return collectExplicitMovements(project, beforePaths, afterPaths); + } public static class Movement { @NotNull private final FilePath myBeforePath;