From c23a84f0a929718ab4bf868efe63b6bb09c4d27a Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Sun, 1 Apr 2018 21:19:05 +0300 Subject: [PATCH] TW-54380 vcs: warn if partial changes are not supported by CommitExecutor * do not show checkboxes if none of executors supports partial commit --- .../src/messages/VcsBundle.properties | 2 ++ .../openapi/vcs/changes/CommitExecutor.java | 4 +++ .../patch/CreatePatchCommitExecutor.java | 5 +++ .../shelf/ShelveChangesCommitExecutor.java | 5 +++ .../changes/ui/CommitChangeListDialog.java | 34 ++++++++++++++++--- .../ui/MultipleLocalChangeListsBrowser.java | 7 ++-- .../util/CloudGitDeploymentRuntime.java | 5 +++ .../checkin/GitCommitAndPushExecutor.java | 5 +++ 8 files changed, 61 insertions(+), 6 deletions(-) diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index b5a355ea541c..ce2d0ed46d3b 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -274,6 +274,8 @@ commit.dialog.refresh.files=Synchronizing files... commit.dialog.rejected.commit.template=Rejected commit: {0} commit.dialog.changelist.label=Changelis&t: commit.dialog.changed.files.label=Changed &Files +commit.dialog.partial.commit.warning.title=Partial Commit Is Not Supported +commit.dialog.partial.commit.warning.body=Partial commit is not supported for ''{0}''.\nAll changes in the selected files will be committed. commit.wait.util.synced.message=Please wait until VCS synchronization is finished. commit.wait.util.synced.title=Finishing VCS refresh change.list.manager.wait.lists.synchronization={0}: Local Changes Refresh diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutor.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutor.java index 30a9a4e2716d..a0c811989fc9 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutor.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutor.java @@ -22,6 +22,10 @@ public interface CommitExecutor { return null; } + default boolean supportsPartialCommit() { + return false; + } + @NotNull CommitSession createCommitSession(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java index 818cecfa0471..a87540a5586e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java @@ -76,6 +76,11 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr return "reference.dialogs.vcs.patch.create"; } + @Override + public boolean supportsPartialCommit() { + return true; + } + @Override @NotNull public CommitSession createCommitSession() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesCommitExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesCommitExecutor.java index 62703650c920..3b95f0315b15 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesCommitExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesCommitExecutor.java @@ -55,6 +55,11 @@ public class ShelveChangesCommitExecutor extends LocalCommitExecutor { return "reference.dialogs.vcs.shelve"; } + @Override + public boolean supportsPartialCommit() { + return true; + } + private class ShelveChangesCommitSession implements CommitSession, CommitSessionContextAware { @Override public void setContext(CommitContext context) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java index 0dd234e3406b..d3dce30db30c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java @@ -1,6 +1,7 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.vcs.changes.ui; +import com.intellij.CommonBundle; import com.intellij.diff.util.DiffPlaces; import com.intellij.diff.util.DiffUserDataKeysEx; import com.intellij.diff.util.DiffUtil; @@ -29,6 +30,7 @@ import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vcs.changes.actions.ScheduleForAdditionAction; import com.intellij.openapi.vcs.changes.actions.diff.lst.LocalChangeListDiffTool; import com.intellij.openapi.vcs.checkin.*; +import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker; import com.intellij.openapi.vcs.impl.CheckinHandlersManager; import com.intellij.openapi.vcs.impl.LineStatusTrackerManager; import com.intellij.openapi.vcs.impl.PartialChangesUtil; @@ -100,6 +102,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj @NotNull private final List myHandlers = newArrayList(); private final boolean myAllOfDefaultChangeListChangesIncluded; @NotNull private final String myCommitActionName; + private final boolean myEnablePartialCommit; @NotNull private final Map myListComments; @NotNull private final List myExecutorActions; @@ -290,7 +293,6 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myIsAlien = isAlien; myResultHandler = customResultHandler; myListComments = newHashMap(); - myDiffDetails = new MyChangeProcessor(myProject); if (!myShowVcsCommit && isEmpty(executors)) { throw new IllegalArgumentException("nothing found to execute commit with"); @@ -313,7 +315,10 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj } myHelpId = myShowVcsCommit ? HELP_ID : getHelpId(executors); + myEnablePartialCommit = ContainerUtil.exists(getAffectedVcses(), AbstractVcs::arePartialChangelistsSupported) && + (myShowVcsCommit || ContainerUtil.exists(myExecutors, executor -> executor.supportsPartialCommit())); + myDiffDetails = new MyChangeProcessor(myProject, myEnablePartialCommit); myCommitMessageArea = new CommitMessage(project, true, true, myShowVcsCommit); if (myIsAlien) { @@ -329,7 +334,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj else { LineStatusTrackerManager.getInstanceImpl(myProject).resetExcludedFromCommitMarkers(); - MultipleLocalChangeListsBrowser browser = new MultipleLocalChangeListsBrowser(project, true, true, myShowVcsCommit); + MultipleLocalChangeListsBrowser browser = new MultipleLocalChangeListsBrowser(project, true, true, + myShowVcsCommit, myEnablePartialCommit); myBrowser = browser; if (initialSelection != null) browser.setSelectedChangeList(initialSelection); @@ -627,6 +633,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj return; } + if (!checkCommitOptionsSupported(commitExecutor)) return; if (!saveDialogState()) return; saveComments(true); @@ -896,6 +903,25 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myListComments.forEach((changeListName, comment) -> changeListManager.editComment(changeListName, comment)); } + private boolean checkCommitOptionsSupported(@NotNull CommitExecutor commitExecutor) { + if (myIsAlien) return true; + + if (!commitExecutor.supportsPartialCommit()) { + boolean hasPartialChanges = ContainerUtil.exists(getIncludedChanges(), change -> { + PartialLocalLineStatusTracker tracker = PartialChangesUtil.getPartialTracker(myProject, change); + return tracker != null && tracker.hasPartialChangesToCommit(); + }); + if (hasPartialChanges) { + return Messages.YES == + Messages.showYesNoDialog(myProject, + message("commit.dialog.partial.commit.warning.body", getExecutorPresentableText(commitExecutor)), + message("commit.dialog.partial.commit.warning.title"), + commitExecutor.getActionText(), CommonBundle.getCancelButtonText(), Messages.getWarningIcon()); + } + } + return true; + } + @Override public void doCancelAction() { myCommitOptions.saveChangeListComponentsState(); @@ -1151,11 +1177,11 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj } private class MyChangeProcessor extends ChangeViewDiffRequestProcessor { - public MyChangeProcessor(@NotNull Project project) { + public MyChangeProcessor(@NotNull Project project, boolean enablePartialCommit) { super(project, DiffPlaces.COMMIT_DIALOG); putContextUserData(DiffUserDataKeysEx.SHOW_READ_ONLY_LOCK, true); - putContextUserData(LocalChangeListDiffTool.ALLOW_EXCLUDE_FROM_COMMIT, true); + putContextUserData(LocalChangeListDiffTool.ALLOW_EXCLUDE_FROM_COMMIT, enablePartialCommit); } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java index ca6786f188a3..8bd99c188f97 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java @@ -62,6 +62,7 @@ public class MultipleLocalChangeListsBrowser extends CommitDialogChangesBrowser new MergingUpdateQueue("MultipleLocalChangeListsBrowser", 300, true, ANY_COMPONENT, this); private final boolean myEnableUnversioned; + private final boolean myEnablePartialCommit; @Nullable private JComponent myBottomDiffComponent; @NotNull private final ChangeListChooser myChangeListChooser; @@ -78,9 +79,11 @@ public class MultipleLocalChangeListsBrowser extends CommitDialogChangesBrowser public MultipleLocalChangeListsBrowser(@NotNull Project project, boolean showCheckboxes, boolean highlightProblems, - boolean enableUnversioned) { + boolean enableUnversioned, + boolean enablePartialCommit) { super(project, showCheckboxes, highlightProblems); myEnableUnversioned = enableUnversioned; + myEnablePartialCommit = enablePartialCommit; myChangeList = ChangeListManager.getInstance(project).getDefaultChangeList(); myChangeListChooser = new ChangeListChooser(); @@ -151,7 +154,7 @@ public class MultipleLocalChangeListsBrowser extends CommitDialogChangesBrowser protected void updateDiffContext(@NotNull DiffRequestChain chain) { super.updateDiffContext(chain); chain.putUserData(DiffUserDataKeysEx.BOTTOM_PANEL, myBottomDiffComponent); - chain.putUserData(LocalChangeListDiffTool.ALLOW_EXCLUDE_FROM_COMMIT, true); + chain.putUserData(LocalChangeListDiffTool.ALLOW_EXCLUDE_FROM_COMMIT, myEnablePartialCommit); } diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java index a0f1ac27d937..2b95602922ac 100644 --- a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java +++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java @@ -81,6 +81,11 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime { return "Commit and Push"; } + @Override + public boolean supportsPartialCommit() { + return true; + } + @NotNull @Override public CommitSession createCommitSession() { diff --git a/plugins/git4idea/src/git4idea/checkin/GitCommitAndPushExecutor.java b/plugins/git4idea/src/git4idea/checkin/GitCommitAndPushExecutor.java index 89f8869b4255..8988d0cbfc90 100644 --- a/plugins/git4idea/src/git4idea/checkin/GitCommitAndPushExecutor.java +++ b/plugins/git4idea/src/git4idea/checkin/GitCommitAndPushExecutor.java @@ -35,6 +35,11 @@ public class GitCommitAndPushExecutor implements CommitExecutor { return ID; } + @Override + public boolean supportsPartialCommit() { + return true; + } + @NotNull public CommitSession createCommitSession() { myCheckinEnvironment.setNextCommitIsPushed(true);