package app.git import app.git.graph.GraphCommitList import app.git.graph.GraphWalk import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ensureActive import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.ResetCommand import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.revwalk.RevCommit import javax.inject.Inject class LogManager @Inject constructor( private val statusManager: StatusManager, ) { suspend fun loadLog(git: Git, currentBranch: Ref?) = withContext(Dispatchers.IO) { val commitList = GraphCommitList() val repositoryState = git.repository.repositoryState println("Repository state ${repositoryState.description}") if (currentBranch != null || repositoryState.isRebasing) { // Current branch is null when there is no log (new repo) or rebasing val logList = git.log().setMaxCount(2).call().toList() val walk = GraphWalk(git.repository) walk.use { walk.markStartAllRefs(Constants.R_HEADS) walk.markStartAllRefs(Constants.R_REMOTES) walk.markStartAllRefs(Constants.R_TAGS) if (statusManager.hasUncommitedChanges(git)) commitList.addUncommitedChangesGraphCommit(logList.first()) commitList.source(walk) commitList.fillTo(1000) // TODO: Limited commits to show to 1000, add a setting to let the user adjust this } ensureActive() } return@withContext commitList } suspend fun checkoutCommit(git: Git, revCommit: RevCommit) = withContext(Dispatchers.IO) { git .checkout() .setName(revCommit.name) .call() } suspend fun revertCommit(git: Git, revCommit: RevCommit) = withContext(Dispatchers.IO) { git .revert() .include(revCommit) .call() } suspend fun resetToCommit(git: Git, revCommit: RevCommit, resetType: ResetType) = withContext(Dispatchers.IO) { val reset = when (resetType) { ResetType.SOFT -> ResetCommand.ResetType.SOFT ResetType.MIXED -> ResetCommand.ResetType.MIXED ResetType.HARD -> ResetCommand.ResetType.HARD } git .reset() .setMode(reset) .setRef(revCommit.name) .call() } suspend fun latestMessage(git: Git): String = withContext(Dispatchers.IO) { try { val log = git.log().setMaxCount(1).call() val latestCommitNode = log.firstOrNull() return@withContext if(latestCommitNode == null) "" else latestCommitNode.fullMessage } catch (ex: Exception) { ex.printStackTrace() return@withContext "" } } suspend fun hasPreviousCommits(git: Git): Boolean = withContext(Dispatchers.IO) { try { val log = git.log().setMaxCount(1).call() val latestCommitNode = log.firstOrNull() return@withContext latestCommitNode != null } catch (ex: Exception) { ex.printStackTrace() return@withContext false } } } enum class ResetType { SOFT, MIXED, HARD, }