IDEA-153574 IDEA-174872 vcs: "Compare before with local" action

This commit is contained in:
Aleksey Pivovarov
2017-07-05 18:23:33 +03:00
parent e9143a0c9a
commit d295313a04
14 changed files with 182 additions and 49 deletions
@@ -78,7 +78,9 @@
<extensionPoint qualifiedName="com.intellij.ignoredFileProvider"
interface="com.intellij.openapi.vcs.changes.IgnoredFileProvider"/>
<extensionPoint name="openapi.vcs.history.actions.ShowDiffWithLocalAction.ExtensionProvider"
<extensionPoint name="openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction.ExtensionProvider"
interface="com.intellij.openapi.actionSystem.AnActionExtensionProvider"/>
<extensionPoint name="openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider"
interface="com.intellij.openapi.actionSystem.AnActionExtensionProvider"/>
<extensionPoint name="openapi.vcs.changes.actions.CreatePatchFromChangesAction.Dialog.ExtensionProvider"
interface="com.intellij.openapi.actionSystem.AnActionExtensionProvider"/>
@@ -40,7 +40,7 @@
<diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.update.ShowUpdatedDiffActionProvider"/>
<diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction" order="last"/>
<openapi.vcs.history.actions.ShowDiffWithLocalAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.shelf.DiffShelvedChangesWithLocalActionProvider"/>
<openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.shelf.DiffShelvedChangesWithLocalActionProvider"/>
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
@@ -24,9 +24,10 @@
text="Com_pare with Specified Revision..." popup="true"/>
<action id="Vcs.ShowHistoryForBlock" class="com.intellij.openapi.vcs.actions.SelectedBlockHistoryAction"/>
<action id="Vcs.GetVersion" class="com.intellij.openapi.vcs.history.actions.GetVersionAction"/>
<action id="Vcs.ShowDiffWithLocal" class="com.intellij.openapi.vcs.history.actions.ShowDiffWithLocalAction"
text="Compare with Local" description="Compare version from selected revision with current version"
icon="AllIcons.Actions.DiffWithCurrent"/>
<action id="Vcs.ShowDiffWithLocal.Before" class="com.intellij.openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction"
text="Compare Before with Local" description="Compare version before selected revision with current version"/>
<action id="Vcs.ShowDiffWithLocal" class="com.intellij.openapi.vcs.history.actions.ShowDiffAfterWithLocalAction"
text="Compare After with Local" description="Compare version after selected revision with current version"/>
<group class="com.intellij.openapi.vcs.actions.VcsActionGroup" id="VcsGroup"/>
@@ -375,6 +376,7 @@
<reference ref="Compare.SameVersion"/>
<reference ref="Compare.LastVersion"/>
<reference ref="Compare.Specified"/>
<reference ref="Vcs.ShowDiffWithLocal.Before"/>
<reference ref="Vcs.ShowDiffWithLocal"/>
<separator/>
<reference ref="Diff.PrevChange"/>
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.changes.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -24,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,12 +34,17 @@ import java.util.List;
import static com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction.showDiffForChange;
/**
* @author yole
*/
public class ShowDiffWithLocalAction extends AnAction implements DumbAware {
private final boolean myBeforeWithLocal;
public ShowDiffWithLocalAction() {
ActionUtil.copyFrom(this, "Vcs.ShowDiffWithLocal");
this(false);
getTemplatePresentation().setIcon(AllIcons.Actions.DiffWithCurrent);
}
public ShowDiffWithLocalAction(boolean beforeWithLocal) {
myBeforeWithLocal = beforeWithLocal;
ActionUtil.copyFrom(this, beforeWithLocal ? "Vcs.ShowDiffWithLocal.Before" : "Vcs.ShowDiffWithLocal");
}
public void actionPerformed(AnActionEvent e) {
@@ -49,9 +56,9 @@ public class ShowDiffWithLocalAction extends AnAction implements DumbAware {
List<Change> changesToLocal = new ArrayList<>();
for (int i = 0; i < selection.getChanges().size(); i++) {
if (i == selection.getIndex()) index = changesToLocal.size();
ContentRevision afterRevision = selection.getChanges().get(i).getAfterRevision();
if (afterRevision != null && isValidAfterRevision(afterRevision)) {
changesToLocal.add(new Change(afterRevision, getCurrentRevision(afterRevision, e)));
Change change = getChangeWithLocal(selection.getChanges().get(i));
if (change != null) {
changesToLocal.add(change);
}
}
@@ -60,29 +67,30 @@ public class ShowDiffWithLocalAction extends AnAction implements DumbAware {
}
}
@NotNull
protected ContentRevision getCurrentRevision(@NotNull ContentRevision afterRevision, @NotNull AnActionEvent e) {
return CurrentContentRevision.create(afterRevision.getFile());
}
public void update(final AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
ChangesSelection selection = e.getData(VcsDataKeys.CHANGES_SELECTION);
boolean isInAir = CommittedChangesBrowserUseCase.IN_AIR.equals(CommittedChangesBrowserUseCase.DATA_KEY.getData(e.getDataContext()));
boolean isToolbar = "ChangesBrowser".equals(e.getPlace());
e.getPresentation().setEnabled(project != null && selection != null && !isInAir && anyHasAfterRevision(selection.getChanges()));
e.getPresentation().setEnabled(project != null && !isToolbar && selection != null && !isInAir && canShowDiff(selection.getChanges()));
e.getPresentation().setVisible(!isToolbar);
}
private static boolean isValidAfterRevision(@Nullable final ContentRevision afterRevision) {
return afterRevision != null && !afterRevision.getFile().isNonLocal() && !afterRevision.getFile().isDirectory();
@Nullable
private Change getChangeWithLocal(@NotNull Change c) {
ContentRevision revision = myBeforeWithLocal ? c.getBeforeRevision() : c.getAfterRevision();
if (!isValidRevision(revision)) return null;
ContentRevision contentRevision = CurrentContentRevision.create(revision.getFile());
return new Change(revision, contentRevision);
}
private static boolean anyHasAfterRevision(@NotNull final List<Change> changes) {
for (Change c : changes) {
if (isValidAfterRevision(c.getAfterRevision())) {
return true;
}
}
return false;
private boolean canShowDiff(@NotNull List<Change> changes) {
return ContainerUtil.exists(changes, c -> getChangeWithLocal(c) != null);
}
private static boolean isValidRevision(@Nullable ContentRevision revision) {
return revision != null && !revision.getFile().isNonLocal() && !revision.getFile().isDirectory();
}
}
@@ -71,7 +71,9 @@ public class RepositoryChangesBrowser extends ChangesBrowser implements DataProv
protected void buildToolBar(final DefaultActionGroup toolBarGroup) {
super.buildToolBar(toolBarGroup);
toolBarGroup.add(new ShowDiffWithLocalAction());
toolBarGroup.add(new ShowDiffWithLocalAction(true));
toolBarGroup.add(new ShowDiffWithLocalAction(false));
myEditSourceAction = new MyEditSourceAction();
myEditSourceAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), this);
toolBarGroup.add(myEditSourceAction);
@@ -408,7 +408,9 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton impleme
diffAction.registerCustomShortcutSet(CommonShortcuts.getDiff(), null);
result.add(diffAction);
result.add(ActionManager.getInstance().getAction("Vcs.ShowDiffWithLocal"));
if (popup) {
result.add(ActionManager.getInstance().getAction("Vcs.ShowDiffWithLocal"));
}
final AnAction diffGroup = ActionManager.getInstance().getAction(VCS_HISTORY_ACTIONS_GROUP);
if (diffGroup != null) result.add(diffGroup);
@@ -30,11 +30,11 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
public class ShowDiffWithLocalAction extends ExtendableAction implements DumbAware {
public class ShowDiffAfterWithLocalAction extends ExtendableAction implements DumbAware {
private static final ExtensionPointName<AnActionExtensionProvider> EP_NAME =
ExtensionPointName.create("com.intellij.openapi.vcs.history.actions.ShowDiffWithLocalAction.ExtensionProvider");
ExtensionPointName.create("com.intellij.openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider");
public ShowDiffWithLocalAction() {
public ShowDiffAfterWithLocalAction() {
super(EP_NAME);
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.history.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.AnActionExtensionProvider;
import com.intellij.openapi.actionSystem.ExtendableAction;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;
public class ShowDiffBeforeWithLocalAction extends ExtendableAction implements DumbAware {
private static final ExtensionPointName<AnActionExtensionProvider> EP_NAME =
ExtensionPointName.create("com.intellij.openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction.ExtensionProvider");
public ShowDiffBeforeWithLocalAction() {
super(EP_NAME);
}
@Override
public void defaultActionPerformed(@NotNull AnActionEvent e) {
}
@Override
public void defaultUpdate(@NotNull AnActionEvent e) {
e.getPresentation().setEnabledAndVisible(false);
}
}
@@ -208,7 +208,7 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi
final DefaultActionGroup popupActions = new DefaultActionGroup();
popupActions.add(new MyDiffAction());
popupActions.add(new MyDiffLocalAction());
popupActions.add(new MyDiffAfterWithLocalAction());
popupActions.add(ShowAllAffectedGenericAction.getInstance());
popupActions.add(ActionManager.getInstance().getAction(VcsActions.ACTION_COPY_REVISION_NUMBER));
PopupHandler.installPopupHandler(myList, popupActions, ActionPlaces.UPDATE_POPUP, ActionManager.getInstance());
@@ -496,8 +496,8 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi
}
}
private class MyDiffLocalAction extends DumbAwareAction {
public MyDiffLocalAction() {
private class MyDiffAfterWithLocalAction extends DumbAwareAction {
public MyDiffAfterWithLocalAction() {
ActionUtil.copyFrom(this, "Vcs.ShowDiffWithLocal");
}
@@ -37,7 +37,8 @@
<getDataRule key="Vcs.FileHistory.Ui" implementationClass="com.intellij.vcs.log.history.FileHistoryUiDataRule"/>
<diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromHistoryActionProvider"/>
<openapi.vcs.history.actions.ShowDiffWithLocalAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.ShowDiffWithLocalFromHistoryActionProvider"/>
<openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.ShowDiffBeforeWithLocalFromHistoryActionProvider"/>
<openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.ShowDiffAfterWithLocalFromHistoryActionProvider"/>
<openapi.vcs.changes.actions.CreatePatchFromChangesAction.Dialog.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.CreatePatchFromHistoryActionProvider$Dialog"/>
<openapi.vcs.changes.actions.CreatePatchFromChangesAction.Clipboard.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.CreatePatchFromHistoryActionProvider$Clipboard"/>
</extensions>
@@ -122,6 +123,7 @@
<group id="Vcs.FileHistory.ContextMenu">
<reference id="Vcs.Log.OpenRepositoryVersion"/>
<reference id="Diff.ShowDiff"/>
<reference id="Vcs.ShowDiffWithLocal.Before"/>
<reference id="Vcs.ShowDiffWithLocal"/>
<reference id="ChangesView.CreatePatchFromChanges"/>
<reference id="Vcs.Log.GetVersion"/>
@@ -132,7 +134,6 @@
</group>
<group id="Vcs.FileHistory.Toolbar">
<reference id="Diff.ShowDiff"/>
<reference id="Vcs.ShowDiffWithLocal"/>
<reference id="ChangesView.CreatePatchFromChanges"/>
<reference id="Vcs.Log.GetVersion"/>
<reference id="Vcs.Log.AnnotateRevisionAction"/>
@@ -176,6 +177,7 @@
<group id="Log.FileHistory.KeymapGroup" popup="false">
<reference id="Vcs.Log.OpenRepositoryVersion"/>
<reference id="Diff.ShowDiff"/>
<reference id="Vcs.ShowDiffWithLocal.Before"/>
<reference id="Vcs.ShowDiffWithLocal"/>
<reference id="ChangesView.CreatePatchFromChanges"/>
<reference id="Vcs.Log.GetVersion"/>
@@ -129,7 +129,7 @@ public class FileHistoryUi extends AbstractVcsLogUi {
}
@Nullable
public FilePath getPath(@NotNull VcsFullCommitDetails details) {
public FilePath getAfterPath(@NotNull VcsFullCommitDetails details) {
if (myPath.isDirectory()) return myPath;
List<Change> changes = collectRelevantChanges(details);
@@ -143,6 +143,21 @@ public class FileHistoryUi extends AbstractVcsLogUi {
return null;// file was deleted
}
@Nullable
public FilePath getBeforePath(@NotNull VcsFullCommitDetails details) {
if (myPath.isDirectory()) return myPath;
List<Change> changes = collectRelevantChanges(details);
for (Change change : changes) {
ContentRevision revision = change.getBeforeRevision();
if (revision != null) {
return revision.getFile();
}
}
return null;// file was created
}
@NotNull
public List<Change> collectRelevantChanges(@NotNull VcsFullCommitDetails details) {
Set<FilePath> fileNames = getFileNames(details);
@@ -113,8 +113,8 @@ public class CompareRevisionsFromHistoryActionProvider implements AnActionExtens
// so that it could return a single file path for each revision
VcsFullCommitDetails newestDetail = details.get(0);
VcsFullCommitDetails olderDetail = details.get(1);
notNull(handler).showDiff(olderDetail.getRoot(), ui.getPath(olderDetail), olderDetail.getId(),
ui.getPath(newestDetail), newestDetail.getId());
notNull(handler).showDiff(olderDetail.getRoot(), ui.getAfterPath(olderDetail), olderDetail.getId(),
ui.getAfterPath(newestDetail), newestDetail.getId());
}
else if (details.size() == 1) {
VcsFullCommitDetails detail = notNull(ContainerUtil.getFirstItem(details));
@@ -28,19 +28,12 @@ import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ShowDiffWithLocalFromHistoryActionProvider extends FileHistorySingleCommitAction implements AnActionExtensionProvider {
public class ShowDiffAfterWithLocalFromHistoryActionProvider extends FileHistorySingleCommitAction implements AnActionExtensionProvider {
@Override
public boolean isActive(@NotNull AnActionEvent e) {
return e.getData(VcsLogInternalDataKeys.FILE_HISTORY_UI) != null;
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
e.getPresentation().setDescription("Compare selected revision with the local version of the file");
}
@Override
protected boolean isEnabled(@NotNull FileHistoryUi ui, @Nullable VcsFullCommitDetails detail, @NotNull AnActionEvent e) {
FilePath filePath = e.getData(VcsDataKeys.FILE_PATH);
@@ -59,6 +52,6 @@ public class ShowDiffWithLocalFromHistoryActionProvider extends FileHistorySingl
FilePath path = e.getRequiredData(VcsDataKeys.FILE_PATH);
VcsLogDiffHandler handler = e.getRequiredData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
handler.showDiffWithLocal(detail.getRoot(), ui.getPath(detail), detail.getId(), path);
handler.showDiffWithLocal(detail.getRoot(), ui.getAfterPath(detail), detail.getId(), path);
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.ui.actions.history;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.AnActionExtensionProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.VcsLogDiffHandler;
import com.intellij.vcs.log.history.FileHistoryUi;
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ShowDiffBeforeWithLocalFromHistoryActionProvider extends FileHistorySingleCommitAction implements AnActionExtensionProvider {
@Override
public boolean isActive(@NotNull AnActionEvent e) {
return e.getData(VcsLogInternalDataKeys.FILE_HISTORY_UI) != null;
}
@Override
protected boolean isEnabled(@NotNull FileHistoryUi ui, @Nullable VcsFullCommitDetails detail, @NotNull AnActionEvent e) {
FilePath filePath = e.getData(VcsDataKeys.FILE_PATH);
VcsLogDiffHandler handler = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
if (filePath == null || filePath.getVirtualFile() == null || handler == null) {
return false;
}
if (detail != null) {
return detail.getParents().size() == 1;
}
return true;
}
@Override
protected void performAction(@NotNull Project project,
@NotNull FileHistoryUi ui,
@NotNull VcsFullCommitDetails detail,
@NotNull AnActionEvent e) {
if (ChangeListManager.getInstance(project).isFreezedWithNotification(null)) return;
if (detail.getParents().size() != 1) return;
FilePath path = e.getRequiredData(VcsDataKeys.FILE_PATH);
VcsLogDiffHandler handler = e.getRequiredData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
handler.showDiffWithLocal(detail.getRoot(), ui.getBeforePath(detail), detail.getParents().get(0), path);
}
}