diff --git a/platform/lvcs-impl/api-dump-unreviewed.txt b/platform/lvcs-impl/api-dump-unreviewed.txt index f491e47facaa..878b82533727 100644 --- a/platform/lvcs-impl/api-dump-unreviewed.txt +++ b/platform/lvcs-impl/api-dump-unreviewed.txt @@ -827,7 +827,7 @@ f:com.intellij.openapi.command.impl.FileUndoProvider - a:getPresentation(com.intellij.platform.lvcs.impl.ActivityItem):com.intellij.platform.lvcs.impl.ActivityPresentation - a:getSupportedFilterKindFor(com.intellij.platform.lvcs.impl.ActivityScope):com.intellij.platform.lvcs.impl.FilterKind - a:loadActivityList(com.intellij.platform.lvcs.impl.ActivityScope,java.lang.String):com.intellij.platform.lvcs.impl.ActivityData -- a:loadDiffData(com.intellij.platform.lvcs.impl.ActivityScope,com.intellij.platform.lvcs.impl.ActivitySelection):com.intellij.platform.lvcs.impl.ActivityDiffData +- a:loadDiffData(com.intellij.platform.lvcs.impl.ActivityScope,com.intellij.platform.lvcs.impl.ActivitySelection,com.intellij.platform.lvcs.impl.DirectoryDiffMode):com.intellij.platform.lvcs.impl.ActivityDiffData - a:loadSingleDiff(com.intellij.platform.lvcs.impl.ActivityScope,com.intellij.platform.lvcs.impl.ActivitySelection):com.intellij.diff.chains.DiffRequestProducer *:com.intellij.platform.lvcs.impl.ActivityScope - *sf:Companion:com.intellij.platform.lvcs.impl.ActivityScope$Companion @@ -953,6 +953,13 @@ f:com.intellij.platform.lvcs.impl.ChangeSetSelectionKt - sf:getLeftRevision(com.intellij.platform.lvcs.impl.ChangeSetSelection):com.intellij.platform.lvcs.impl.RevisionId - sf:getRightRevision(com.intellij.platform.lvcs.impl.ChangeSetSelection):com.intellij.platform.lvcs.impl.RevisionId - sf:toChangeSetSelection(com.intellij.platform.lvcs.impl.ActivitySelection):com.intellij.platform.lvcs.impl.ChangeSetSelection +*e:com.intellij.platform.lvcs.impl.DirectoryDiffMode +- java.lang.Enum +- sf:WithLocal:com.intellij.platform.lvcs.impl.DirectoryDiffMode +- sf:WithNext:com.intellij.platform.lvcs.impl.DirectoryDiffMode +- s:getEntries():kotlin.enums.EnumEntries +- s:valueOf(java.lang.String):com.intellij.platform.lvcs.impl.DirectoryDiffMode +- s:values():com.intellij.platform.lvcs.impl.DirectoryDiffMode[] *e:com.intellij.platform.lvcs.impl.FilterKind - java.lang.Enum - sf:CONTENT:com.intellij.platform.lvcs.impl.FilterKind @@ -1066,6 +1073,7 @@ f:com.intellij.platform.lvcs.impl.ui.ActivityView$Companion - f:showInToolWindow(com.intellij.openapi.project.Project,com.intellij.history.integration.IdeaGateway,com.intellij.platform.lvcs.impl.ActivityScope):V *f:com.intellij.platform.lvcs.impl.ui.ActivityViewDataKeys - sf:INSTANCE:com.intellij.platform.lvcs.impl.ui.ActivityViewDataKeys +- f:getDIRECTORY_DIFF_MODE():com.intellij.openapi.actionSystem.DataKey - f:getSCOPE():com.intellij.openapi.actionSystem.DataKey - f:getSELECTED_DIFFERENCES():com.intellij.openapi.actionSystem.DataKey - f:getSELECTION():com.intellij.openapi.actionSystem.DataKey diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ActivityProvider.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ActivityProvider.kt index e57313310cc7..3f201c1b5e7b 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ActivityProvider.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ActivityProvider.kt @@ -12,7 +12,7 @@ interface ActivityProvider { fun loadActivityList(scope: ActivityScope, fileFilter: String?): ActivityData fun filterActivityList(scope: ActivityScope, data: ActivityData, contentFilter: String?): Set? - fun loadDiffData(scope: ActivityScope, selection: ActivitySelection): ActivityDiffData? + fun loadDiffData(scope: ActivityScope, selection: ActivitySelection, diffMode: DirectoryDiffMode): ActivityDiffData? fun loadSingleDiff(scope: ActivityScope, selection: ActivitySelection): DiffRequestProducer? fun getSupportedFilterKindFor(scope: ActivityScope): FilterKind @@ -23,4 +23,9 @@ interface ActivityProvider { @ApiStatus.Experimental enum class FilterKind { FILE, CONTENT +} + +@ApiStatus.Experimental +enum class DirectoryDiffMode { + WithLocal, WithNext } \ No newline at end of file diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/LocalHistoryActivityProvider.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/LocalHistoryActivityProvider.kt index 8139806fe8e7..4f4c415a7fdd 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/LocalHistoryActivityProvider.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/LocalHistoryActivityProvider.kt @@ -131,9 +131,9 @@ internal class LocalHistoryActivityProvider(val project: Project, private val ga return data.items.filterTo(mutableSetOf()) { (it is ChangeSetActivityItem) && filteredIds.contains(it.id) } } - override fun loadDiffData(scope: ActivityScope, selection: ActivitySelection): ActivityDiffData? { + override fun loadDiffData(scope: ActivityScope, selection: ActivitySelection, diffMode: DirectoryDiffMode): ActivityDiffData? { val changeSetSelection = selection.toChangeSetSelection() ?: return null - return facade.createDiffData(gateway, scope, changeSetSelection, USE_OLD_CONTENT) + return facade.createDiffData(gateway, scope, changeSetSelection, diffMode, USE_OLD_CONTENT) } override fun loadSingleDiff(scope: ActivityScope, selection: ActivitySelection): DiffRequestProducer? { diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/ChangeSetSelectionAction.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/ChangeSetSelectionAction.kt index 6833d114d0b0..22cd21452a56 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/ChangeSetSelectionAction.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/ChangeSetSelectionAction.kt @@ -45,9 +45,9 @@ abstract class ChangeSetSelectionAction : DumbAwareAction() { val selection = activitySelection.toChangeSetSelection() ?: return - actionPerformed(project, facade, gateway, activityScope, selection) + actionPerformed(project, facade, gateway, activityScope, selection, e) } abstract fun actionPerformed(project: Project, facade: LocalHistoryFacade, gateway: IdeaGateway, - activityScope: ActivityScope, selection: ChangeSetSelection) + activityScope: ActivityScope, selection: ChangeSetSelection, e: AnActionEvent) } \ No newline at end of file diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/CreatePatchAction.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/CreatePatchAction.kt index 42baf3719c70..007647008c16 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/CreatePatchAction.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/CreatePatchAction.kt @@ -7,6 +7,7 @@ import com.intellij.history.core.revisions.Difference import com.intellij.history.integration.IdeaGateway import com.intellij.history.integration.LocalHistoryBundle import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages @@ -15,9 +16,11 @@ import com.intellij.openapi.vcs.changes.Change import com.intellij.openapi.vcs.changes.actions.CreatePatchFromChangesAction import com.intellij.platform.lvcs.impl.ActivityScope import com.intellij.platform.lvcs.impl.ChangeSetSelection +import com.intellij.platform.lvcs.impl.DirectoryDiffMode import com.intellij.platform.lvcs.impl.USE_OLD_CONTENT import com.intellij.platform.lvcs.impl.diff.getDiff import com.intellij.platform.lvcs.impl.statistics.LocalHistoryCounter +import com.intellij.platform.lvcs.impl.ui.ActivityViewDataKeys internal class CreatePatchAction : ChangeSetSelectionAction() { @@ -25,11 +28,13 @@ internal class CreatePatchAction : ChangeSetSelectionAction() { facade: LocalHistoryFacade, gateway: IdeaGateway, activityScope: ActivityScope, - selection: ChangeSetSelection) { + selection: ChangeSetSelection, + e: AnActionEvent) { LocalHistoryCounter.logActionInvoked(LocalHistoryCounter.ActionKind.CreatePatch, activityScope) + val diffMode = e.getData(ActivityViewDataKeys.DIRECTORY_DIFF_MODE) ?: DirectoryDiffMode.WithLocal val changes = ProgressManager.getInstance().runProcessWithProgressSynchronously(ThrowableComputable { - val diff = facade.getDiff(gateway, activityScope, selection, USE_OLD_CONTENT) + val diff = facade.getDiff(gateway, activityScope, selection, diffMode, USE_OLD_CONTENT) if (diff.any { it.left?.hasUnavailableContent() == true || it.right?.hasUnavailableContent() == true }) { return@ThrowableComputable null } diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/RevertAction.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/RevertAction.kt index 281621e28418..34d61d9e0c12 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/RevertAction.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/actions/RevertAction.kt @@ -4,9 +4,11 @@ package com.intellij.platform.lvcs.impl.actions import com.intellij.history.core.LocalHistoryFacade import com.intellij.history.integration.IdeaGateway import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.project.Project import com.intellij.platform.lvcs.impl.ActivityScope import com.intellij.platform.lvcs.impl.ChangeSetSelection +import com.intellij.platform.lvcs.impl.DirectoryDiffMode import com.intellij.platform.lvcs.impl.USE_OLD_CONTENT import com.intellij.platform.lvcs.impl.operations.createReverter import com.intellij.platform.lvcs.impl.statistics.LocalHistoryCounter @@ -21,10 +23,12 @@ internal class RevertAction : ChangeSetSelectionAction() { facade: LocalHistoryFacade, gateway: IdeaGateway, activityScope: ActivityScope, - selection: ChangeSetSelection) { + selection: ChangeSetSelection, + e: AnActionEvent) { LocalHistoryCounter.logActionInvoked(LocalHistoryCounter.ActionKind.RevertRevisions, activityScope) - val reverter = facade.createReverter(project, gateway, activityScope, selection, USE_OLD_CONTENT) + val diffMode = DirectoryDiffMode.WithLocal // revert everything after the selected changeset + val reverter = facade.createReverter(project, gateway, activityScope, selection, diffMode, USE_OLD_CONTENT) if (reverter == null || reverter.checkCanRevert().isNotEmpty()) return reverter.revert() } diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/diff/ActivityDiffDataImpl.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/diff/ActivityDiffDataImpl.kt index b93038349487..6f8e56dfcf95 100644 --- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/diff/ActivityDiffDataImpl.kt +++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/diff/ActivityDiffDataImpl.kt @@ -15,8 +15,9 @@ private class ActivityDiffDataImpl(override val presentableChanges: Iterable
,
+                                        diffMode: DirectoryDiffMode,
                                         isOldContentUsed: Boolean): List {
-  return entryPaths.flatMap {
-    val leftEntry = findEntry(rootEntry, selection.leftRevision, it, isOldContentUsed)
-    val rightEntry = findEntry(rootEntry, selection.rightRevision, it, isOldContentUsed)
-    Entry.getDifferencesBetween(leftEntry, rightEntry, selection.rightRevision is RevisionId.Current)
+  val leftRevision = selection.leftRevision
+  val rightRevision = when (diffMode) {
+    DirectoryDiffMode.WithLocal -> selection.rightRevision
+    DirectoryDiffMode.WithNext -> {
+      val rightItem = selection.rightItem
+      if (rightItem != null) RevisionId.ChangeSet(rightItem.id) else nextRevision(leftRevision)
+    }
   }
+  return entryPaths.flatMap {
+    val leftEntry = findEntry(rootEntry, leftRevision, it, isOldContentUsed)
+    val rightEntry = findEntry(rootEntry, rightRevision, it, isOldContentUsed)
+    Entry.getDifferencesBetween(leftEntry, rightEntry, rightRevision is RevisionId.Current)
+  }
+}
+
+private fun LocalHistoryFacade.nextRevision(revisionId: RevisionId): RevisionId {
+  if (revisionId is RevisionId.Current) return RevisionId.Current
+  revisionId as RevisionId.ChangeSet
+
+  var nextChange: Long? = null
+  for (change in changes) {
+    if (change.id == revisionId.id) break
+    nextChange = change.id
+  }
+  return nextChange?.let { RevisionId.ChangeSet(it) } ?: RevisionId.Current
 }
 
 internal fun LocalHistoryFacade.getDiff(gateway: IdeaGateway,
                                         scope: ActivityScope,
                                         selection: ChangeSetSelection,
+                                        diffMode: DirectoryDiffMode,
                                         isOldContentUsed: Boolean): List {
   val rootEntry = selection.data.getRootEntry(gateway)
   val entryPaths = getEntryPaths(gateway, scope)
-  return getDiff(rootEntry, selection, entryPaths, isOldContentUsed).toList()
+  return getDiff(rootEntry, selection, entryPaths, diffMode, isOldContentUsed).toList()
 }
 
 internal fun getEntryPaths(gateway: IdeaGateway, scope: ActivityScope): Collection {
diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/operations/Revert.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/operations/Revert.kt
index bccc832b4d12..24028dd9415d 100644
--- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/operations/Revert.kt
+++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/operations/Revert.kt
@@ -18,7 +18,7 @@ import org.jetbrains.annotations.Nls
 import java.util.function.Supplier
 
 internal fun LocalHistoryFacade.createReverter(project: Project, gateway: IdeaGateway, scope: ActivityScope, selection: ChangeSetSelection,
-                                               isOldContentUsed: Boolean): Reverter? {
+                                               diffMode: DirectoryDiffMode, isOldContentUsed: Boolean): Reverter? {
   val targetRevisionId = selection.leftRevision
   if (targetRevisionId == RevisionId.Current) return null
 
@@ -32,7 +32,7 @@ internal fun LocalHistoryFacade.createReverter(project: Project, gateway: IdeaGa
                              commandNameSupplier)
   }
 
-  val diff = getDiff(gateway, scope, selection, isOldContentUsed)
+  val diff = getDiff(gateway, scope, selection, diffMode, isOldContentUsed)
   return DifferenceReverter(project, this, gateway, diff, commandNameSupplier)
 }
 
diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityView.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityView.kt
index d64bacb99793..b49f1114bb0c 100644
--- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityView.kt
+++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityView.kt
@@ -151,6 +151,7 @@ class ActivityView(private val project: Project, gateway: IdeaGateway, val activ
     if (ActivityViewDataKeys.SELECTION.`is`(dataId)) return activityList.selection
     if (ActivityViewDataKeys.SCOPE.`is`(dataId)) return activityScope
     if (EditorTabDiffPreviewManager.EDITOR_TAB_DIFF_PREVIEW.`is`(dataId)) return editorDiffPreview
+    if (ActivityViewDataKeys.DIRECTORY_DIFF_MODE.`is`(dataId)) return model.diffMode
     return null
   }
 
diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewDataKeys.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewDataKeys.kt
index 0c998cfeda5b..b2f5b3589e23 100644
--- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewDataKeys.kt
+++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewDataKeys.kt
@@ -5,6 +5,7 @@ import com.intellij.openapi.actionSystem.DataKey
 import com.intellij.openapi.vcs.changes.ui.PresentableChange
 import com.intellij.platform.lvcs.impl.ActivityScope
 import com.intellij.platform.lvcs.impl.ActivitySelection
+import com.intellij.platform.lvcs.impl.DirectoryDiffMode
 import org.jetbrains.annotations.ApiStatus
 
 @ApiStatus.Experimental
@@ -12,4 +13,5 @@ object ActivityViewDataKeys {
   val SELECTION: DataKey = DataKey.create("ActivityView.Selection")
   val SCOPE: DataKey = DataKey.create("ActivityView.Scope")
   val SELECTED_DIFFERENCES: DataKey> = DataKey.create("ActivityView.SelectedDifferences")
+  val DIRECTORY_DIFF_MODE: DataKey = DataKey.create("ActivityView.DirectoryDiffMode")
 }
\ No newline at end of file
diff --git a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewModel.kt b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewModel.kt
index b412e9fd7c42..21e5d24dcc18 100644
--- a/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewModel.kt
+++ b/platform/lvcs-impl/src/com/intellij/platform/lvcs/impl/ui/ActivityViewModel.kt
@@ -22,6 +22,7 @@ internal class ActivityViewModel(private val project: Project, gateway: IdeaGate
 
   private val activityItemsFlow = MutableStateFlow(ActivityData.EMPTY)
   private val selectionFlow = MutableStateFlow(null)
+  private val diffModeFlow = MutableStateFlow(DirectoryDiffMode.WithLocal)
 
   private val filterFlow = MutableStateFlow(null)
 
@@ -50,15 +51,15 @@ internal class ActivityViewModel(private val project: Project, gateway: IdeaGate
     }
     if (!isSingleDiffSupported) {
       coroutineScope.launch {
-        selectionFlow.collectLatest { selection ->
-          thisLogger().debug("Loading diff data for $activityScope")
+        combine(selectionFlow, diffModeFlow) { s, d -> s to d }.collectLatest { (selection, diffMode) ->
+          thisLogger().debug("Loading diff data for $activityScope diff mode $diffMode")
           withContext(Dispatchers.EDT) {
             eventDispatcher.multicaster.onDiffDataLoadingStarted()
           }
           val diffData = selection?.let {
             withContext(Dispatchers.Default) {
               LocalHistoryCounter.logLoadDiff(project, activityScope) {
-                activityProvider.loadDiffData(activityScope, selection)
+                activityProvider.loadDiffData(activityScope, selection, diffMode)
               }
             }
           }
@@ -89,6 +90,7 @@ internal class ActivityViewModel(private val project: Project, gateway: IdeaGate
   }
 
   internal val selection get() = selectionFlow.value
+  internal val diffMode get() = diffModeFlow.value
 
   internal val isSingleDiffSupported get() = !activityScope.hasMultipleFiles
 
diff --git a/platform/lvcs-impl/testSrc/com/intellij/platform/lvcs/impl/LocalHistoryActivityProviderTest.kt b/platform/lvcs-impl/testSrc/com/intellij/platform/lvcs/impl/LocalHistoryActivityProviderTest.kt
index 9d7a4727b2e5..2c428a3337c5 100644
--- a/platform/lvcs-impl/testSrc/com/intellij/platform/lvcs/impl/LocalHistoryActivityProviderTest.kt
+++ b/platform/lvcs-impl/testSrc/com/intellij/platform/lvcs/impl/LocalHistoryActivityProviderTest.kt
@@ -234,12 +234,40 @@ class LocalHistoryActivityProviderTest : IntegrationTestCase() {
     TestCase.assertEquals(listOf("ADDED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, 3, 4))
     TestCase.assertEquals(listOf("ADDED:${file.name}", "ADDED:${directory.name}", "ADDED:${innerDirectory.name}").sorted(),
                           getDiffDataForSelection(provider, scope, activityList, 0, 4))
+
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithNext, 0))
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, 0))
+
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithNext, 1))
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, 1))
+
+    TestCase.assertEquals(listOf("ADDED:${innerDirectory.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithNext, 2))
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}", "ADDED:${innerDirectory.name}").sorted(),
+                          getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, 2))
+
+    TestCase.assertEquals(listOf("ADDED:${directory.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithNext, 3))
+    TestCase.assertEquals(listOf("MODIFIED:${file.name}", "ADDED:${directory.name}", "ADDED:${innerDirectory.name}").sorted(),
+                          getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, 3))
+
+    TestCase.assertEquals(listOf("ADDED:${file.name}"), getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithNext, 4))
+    TestCase.assertEquals(listOf("ADDED:${file.name}", "ADDED:${directory.name}", "ADDED:${innerDirectory.name}").sorted(),
+                          getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, 4))
+  }
+
+  private fun getDiffDataForSelection(provider: LocalHistoryActivityProvider, scope: ActivityScope, activityList: ActivityData,
+                                      diffMode: DirectoryDiffMode, index: Int): List {
+    return getDiffDataForSelection(provider, scope, activityList, diffMode, index, index)
   }
 
   private fun getDiffDataForSelection(provider: LocalHistoryActivityProvider, scope: ActivityScope, activityList: ActivityData,
                                       from: Int, to: Int): List {
-    val selection = ActivitySelection(listOf(activityList.items[from], activityList.items[to]), activityList)
-    return provider.loadDiffData(scope, selection)!!.presentableChanges.map { "${it.fileStatus}:${it.filePath.name}" }.sorted()
+    return getDiffDataForSelection(provider, scope, activityList, DirectoryDiffMode.WithLocal, from, to)
+  }
+
+  private fun getDiffDataForSelection(provider: LocalHistoryActivityProvider, scope: ActivityScope, activityList: ActivityData,
+                                      diffMode: DirectoryDiffMode, from: Int, to: Int): List {
+    val selection = ActivitySelection(listOf(from, to).distinct().map { activityList.items[it] }, activityList)
+    return provider.loadDiffData(scope, selection, diffMode)!!.presentableChanges.map { "${it.fileStatus}:${it.filePath.name}" }.sorted()
   }
 
   private fun ActivityData.getLabelNameSet(): Set {