From 098d37f983024022f9ac7795a20b6a28bad43b32 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sat, 25 Mar 2023 16:08:01 +0100 Subject: [PATCH] Added support to opening submodules directly Fixes #58 --- .../OpenSubmoduleRepositoryUseCase.kt | 35 +++++++++++++++++++ .../gitnuro/viewmodels/TabViewModel.kt | 18 ++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/git/repository/OpenSubmoduleRepositoryUseCase.kt diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/repository/OpenSubmoduleRepositoryUseCase.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/repository/OpenSubmoduleRepositoryUseCase.kt new file mode 100644 index 0000000..a8baac2 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/repository/OpenSubmoduleRepositoryUseCase.kt @@ -0,0 +1,35 @@ +package com.jetpackduba.gitnuro.git.repository + +import com.jetpackduba.gitnuro.exceptions.InvalidDirectoryException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.submodule.SubmoduleWalk +import java.io.File +import javax.inject.Inject + +class OpenSubmoduleRepositoryUseCase @Inject constructor( + private val openRepositoryUseCase: OpenRepositoryUseCase +) { + suspend operator fun invoke(directory: File): Repository = withContext(Dispatchers.IO) { + val parent = getRepositoryParent(directory) + ?: throw InvalidDirectoryException("Submodule's parent repository not found") + + val repository = openRepositoryUseCase(parent) + + val submoduleRelativePath = directory.absolutePath.removePrefix("${repository.directory.parent}/") + + return@withContext SubmoduleWalk.getSubmoduleRepository(repository, submoduleRelativePath) + ?: throw InvalidDirectoryException("Invalid submodule directory. Check if the submodule has been initialized before trying to open it.") + } + + private fun getRepositoryParent(directory: File?): File? { + if (directory == null) return null + + if (directory.listFiles()?.any { it.name == ".git" && it.isDirectory } == true) { + return directory + } + + return getRepositoryParent(directory.parentFile) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt index 2d4823d..ed9f6ca 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt @@ -11,6 +11,7 @@ import com.jetpackduba.gitnuro.git.rebase.AbortRebaseUseCase import com.jetpackduba.gitnuro.git.repository.GetRepositoryStateUseCase import com.jetpackduba.gitnuro.git.repository.InitLocalRepositoryUseCase import com.jetpackduba.gitnuro.git.repository.OpenRepositoryUseCase +import com.jetpackduba.gitnuro.git.repository.OpenSubmoduleRepositoryUseCase import com.jetpackduba.gitnuro.git.stash.StashChangesUseCase import com.jetpackduba.gitnuro.git.workspace.StageUntrackedFileUseCase import com.jetpackduba.gitnuro.logging.printLog @@ -46,6 +47,7 @@ class TabViewModel @Inject constructor( private val getRepositoryStateUseCase: GetRepositoryStateUseCase, private val initLocalRepositoryUseCase: InitLocalRepositoryUseCase, private val openRepositoryUseCase: OpenRepositoryUseCase, + private val openSubmoduleRepositoryUseCase: OpenSubmoduleRepositoryUseCase, private val diffViewModelProvider: Provider, private val rebaseInteractiveViewModelProvider: Provider, private val historyViewModelProvider: Provider, @@ -165,15 +167,25 @@ class TabViewModel @Inject constructor( _repositorySelectionStatus.value = RepositorySelectionStatus.Opening(directory.absolutePath) - val repository: Repository = openRepositoryUseCase(directory) - try { + val repository: Repository = if (directory.listFiles()?.any { it.name == ".git" && it.isFile } == true) { + openSubmoduleRepositoryUseCase(directory) + } else { + openRepositoryUseCase(directory) + } + + repository.workTree // test if repository is valid _repositorySelectionStatus.value = RepositorySelectionStatus.Open(repository) val git = Git(repository) tabState.initGit(git) - onRepositoryChanged(repository.directory.parent) + val path = if(directory.name == ".git") { + directory.parent + } else + directory.absolutePath + + onRepositoryChanged(path) tabState.newSelectedItem(selectedItem = SelectedItem.UncommitedChanges) newDiffSelected = null refreshRepositoryInfo()