diff --git a/platform/diff-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerBase.kt b/platform/diff-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerBase.kt index 73c6806238f2..46e55eeb107f 100644 --- a/platform/diff-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerBase.kt +++ b/platform/diff-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerBase.kt @@ -51,7 +51,8 @@ abstract class LineStatusTrackerBase { var isReleased: Boolean = false private set - private var isInitialized: Boolean = false + protected var isInitialized: Boolean = false + private set protected val blocks: List get() = documentTracker.blocks internal val LOCK: DocumentTracker.Lock get() = documentTracker.LOCK @@ -93,7 +94,7 @@ abstract class LineStatusTrackerBase { } @CalledInAwt - fun setBaseRevision(vcsContent: CharSequence) { + open fun setBaseRevision(vcsContent: CharSequence) { setBaseRevision(vcsContent, null) } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java index ff796332193c..fea4481834c6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java @@ -160,13 +160,14 @@ public class ChangeListWorker { myPartialChangeTrackers.put(filePath, tracker); - tracker.initChangeTracking(myDefault.id, ContainerUtil.map(myLists, list -> list.id)); - + ListData oldList = null; Change change = getChangeForAfterPath(filePath); if (change != null) { - removeChangeMapping(change); + oldList = removeChangeMapping(change); } + tracker.initChangeTracking(myDefault.id, ContainerUtil.map(myLists, list -> list.id), oldList != null ? oldList.id : null); + if (LOG.isDebugEnabled()) { LOG.debug(String.format("[registerChangeTracker] path: %s", filePath)); } @@ -769,7 +770,7 @@ public class ChangeListWorker { ListData partialList = getDataById(listId); if (myMainWorker && partialList == null) { LOG.error(String.format("Unknown changelist %s", listId)); - tracker.initChangeTracking(myDefault.id, ContainerUtil.map(myLists, list -> list.id)); + tracker.initChangeTracking(myDefault.id, ContainerUtil.map(myLists, list -> list.id), null); } data.add(partialList != null ? partialList : myDefault); } @@ -1187,7 +1188,7 @@ public class ChangeListWorker { } @Override - public void initChangeTracking(@NotNull String defaultId, @NotNull List changelistsIds) { + public void initChangeTracking(@NotNull String defaultId, @NotNull List changelistsId, @Nullable String fileChangelistIds) { throw new UnsupportedOperationException(); } @@ -1220,7 +1221,7 @@ public class ChangeListWorker { @NotNull List getAffectedChangeListsIds(); - void initChangeTracking(@NotNull String defaultId, @NotNull List changelistsIds); + void initChangeTracking(@NotNull String defaultId, @NotNull List changelistsIds, @Nullable String fileChangelistId); void defaultListChanged(@NotNull String oldListId, @NotNull String newListId); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt index d17ba9320f75..eb6d77dd83df 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt @@ -73,6 +73,7 @@ class PartialLocalLineStatusTracker(project: Project, private var defaultMarker: ChangeListMarker private var currentMarker: ChangeListMarker? = null + private var initialChangeListId: String? = null private val affectedChangeLists = HashSet() private val batchChangeTaskCounter: AtomicInteger = AtomicInteger() @@ -116,6 +117,8 @@ class PartialLocalLineStatusTracker(project: Project, newIds.add(block.marker.changelistId) } + if (!isInitialized) initialChangeListId?.let { newIds.add(it) } + if (newIds.isEmpty()) { if (affectedChangeLists.size == 1) { newIds.add(affectedChangeLists.single()) @@ -143,7 +146,10 @@ class PartialLocalLineStatusTracker(project: Project, } @CalledInAwt - fun setBaseRevision(vcsContent: CharSequence, changelistId: String?) { + override fun setBaseRevision(vcsContent: CharSequence) { + val changelistId = if (!isInitialized) initialChangeListId else null + initialChangeListId = null + setBaseRevision(vcsContent) { if (changelistId != null) { changeListManager.executeUnderDataLock { @@ -173,10 +179,12 @@ class PartialLocalLineStatusTracker(project: Project, } - override fun initChangeTracking(defaultId: String, changelistsIds: List) { + override fun initChangeTracking(defaultId: String, changelistsIds: List, fileChangelistId: String?) { documentTracker.writeLock { defaultMarker = ChangeListMarker(defaultId) + if (!isInitialized) initialChangeListId = fileChangelistId + val idsSet = changelistsIds.toSet() moveMarkers({ !idsSet.contains(it.marker.changelistId) }, defaultMarker) @@ -195,6 +203,8 @@ class PartialLocalLineStatusTracker(project: Project, documentTracker.writeLock { if (!affectedChangeLists.contains(listId)) return@writeLock + if (!isInitialized && initialChangeListId == listId) initialChangeListId = null + moveMarkers({ it.marker.changelistId == listId }, defaultMarker) if (affectedChangeLists.size == 1 && affectedChangeLists.contains(listId)) { @@ -210,6 +220,8 @@ class PartialLocalLineStatusTracker(project: Project, documentTracker.writeLock { if (!affectedChangeLists.contains(fromListId)) return@writeLock + if (!isInitialized && initialChangeListId == fromListId) initialChangeListId = toListId + moveMarkers({ it.marker.changelistId == fromListId }, ChangeListMarker(toListId)) updateAffectedChangeLists(false) @@ -218,6 +230,8 @@ class PartialLocalLineStatusTracker(project: Project, override fun moveChangesTo(toListId: String) { documentTracker.writeLock { + if (!isInitialized) initialChangeListId = toListId + moveMarkers({ true }, ChangeListMarker(toListId)) updateAffectedChangeLists(false) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt index fe5f8f61654b..ef41a55bc639 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt @@ -391,18 +391,14 @@ class LineStatusTrackerManager( @CalledInAwt - private fun installTracker(virtualFile: VirtualFile, - document: Document) { + private fun installTracker(virtualFile: VirtualFile, document: Document) { if (!canGetBaseRevisionFor(virtualFile)) return - val changelistId = changeListManager.getChangeList(virtualFile)?.id - installTracker(virtualFile, document, changelistId) + doInstallTracker(virtualFile, document) } @CalledInAwt - private fun installTracker(virtualFile: VirtualFile, - document: Document, - oldChangesChangelistId: String?): LineStatusTracker<*>? { + private fun doInstallTracker(virtualFile: VirtualFile, document: Document): LineStatusTracker<*>? { synchronized(LOCK) { if (isDisposed) return null if (trackers[document] != null) return null @@ -418,7 +414,7 @@ class LineStatusTrackerManager( trackers.put(document, data) registerTrackerInCLM(data) - refreshTracker(tracker, changelistId = oldChangesChangelistId) + refreshTracker(tracker) eventDispatcher.multicaster.onTrackerAdded(tracker) log("Tracker installed", virtualFile) @@ -471,10 +467,10 @@ class LineStatusTrackerManager( } @CalledInAwt - private fun refreshTracker(tracker: LineStatusTracker<*>, changelistId: String? = null) { + private fun refreshTracker(tracker: LineStatusTracker<*>) { synchronized(LOCK) { if (isDisposed) return - loader.scheduleRefresh(RefreshRequest(tracker.document, changelistId)) + loader.scheduleRefresh(RefreshRequest(tracker.document)) log("Refresh queued", tracker.virtualFile) } @@ -583,20 +579,16 @@ class LineStatusTrackerManager( } val tracker = getLineStatusTracker(document)!! - if (tracker is PartialLocalLineStatusTracker) { - val changelist = request.changelistId ?: changeListManager.getChangeList(virtualFile)?.id - tracker.setBaseRevision(refreshData.text, changelist) + tracker.setBaseRevision(refreshData.text) + log("Loading finished: success", virtualFile) + if (tracker is PartialLocalLineStatusTracker) { val state = fileStatesAwaitingRefresh.remove(tracker.virtualFile) if (state != null) { tracker.restoreState(state) log("Loading finished: state restored", virtualFile) } } - else { - tracker.setBaseRevision(refreshData.text) - } - log("Loading finished: success", virtualFile) } } } @@ -688,7 +680,7 @@ class LineStatusTrackerManager( if (changeList != null && !changeList.isDefault) { log("Tracker install from DocumentListener: ", virtualFile) - val tracker = installTracker(virtualFile, document, changeList.id) + val tracker = doInstallTracker(virtualFile, document) if (tracker is PartialLocalLineStatusTracker) { tracker.replayChangesFromDocumentEvents(listOf(event)) } @@ -779,7 +771,7 @@ class LineStatusTrackerManager( private class ContentInfo(val revision: VcsRevisionNumber, val charset: Charset) - private class RefreshRequest(val document: Document, val changelistId: String? = null) { + private class RefreshRequest(val document: Document) { override fun equals(other: Any?): Boolean = other is RefreshRequest && document == other.document override fun hashCode(): Int = document.hashCode() } diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt index 64f3c1aabea8..72c82fff985a 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt @@ -378,7 +378,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { init { resetChangelists() - partialTracker.initChangeTracking(defaultChangeListIds(), changeListIds()) + partialTracker.initChangeTracking(defaultChangeListIds(), changeListIds(), null) } override fun destroy() {