More files to support .ignore
[?]
Apr 4, 2021, 6:38 PM
A7IL6I3VCB3F3QMYQFPXBL33DN5XDGGQPZIBZRHYSQBSIUBBFQJQCDependencies
- [2]
37OJKSWJImproved caching code a lot - [3]
ISO7J5ZHMore caches, better and generic cache code. Now Dracon listen to file changes to drop cached data. Implemented caches: - File contents in specific revision (never dropped) - Pijul ls and Pijul diff results - File Revision and File changes by patch - some others.. Dracon is incredible fast now, but still will take some time for bigger repos. - [4]
Q7FXTHVUFirst record support, YEAAAH, RECOOORD - [5]
5AUENX2YAdd support to view files affected by a revision - [6]
QXUEMZ3BInitial CahngeProvider - [7]
6CR2EFUNFirst ChangeProvider implementation!!! Wheehooo - [8]
OPFG6CZ2File status tracking supported. - [9]
FNNW5IEAAdded more plugin files to Pijul - [10]
2N67RQZCAdd auto installation support and cache content of ContentRevision - [11]
FRFFQV7VBasic show history support. - [12]
ZCRW57C5Improved support for revisions - [13]
Q35OTML2Remove use of coroutines, which was blocking IntelliJ UI in larger repositories Improvements for bigger repositories, now Dracon caches the changes that happened in a revision in a file, so everytime Dracon needs to query the changes of a revision, it loads directly from memory instead of doing a full-scan in Pijul repository. For tiny projects it is not a problem, but for medium ones it takes more than five minutes to scan the entire repository (and it was tested with a repo of only 700 records, however there was changes that had more than 60.000 lines). The cache file is saved in IntelliJ Data Path (project specific) and is compressed with gzip, so it will not use so much disk space (the cost worths the gains). - [14]
UERDG6LDAdded more plugin files to Pijul - [15]
EAGIDXOLBuild 2 to only listen to changes in project under pijul - [16]
B43WNBLF- Add Show History to Pijul menu - Always ignore .idea and .pijul in tracking. - Make findPijul a generic function to allow to find editor-server. - Only show one revision for directories. - Add `Hunk::resolvePath(Path)` to resolve the affected file to a Java NIO Path. - Fix StringOutOfBounds in Change Parsering Algorithm - Use editor-server instead of copie for interfacing with `pijul record` file. - Fix FileStatus provider not returning correctly for untracked files. - Add CommittedChangesProvider for Pijul. - [*]
GGYFPXNDInitial plugin
Change contents
- edit in src/main/resources/META-INF/plugin.xml at line 31
<vcsRepositoryCreator implementation="com.github.jonathanxd.dracon.repository.PijulRepositoryCreator"/><vcsRepositoryInitializer implementation="com.github.jonathanxd.dracon.repository.PijulRepositoryInit"/><vcs.ignoredFilesHolder implementation="com.github.jonathanxd.dracon.ignore.PijulIgnoredFileHolderProvider"/><ignoredFileContentProvider implementation="com.github.jonathanxd.dracon.ignore.PijulIgnoredFileContentProvider"/> - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 14
import com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.ignore.IgnoreUtil - replacement in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 45
status.resultif (status.result == FileStatus.UNKNOWN && isIgnored(virtualFile)) {FileStatus.IGNORED} else {status.result} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 51
nullif (isIgnored(virtualFile)) {FileStatus.IGNORED} else {null} - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 59
fun isIgnored(virtualFile: VirtualFile) =IgnoreUtil.ignoredFiles(this.project.service<PijulVcsContext>().root, emptyList()).any { it == Paths.get(VcsUtil.getFilePath(virtualFile).path) } - file addition: repository[3.107]
- file addition: PijulRepositoryManager.kt[0.1127]
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijulVcsimport com.intellij.dvcs.repo.AbstractRepositoryManagerimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Project@Serviceclass PijulRepositoryManager(project: Project) : AbstractRepositoryManager<PijulRepository>(pijulVcs(project), ".pijul") {override fun getRepositories(): MutableList<PijulRepository> =this.getRepositories(PijulRepository::class.java)override fun isSyncEnabled(): Boolean =true} - file addition: PijulRepositoryInit.kt[0.1127]
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.github.jonathanxd.dracon.pijul.SuccessStatusCodeimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.VcsRepositoryCreatorimport com.intellij.openapi.Disposableimport com.intellij.openapi.project.Projectimport com.intellij.openapi.project.ProjectManagerimport com.intellij.openapi.vcs.VcsExceptionimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.vcs.VcsRepositoryInitializerimport java.io.Fileclass PijulRepositoryInit : VcsRepositoryInitializer {override fun initRepository(rootDir: File) {val project = ProjectManager.getInstance().defaultProjectval result = pijul(project).init(project, rootDir.toPath())if (result.statusCode !is SuccessStatusCode) {throw VcsException(result.toString())}}override fun getSupportedVcs(): VcsKey =PijulVcs.KEY} - file addition: PijulRepositoryCreator.kt[0.1127]
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.VcsRepositoryCreatorimport com.intellij.openapi.Disposableimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vfs.VirtualFileclass PijulRepositoryCreator : VcsRepositoryCreator {override fun createRepositoryIfValid(project: Project,root: VirtualFile,parentDisposable: Disposable): Repository? =if (Pijul.isUnderPijul(root)) PijulRepository(project, root, parentDisposable) else nulloverride fun getVcsKey(): VcsKey = PijulVcs.KEY} - file addition: PijulRepository.kt[0.1127]
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.ignore.PijulLocalIgnoredFileHolderimport com.github.jonathanxd.dracon.pijul.pijulimport com.github.jonathanxd.dracon.pijulVcsimport com.intellij.dvcs.ignore.VcsIgnoredHolderUpdateListenerimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.RepositoryImplimport com.intellij.openapi.Disposableimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.util.Disposerimport com.intellij.openapi.vcs.AbstractVcsimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.changes.ChangesViewIimport com.intellij.openapi.vcs.changes.ChangesViewManagerimport com.intellij.openapi.vfs.VirtualFileimport org.jetbrains.annotations.NotNullclass PijulRepository(project: @NotNull Project, dir: @NotNull VirtualFile, parentDisposable: @NotNull Disposable) :RepositoryImpl(project, dir, parentDisposable) {private val vcs = pijulVcs(project)private val localIgnoredHolder: PijulLocalIgnoredFileHolder by lazy {PijulLocalIgnoredFileHolder(this, project.service())}init {localIgnoredHolder.setupListeners()Disposer.register(this, localIgnoredHolder)localIgnoredHolder.addUpdateStateListener(MyIgnoredHolderAsyncListener(getProject()))update()}companion object {fun getInstance(root: VirtualFile,project: Project,parentDisposable: Disposable): PijulRepository {val repository = PijulRepository(project, root, parentDisposable)return repository}}override fun getState(): Repository.State = Repository.State.NORMALoverride fun getCurrentBranchName(): String? =pijul(this.project).channel(project, project.baseDir).result?.channels?.firstOrNull { it.current }?.nameoverride fun getVcs(): AbstractVcs =this.vcsoverride fun getCurrentRevision(): String? =pijul(this.project).latestRevisionNumber(project, project.baseDir).result?.hashoverride fun update() {}fun getIgnoredFilesHolder(): VcsRepositoryIgnoredFilesHolder =this.localIgnoredHolderoverride fun toLogString(): String ="PijulRepository ${this.root}"private class MyIgnoredHolderAsyncListener(project: Project) :VcsIgnoredHolderUpdateListener {private val changesViewI: ChangesViewIprivate val project: Projectoverride fun updateStarted() {changesViewI.scheduleRefresh()}override fun updateFinished(ignoredPaths: Collection<FilePath>, isFullRescan: Boolean) {if (project.isDisposed) returnchangesViewI.scheduleRefresh()}init {changesViewI = ChangesViewManager.getInstance(project)this.project = project}}} - file move: credit → credit
- replacement in src/main/kotlin/com/github/jonathanxd/dracon/pijul/PijulOperationResult.kt at line 28
}[3.12980]fun <Y> andThen(other: (R) -> PijulOperationResult<Y>): PijulOperationResult<Y> {return if (this.statusCode !is SuccessStatusCode) {this as PijulOperationResult<Y>} else {other(this.result!!)}}fun <Y> andThenValue(other: (R) -> Y): PijulOperationResult<Y> {return if (this.statusCode !is SuccessStatusCode) {this as PijulOperationResult<Y>} else {PijulOperationResult(operation, statusCode, other(this.result!!))}}}fun <R, Y> PijulOperationResult<List<R>>.mapEvery(f: (R) -> Y): PijulOperationResult<List<Y>> =this.map { it.map(f) } - edit in src/main/kotlin/com/github/jonathanxd/dracon/pijul/Pijul.kt at line 78
@RequiresBackgroundThreadfun init(project: Project, root: Path): PijulOperationResult<Unit> - edit in src/main/kotlin/com/github/jonathanxd/dracon/pijul/Pijul.kt at line 186
fun untrackedFiles(project: Project, root: Path): PijulOperationResult<List<Path>> - file move: lang → lang
- file move: ignore → ignore
- file move: ignore → ignore
- file addition: PijulLocalIgnoredFileHolder.kt[2.24032]
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.repository.PijulRepositoryimport com.github.jonathanxd.dracon.repository.PijulRepositoryManagerimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderBaseimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.ProjectManagerimport com.intellij.openapi.util.registry.Registryimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.LocalFilePathimport com.intellij.openapi.vcs.VcsExceptionimport java.nio.file.Filesimport java.nio.file.Pathsimport java.util.ArrayListimport java.util.HashSetclass PijulLocalIgnoredFileHolder(repository: PijulRepository, repositoryManager: PijulRepositoryManager) :VcsRepositoryIgnoredFilesHolderBase<PijulRepository>(repository, repositoryManager) {@Throws(VcsException::class)override fun requestIgnored(paths: Collection<FilePath>?): Set<FilePath> {val ctx = repository.project.service<PijulVcsContext>()val ignored: MutableSet<FilePath> = HashSet()ignored.addAll(IgnoreUtil.ignoredFiles(ctx.root, paths?.map { Paths.get(it.path) }.orEmpty()).map { LocalFilePath(it, Files.isDirectory(it)) })return ignored}override fun scanTurnedOff(): Boolean {return false}} - file addition: PijulIgnoredFileHolder.kt[2.24032]
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijulVcsimport com.github.jonathanxd.dracon.repository.PijulRepositoryimport com.github.jonathanxd.dracon.repository.PijulRepositoryManagerimport com.intellij.dvcs.ignore.VcsIgnoredFilesHolderBaseimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.AbstractVcsimport com.intellij.openapi.vcs.changes.ChangesViewRefresherimport com.intellij.openapi.vcs.changes.FileHolderimport com.intellij.openapi.vcs.changes.VcsIgnoredFilesHolderclass PijulIgnoredFileHolder(private val project: Project, val manager: PijulRepositoryManager) :VcsIgnoredFilesHolderBase<PijulRepository>(manager) {override fun getHolder(repository: PijulRepository): VcsRepositoryIgnoredFilesHolder {return repository.getIgnoredFilesHolder()}override fun copy(): FileHolder {return PijulIgnoredFileHolder(project, manager) // re-scan roots on refresh}}class PijulIgnoredFileHolderProvider(private val project: Project) : VcsIgnoredFilesHolder.Provider,ChangesViewRefresher {private val vcs = pijulVcs(project)private val manager by lazy {project.service<PijulRepositoryManager>()}override fun getVcs(): AbstractVcs {return vcs}override fun createHolder(): VcsIgnoredFilesHolder {return PijulIgnoredFileHolder(project, manager)}override fun refresh(project: Project) {manager.repositories.forEach { r -> r.getIgnoredFilesHolder().startRescan() }}} - file addition: PijulIgnoredFileContentProvider.kt[2.24032]
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.openapi.diagnostic.loggerimport com.intellij.openapi.project.Projectimport com.intellij.openapi.util.Comparingimport com.intellij.openapi.util.NlsSafeimport com.intellij.openapi.util.io.FileUtilimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.LocalFilePathimport com.intellij.openapi.vcs.VcsExceptionimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vcs.actions.VcsContextFactoryimport com.intellij.openapi.vcs.changes.IgnoreSettingsTypeimport com.intellij.openapi.vcs.changes.IgnoredFileContentProviderimport com.intellij.openapi.vcs.changes.IgnoredFileDescriptorimport com.intellij.openapi.vcs.changes.IgnoredFileProviderimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.vcsUtil.VcsUtilimport java.nio.file.Filesimport java.nio.file.Pathsprivate val LOG = logger<PijulIgnoredFileContentProvider>()class PijulIgnoredFileContentProvider(private val project: Project) : IgnoredFileContentProvider {override fun getSupportedVcs(): VcsKey = PijulVcs.KEYoverride fun getFileName() = ".ignore"override fun buildIgnoreFileContent(ignoreFileRoot: VirtualFile,ignoredFileProviders: Array<IgnoredFileProvider>): String {if (!Pijul.isUnderPijul(ignoreFileRoot)) return ""val repoRoot = VcsUtil.getVcsRootFor(project, ignoreFileRoot)if (repoRoot == null || repoRoot != ignoreFileRoot) return ""val content = StringBuilder()val lineSeparator = System.lineSeparator()val untrackedFiles = getUntrackedFiles(repoRoot, VcsUtil.getFilePath(ignoreFileRoot))if (untrackedFiles.isEmpty()) return ""for (provider in ignoredFileProviders) {val ignoredFiles =provider.getIgnoredFiles(project).ignoreBeansToRelativePaths(ignoreFileRoot, untrackedFiles)if (ignoredFiles.isEmpty()) continueif (content.isNotEmpty()) {content.append(lineSeparator).append(lineSeparator)}val description = provider.ignoredGroupDescriptionif (description.isNotBlank()) {content.append(buildIgnoreGroupDescription(provider))content.append(lineSeparator)}content.append(ignoredFiles.joinToString(lineSeparator))}return content.toString()//if (content.isNotEmpty()) "syntax: glob$lineSeparator$lineSeparator$content" else ""}private fun getUntrackedFiles(root: VirtualFile, ignoreFileRoot: FilePath): Set<FilePath> =try {val rootPath = Paths.get(VcsUtil.getFilePath(root).path)HashSet(pijul(project).untrackedFiles(project, rootPath).result!!.map {LocalFilePath(it, Files.isDirectory(it))}.filter {isAncestor(ignoreFileRoot, it, true)})} catch (e: VcsException) {LOG.warn("Cannot get untracked files: ", e)emptySet()}fun isAncestor(ancestor: FilePath, file: FilePath, strict: Boolean): Boolean {var parent = if (strict) file.parentPath else filewhile (true) {if (parent == null) return falseif (parent == ancestor) return trueparent = parent.parentPath}}private fun Iterable<IgnoredFileDescriptor>.ignoreBeansToRelativePaths(ignoreFileRoot: VirtualFile,untrackedFiles: Set<FilePath>): List<String> {val vcsRoot = VcsUtil.getVcsRootFor(project, ignoreFileRoot)val vcsContextFactory = VcsContextFactory.SERVICE.getInstance()return filter { ignoredBean ->when (ignoredBean.type) {IgnoreSettingsType.UNDER_DIR -> shouldIgnoreUnderDir(ignoredBean,untrackedFiles,ignoreFileRoot,vcsRoot,vcsContextFactory)IgnoreSettingsType.FILE -> shouldIgnoreFile(ignoredBean,untrackedFiles,ignoreFileRoot,vcsRoot,vcsContextFactory)IgnoreSettingsType.MASK -> shouldIgnoreByMask(ignoredBean, untrackedFiles)}}.map { ignoredBean ->when (ignoredBean.type) {IgnoreSettingsType.MASK -> ignoredBean.mask!!IgnoreSettingsType.UNDER_DIR -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean)IgnoreSettingsType.FILE -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean)}}}private fun shouldIgnoreUnderDir(ignoredBean: IgnoredFileDescriptor,untrackedFiles: Set<FilePath>,ignoreFileRoot: VirtualFile,vcsRoot: VirtualFile?,vcsContextFactory: VcsContextFactory) =FileUtil.exists(ignoredBean.path)&& untrackedFiles.any { FileUtil.isAncestor(ignoredBean.path!!, it.path, true) }&& FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false)&& Comparing.equal(vcsRoot,VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, true)))private fun shouldIgnoreFile(ignoredBean: IgnoredFileDescriptor,untrackedFiles: Set<FilePath>,ignoreFileRoot: VirtualFile,vcsRoot: VirtualFile?,vcsContextFactory: VcsContextFactory) =FileUtil.exists(ignoredBean.path)&& untrackedFiles.any { ignoredBean.matchesFile(it) }&& FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false)&& Comparing.equal(vcsRoot,VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, false)))private fun shouldIgnoreByMask(ignoredBean: IgnoredFileDescriptor, untrackedFiles: Set<FilePath>) =untrackedFiles.any { ignoredBean.matchesFile(it) }override fun buildUnignoreContent(ignorePattern: String) = throw UnsupportedOperationException()override fun buildIgnoreGroupDescription(ignoredFileProvider: IgnoredFileProvider) =prependCommentHashCharacterIfNeeded(ignoredFileProvider.ignoredGroupDescription)override fun buildIgnoreEntryContent(ignoreEntryRoot: VirtualFile, ignoredFileDescriptor: IgnoredFileDescriptor) =FileUtil.getRelativePath(ignoreEntryRoot.path, ignoredFileDescriptor.path!!, '/') ?: ""override fun supportIgnoreFileNotInVcsRoot() = falseprivate fun prependCommentHashCharacterIfNeeded(description: @NlsSafe String): @NlsSafe String =if (description.startsWith("#")) description else "# $description"} - file addition: IgnoreUtil.kt[2.24032]
package com.github.jonathanxd.dracon.ignoreimport java.nio.file.FileVisitOptionimport java.nio.file.Filesimport java.nio.file.Pathimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeToimport kotlin.streams.toListobject IgnoreUtil {@OptIn(ExperimentalPathApi::class)fun ignoredFiles(root: Path, paths: List<Path>): List<Path> {val ignore = root.resolve(".ignore")return if (Files.exists(ignore) && Files.isRegularFile(ignore)) {val lines = Files.readAllLines(ignore, Charsets.UTF_8)Files.walk(root, FileVisitOption.FOLLOW_LINKS).filter {paths.isEmpty() || paths.contains(it)}.filter {val relative = it.toAbsolutePath().relativeTo(root).toString()lines.any { line -> relative.startsWith(line) }}.toList()} else {emptyList()}}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 46
import java.nio.file.Filesimport java.nio.file.Pathimport java.nio.file.Pathsimport java.nio.file.StandardOpenOptionimport java.nio.file.* - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 50
import kotlin.streams.toList - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 71
return this.doExecution("init", execution)}@RequiresBackgroundThreadoverride fun init(project: Project, root: Path): PijulOperationResult<Unit> {val execution = this.createExecPijulOperation(project, root, listOf("init", root.toString())) - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 217
override fun untrackedFiles(project: Project, root: Path): PijulOperationResult<List<Path>> {return this.trackedFiles(project, root).andThenValue { tracked ->Files.walk(root, FileVisitOption.FOLLOW_LINKS).filter { !tracked.contains(it) }.toList()}} - file move: annotation → annotation