From 0fca4e09bd07621adcd67c94f70eb8f3024af692 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Wed, 27 Mar 2024 08:40:47 +0100 Subject: [PATCH] [vcs-log] implement "Show in File History" action for the annotations context menu GitOrigin-RevId: 8d10e772c0270b444e67a23bae747a40150ba2d3 --- .../actions/AnnotateVcsVirtualFileAction.java | 86 ++------------ .../openapi/vcs/actions/AnnotationData.kt | 41 +++++++ .../messages/VcsLogBundle.properties | 2 + .../vcs-log/impl/src/META-INF/vcs-log.xml | 1 + .../history/VcsLogFileHistoryProviderImpl.kt | 112 +++++++++++------- ...owInFileHistoryAnnotationActionProvider.kt | 75 ++++++++++++ 6 files changed, 196 insertions(+), 121 deletions(-) create mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationData.kt create mode 100644 platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/ShowInFileHistoryAnnotationActionProvider.kt diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateVcsVirtualFileAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateVcsVirtualFileAction.java index 974f2b260f58..7b462598df7c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateVcsVirtualFileAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateVcsVirtualFileAction.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2015 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. - */ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vcs.actions; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -25,22 +11,15 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.AbstractVcsHelper; +import com.intellij.openapi.vcs.VcsBundle; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.annotate.FileAnnotation; -import com.intellij.openapi.vcs.changes.ContentRevision; -import com.intellij.openapi.vcs.changes.TextRevisionNumber; -import com.intellij.openapi.vcs.history.VcsFileRevision; -import com.intellij.openapi.vcs.history.VcsFileRevisionEx; -import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vcs.impl.BackgroundableActionLock; -import com.intellij.openapi.vcs.vfs.ContentRevisionVirtualFile; -import com.intellij.openapi.vcs.vfs.VcsVirtualFile; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ObjectUtils; import com.intellij.vcs.AnnotationProviderEx; -import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.Objects; @@ -60,13 +39,13 @@ public class AnnotateVcsVirtualFileAction { if (VcsAnnotateUtil.getEditorFor(file, e.getDataContext()) == null) return false; - AnnotationData data = extractData(project, file); + AnnotationData data = AnnotationData.extractFrom(project, file); if (data == null) return false; - AnnotationProviderEx provider = ObjectUtils.tryCast(data.vcs.getAnnotationProvider(), AnnotationProviderEx.class); + AnnotationProviderEx provider = ObjectUtils.tryCast(data.getVcs().getAnnotationProvider(), AnnotationProviderEx.class); if (provider == null) return false; - return provider.isAnnotationValid(data.filePath, data.revisionNumber); + return provider.isAnnotationValid(data.getFilePath(), data.getRevisionNumber()); } private static boolean isSuspended(@NotNull AnActionEvent e) { @@ -94,10 +73,10 @@ public class AnnotateVcsVirtualFileAction { } private static void doAnnotate(@NotNull final Project project, @NotNull final Editor editor, @NotNull final VirtualFile file) { - final AnnotationData data = extractData(project, file); + final AnnotationData data = AnnotationData.extractFrom(project, file); assert data != null; - final AnnotationProviderEx provider = (AnnotationProviderEx)data.vcs.getAnnotationProvider(); + final AnnotationProviderEx provider = (AnnotationProviderEx)data.getVcs().getAnnotationProvider(); assert provider != null; @@ -111,7 +90,7 @@ public class AnnotateVcsVirtualFileAction { @Override public void run(final @NotNull ProgressIndicator indicator) { try { - fileAnnotationRef.set(provider.annotate(data.filePath, data.revisionNumber)); + fileAnnotationRef.set(provider.annotate(data.getFilePath(), data.getRevisionNumber())); } catch (VcsException e) { exceptionRef.set(e); @@ -138,7 +117,7 @@ public class AnnotateVcsVirtualFileAction { } if (!fileAnnotationRef.isNull()) { - AnnotateToggleAction.doAnnotate(editor, project, fileAnnotationRef.get(), data.vcs); + AnnotateToggleAction.doAnnotate(editor, project, fileAnnotationRef.get(), data.getVcs()); } } @@ -150,49 +129,6 @@ public class AnnotateVcsVirtualFileAction { ProgressManager.getInstance().run(annotateTask); } - @Nullable - private static AnnotationData extractData(@NotNull Project project, @NotNull VirtualFile file) { - FilePath filePath = null; - VcsRevisionNumber revisionNumber = null; - if (file instanceof VcsVirtualFile) { - VcsFileRevision revision = ((VcsVirtualFile)file).getFileRevision(); - if (revision instanceof VcsFileRevisionEx) { - filePath = ((VcsFileRevisionEx)revision).getPath(); - } - else { - filePath = VcsUtil.getFilePath(file); - } - revisionNumber = revision != null ? revision.getRevisionNumber() : null; - } - else if (file instanceof ContentRevisionVirtualFile) { - ContentRevision revision = ((ContentRevisionVirtualFile)file).getContentRevision(); - filePath = revision.getFile(); - revisionNumber = revision.getRevisionNumber(); - } - if (filePath == null || revisionNumber == null) return null; - if (revisionNumber instanceof TextRevisionNumber || - revisionNumber == VcsRevisionNumber.NULL) { - return null; - } - - AbstractVcs vcs = VcsUtil.getVcsFor(project, filePath); - return vcs != null ? new AnnotationData(vcs, filePath, revisionNumber) : null; - } - - private static class AnnotationData { - @NotNull public final AbstractVcs vcs; - @NotNull public final FilePath filePath; - @NotNull public final VcsRevisionNumber revisionNumber; - - AnnotationData(@NotNull AbstractVcs vcs, - @NotNull FilePath filePath, - @NotNull VcsRevisionNumber revisionNumber) { - this.vcs = vcs; - this.filePath = filePath; - this.revisionNumber = revisionNumber; - } - } - public static class Provider implements AnnotateToggleAction.Provider { @Override public boolean isEnabled(AnActionEvent e) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationData.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationData.kt new file mode 100644 index 000000000000..f93297efb93a --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationData.kt @@ -0,0 +1,41 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.vcs.actions + +import com.intellij.openapi.project.Project +import com.intellij.openapi.vcs.AbstractVcs +import com.intellij.openapi.vcs.FilePath +import com.intellij.openapi.vcs.changes.TextRevisionNumber +import com.intellij.openapi.vcs.history.VcsFileRevisionEx +import com.intellij.openapi.vcs.history.VcsRevisionNumber +import com.intellij.openapi.vcs.vfs.ContentRevisionVirtualFile +import com.intellij.openapi.vcs.vfs.VcsVirtualFile +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.vcsUtil.VcsUtil + +data class AnnotationData(val vcs: AbstractVcs, val filePath: FilePath, val revisionNumber: VcsRevisionNumber) { + companion object { + @JvmStatic + fun extractFrom(project: Project, file: VirtualFile): AnnotationData? { + val filePath: FilePath + val revisionNumber: VcsRevisionNumber + when (file) { + is VcsVirtualFile -> { + val revision = file.fileRevision ?: return null + filePath = if (revision is VcsFileRevisionEx) revision.path else VcsUtil.getFilePath(file) + revisionNumber = revision.revisionNumber + } + is ContentRevisionVirtualFile -> { + val revision = file.contentRevision + filePath = revision.file + revisionNumber = revision.revisionNumber + } + else -> return null + } + + if (revisionNumber is TextRevisionNumber || revisionNumber === VcsRevisionNumber.NULL) return null + + val vcs = VcsUtil.getVcsFor(project, filePath) ?: return null + return AnnotationData(vcs, filePath, revisionNumber) + } + } +} diff --git a/platform/vcs-log/api/resources/messages/VcsLogBundle.properties b/platform/vcs-log/api/resources/messages/VcsLogBundle.properties index 89ab06218c52..ffdc949b4c8f 100644 --- a/platform/vcs-log/api/resources/messages/VcsLogBundle.properties +++ b/platform/vcs-log/api/resources/messages/VcsLogBundle.properties @@ -93,6 +93,7 @@ action.Vcs.Log.ResumeIndexing.text=Resume Indexing action.Vcs.Log.ResumeIndexing.description=Indexing was paused as it took longer than expected. Resume. action.Vcs.Log.SelectInLog.text=Show in VCS Log action.Vcs.Log.SelectInLog.text.template=Show in {0} Log +vcs.log.action.show.in.file.history.text=Show in File History group.Vcs.Log.PresentationSettings.text=View Options group.Vcs.Log.PresentationSettings.description=Configure presentation of the Log group.Vcs.Log.ChangesBrowser.PresentationSettings.text=View Options @@ -164,6 +165,7 @@ file.history.commit.not.found.in.branch={0} does not exist in history for {1} in file.history.commit.not.found={0} does not exist in history for {1} file.history.commit.not.found.view.and.show.all.branches.link=View and show all branches file.history.commit.not.found.view.in.log.link=View in Log +file.history.show.commit.in.history.process=Searching commit {0} in file history # indexing progress vcs.log.status.bar.indexing.cancel.tooltip=Cancel indexing. Indexing could be restarted manually from {0} Log toolbar. diff --git a/platform/vcs-log/impl/src/META-INF/vcs-log.xml b/platform/vcs-log/impl/src/META-INF/vcs-log.xml index 6934ac9328b2..6c2756dc43bd 100644 --- a/platform/vcs-log/impl/src/META-INF/vcs-log.xml +++ b/platform/vcs-log/impl/src/META-INF/vcs-log.xml @@ -81,6 +81,7 @@ + diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.kt index c22cbf021f64..53e7dd7917c2 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.kt @@ -21,25 +21,43 @@ import com.intellij.vcs.log.visible.filters.VcsLogFilterObject import com.intellij.vcs.log.visible.filters.matches import com.intellij.vcsUtil.VcsUtil -class VcsLogFileHistoryProviderImpl(project: Project) : VcsLogFileHistoryProvider { - private val providers = listOf(VcsLogSingleFileHistoryProvider(project), VcsLogDirectoryHistoryProvider(project)) +class VcsLogFileHistoryProviderImpl(private val project: Project) : VcsLogFileHistoryProvider { override fun canShowFileHistory(paths: Collection, revisionNumber: String?): Boolean { - return providers.any { it.canShowFileHistory(paths, revisionNumber) } + return canShowFileHistory(project, paths, revisionNumber) } override fun showFileHistory(paths: Collection, revisionNumber: String?) { - providers.firstOrNull { it.canShowFileHistory(paths, revisionNumber) }?.showFileHistory(paths, revisionNumber) + selectProvider(project, paths, revisionNumber)?.showFileHistoryUi(project, paths, revisionNumber) } } -class VcsLogDirectoryHistoryProvider(private val project: Project) : VcsLogFileHistoryProvider { - override fun canShowFileHistory(paths: Collection, revisionNumber: String?): Boolean { +internal fun canShowFileHistory(project: Project, paths: Collection, revisionNumber: String?): Boolean { + return selectProvider(project, paths, revisionNumber) != null +} + +internal fun showFileHistoryUi(project: Project, paths: Collection, revisionNumber: String?, selectRow: Boolean = false): VcsLogUiEx? { + return selectProvider(project, paths, revisionNumber)?.showFileHistoryUi(project, paths, revisionNumber, selectRow) +} + +private fun selectProvider(project: Project, paths: Collection, revisionNumber: String?): FileHistoryLogUiProvider? { + return listOf(VcsLogSingleFileHistoryProvider, VcsLogDirectoryHistoryProvider).firstOrNull { + it.canShowFileHistory(project, paths, revisionNumber) + } +} + +interface FileHistoryLogUiProvider { + fun canShowFileHistory(project: Project, paths: Collection, revisionNumber: String?): Boolean + fun showFileHistoryUi(project: Project, paths: Collection, revisionNumber: String?, selectRow: Boolean = true): VcsLogUiEx? +} + +object VcsLogDirectoryHistoryProvider : FileHistoryLogUiProvider { + override fun canShowFileHistory(project: Project, paths: Collection, revisionNumber: String?): Boolean { val dataManager = VcsProjectLog.getInstance(project).dataManager ?: return false return createPathsFilter(project, dataManager.logProviders, paths) != null } - override fun showFileHistory(paths: Collection, revisionNumber: String?) { + override fun showFileHistoryUi(project: Project, paths: Collection, revisionNumber: String?, selectRow: Boolean): VcsLogUiEx? { val hash = revisionNumber?.let { HashImpl.build(it) } val root = VcsLogUtil.getActualRoot(project, paths.first())!! @@ -55,58 +73,58 @@ class VcsLogDirectoryHistoryProvider(private val project: Project) : VcsLogFileH val firstTime = ui == null if (firstTime) { val filters = VcsLogFilterObject.collection(pathsFilter, hashFilter) - ui = VcsProjectLog.getInstance(project).openLogTab(filters) ?: return + ui = VcsProjectLog.getInstance(project).openLogTab(filters) ?: return null ui.properties[MainVcsLogUiProperties.SHOW_ONLY_AFFECTED_CHANGES] = true } - selectRowWhenOpen(logManager, hash, root, ui!!, firstTime) + if (selectRow) selectRowWhenOpen(logManager, hash, root, ui!!, firstTime) + + return ui } - companion object { - fun createPathsFilter(project: Project, logProviders: Map, paths: Collection): VcsLogFilter? { - val forRootFilter = mutableSetOf() - val forPathsFilter = mutableListOf() - for (path in paths) { - val root = VcsLogUtil.getActualRoot(project, path) - if (root == null) return null - if (!logProviders.keys.contains(root) || - !VcsLogProperties.SUPPORTS_LOG_DIRECTORY_HISTORY.getOrDefault(logProviders[root])) return null + fun createPathsFilter(project: Project, logProviders: Map, paths: Collection): VcsLogFilter? { + val forRootFilter = mutableSetOf() + val forPathsFilter = mutableListOf() + for (path in paths) { + val root = VcsLogUtil.getActualRoot(project, path) + if (root == null) return null + if (!logProviders.keys.contains(root) || + !VcsLogProperties.SUPPORTS_LOG_DIRECTORY_HISTORY.getOrDefault(logProviders[root])) return null - val correctedPath = getCorrectedPath(project, path, false) - if (!correctedPath.isDirectory) return null + val correctedPath = getCorrectedPath(project, path, false) + if (!correctedPath.isDirectory) return null - if (path.virtualFile == root) { - forRootFilter.add(root) - } - else { - forPathsFilter.add(correctedPath) - } - - if (forPathsFilter.isNotEmpty() && forRootFilter.isNotEmpty()) return null + if (path.virtualFile == root) { + forRootFilter.add(root) + } + else { + forPathsFilter.add(correctedPath) } - if (forPathsFilter.isNotEmpty()) return VcsLogFilterObject.fromPaths(forPathsFilter) - return VcsLogFilterObject.fromRoots(forRootFilter) + if (forPathsFilter.isNotEmpty() && forRootFilter.isNotEmpty()) return null } - private fun createHashFilter(hash: Hash?, root: VirtualFile): VcsLogFilter { - if (hash == null) { - return VcsLogFilterObject.fromBranch(VcsLogUtil.HEAD) - } + if (forPathsFilter.isNotEmpty()) return VcsLogFilterObject.fromPaths(forPathsFilter) + return VcsLogFilterObject.fromRoots(forRootFilter) + } - return VcsLogFilterObject.fromCommit(CommitId(hash, root)) + private fun createHashFilter(hash: Hash?, root: VirtualFile): VcsLogFilter { + if (hash == null) { + return VcsLogFilterObject.fromBranch(VcsLogUtil.HEAD) } - private fun matches(filters: VcsLogFilterCollection, pathsFilter: VcsLogFilter, hashFilter: VcsLogFilter): Boolean { - if (!filters.matches(hashFilter.key, pathsFilter.key)) { - return false - } - return filters.get(pathsFilter.key) == pathsFilter && filters.get(hashFilter.key) == hashFilter + return VcsLogFilterObject.fromCommit(CommitId(hash, root)) + } + + private fun matches(filters: VcsLogFilterCollection, pathsFilter: VcsLogFilter, hashFilter: VcsLogFilter): Boolean { + if (!filters.matches(hashFilter.key, pathsFilter.key)) { + return false } + return filters.get(pathsFilter.key) == pathsFilter && filters.get(hashFilter.key) == hashFilter } } -private class VcsLogSingleFileHistoryProvider(private val project: Project) : VcsLogFileHistoryProvider { - override fun canShowFileHistory(paths: Collection, revisionNumber: String?): Boolean { +private object VcsLogSingleFileHistoryProvider : FileHistoryLogUiProvider { + override fun canShowFileHistory(project: Project, paths: Collection, revisionNumber: String?): Boolean { if (!isNewHistoryEnabled() || paths.size != 1) return false val root = VcsLogUtil.getActualRoot(project, paths.single()) ?: return false @@ -117,12 +135,12 @@ private class VcsLogSingleFileHistoryProvider(private val project: Project) : Vc return logProvider?.diffHandler != null && logProvider.getFileHistoryHandler(project) != null } - override fun showFileHistory(paths: Collection, revisionNumber: String?) { - if (paths.size != 1) return + override fun showFileHistoryUi(project: Project, paths: Collection, revisionNumber: String?, selectRow: Boolean): VcsLogUiEx? { + if (paths.size != 1) return null val root = VcsLogUtil.getActualRoot(project, paths.first())!! val path = getCorrectedPath(project, paths.single(), revisionNumber != null) - if (path.isDirectory) return + if (path.isDirectory) return null val hash = revisionNumber?.let { HashImpl.build(it) } triggerFileHistoryUsage(project, paths, hash) @@ -136,7 +154,9 @@ private class VcsLogSingleFileHistoryProvider(private val project: Project) : Vc if (firstTime) { fileHistoryUi = project.service().openFileHistoryTab(logManager, path, root, hash) } - selectRowWhenOpen(logManager, hash, root, fileHistoryUi!!, firstTime) + if (selectRow) selectRowWhenOpen(logManager, hash, root, fileHistoryUi!!, firstTime) + + return fileHistoryUi } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/ShowInFileHistoryAnnotationActionProvider.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/ShowInFileHistoryAnnotationActionProvider.kt new file mode 100644 index 000000000000..923495e13ea8 --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/ShowInFileHistoryAnnotationActionProvider.kt @@ -0,0 +1,75 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.vcs.log.ui.actions.history + +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.openapi.vcs.actions.AnnotationData +import com.intellij.openapi.vcs.actions.ShowAnnotateOperationsPopup +import com.intellij.openapi.vcs.annotate.AnnotationGutterActionProvider +import com.intellij.openapi.vcs.annotate.FileAnnotation +import com.intellij.platform.ide.progress.withBackgroundProgress +import com.intellij.util.io.await +import com.intellij.vcs.log.VcsLogBundle +import com.intellij.vcs.log.history.canShowFileHistory +import com.intellij.vcs.log.history.showFileHistoryUi +import com.intellij.vcs.log.impl.VcsLogNavigationUtil.jumpToHash +import com.intellij.vcs.log.impl.VcsProjectLog +import com.intellij.vcs.log.util.VcsLogUtil +import com.intellij.vcsUtil.VcsUtil +import kotlinx.coroutines.launch + +class ShowInFileHistoryAnnotationActionProvider : AnnotationGutterActionProvider { + override fun createAction(annotation: FileAnnotation): AnAction { + return ShowInFileHistoryAnnotationAction(annotation) + } +} + +private class ShowInFileHistoryAnnotationAction(private val annotation: FileAnnotation) : + DumbAwareAction(VcsLogBundle.message("vcs.log.action.show.in.file.history.text")) { + + override fun update(e: AnActionEvent) { + val project = e.project + val file = annotation.file + val lineRevisionNumber = getLineRevisionNumber(e) + if (project == null || file == null || lineRevisionNumber == null) { + e.presentation.isEnabledAndVisible = false + return + } + + val annotationData = AnnotationData.extractFrom(project, file) + val annotatedFilePath = annotationData?.filePath ?: VcsUtil.getFilePath(file) + val annotatedRevisionNumber = annotationData?.revisionNumber?.asString() + + e.presentation.isEnabledAndVisible = canShowFileHistory(project, listOf(annotatedFilePath), annotatedRevisionNumber) + } + + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + val file = annotation.file ?: return + val lineRevisionNumber = getLineRevisionNumber(e) ?: return + + val annotationData = AnnotationData.extractFrom(project, file) + val annotatedFilePath = annotationData?.filePath ?: VcsUtil.getFilePath(file) + val annotatedRevisionNumber = annotationData?.revisionNumber?.asString() + + val ui = showFileHistoryUi(project, listOf(annotatedFilePath), annotatedRevisionNumber) ?: return + val future = ui.jumpToHash(lineRevisionNumber, false, true) + + VcsProjectLog.getInstance(project).childScope().launch { + withBackgroundProgress(project, + VcsLogBundle.message("file.history.show.commit.in.history.process", + VcsLogUtil.getShortHash(lineRevisionNumber)), true) { + future.await() + } + } + } + + private fun getLineRevisionNumber(e: AnActionEvent): String? { + val lineNumber = ShowAnnotateOperationsPopup.getAnnotationLineNumber(e.dataContext) + return annotation.getLineRevisionNumber(lineNumber)?.asString() + } + + override fun getActionUpdateThread() = ActionUpdateThread.BGT +}