Comparing directories using DiffManger

Answered

Hello!
I need to compare the content of two directories using DiffManager.getInstance().showDiff().
This simple task is complicated by the fact that the first directory is maintained on a hard disk and the second one is the set of files in memory.
DiffReuqest is one of the parameters of showDiff(). A Document or a VirtualFile can be the wrapped with DiffReuqest, unlike PsiDirectory.
So, this is the source of problem, — a Document can't be the directory, and VirtualFile can't be created without a real reflection in LocalFileSystem.
Is there any way to get this task done and compare set of files with directory like view? Or is the only way to compare this set of files is to use DiffReuqestChain?
Or may it be work around using virtual file systems?
Thank you.

8 comments
Comment actions Permalink

>VirtualFile can't be created without a real reflection in LocalFileSystem.
It can be. See different implementations of VirtualFile in platform code.

>Is there any way to get this task done
There are 2 ways: 
1) To implement non-physical file system, create directory there, use it as any other VirtualFile.
2) Implement directory-diff-specific `com.intellij.ide.diff.DiffElement` and use `com.intellij.diff.tools.dir.DirDiffTool#createViewer` to implement your own `com.intellij.diff.DiffRequest`/`com.intellij.diff.FrameDiffTool` pair.

I suggest using the first one.

You can use `com.intellij.openapi.vfs.ex.dummy.DummyFileSystem` to build in-memory file tree using `DummyFileSystem.createRoot / createChildFile/  createChildDirectory` calls.

You can also build file tree yourself, if dummy system is not flexible enough.
See dummy system as reference implementation. See also `com.intellij.testFramework.LightVirtualFile` , `com.intellij.mock.MockVirtualFileSystem.MyVirtualFile` and `git4idea.log.GitDirectoryVirtualFile` as other solutions for similar problems.

1
Comment actions Permalink

Thank! I tried google virtual File Systems before.

Now solution with DummyFileSystem works for me! 

0
Comment actions Permalink

And one more question: is there any way to setWritable(false) fot VirtualFile created via DummyFileSystem ?

0
Comment actions Permalink

I do not think so.

You can, probably, inherit package-private `com.intellij.openapi.vfs.ex.dummy.VirtualFileDataImpl` and use it in a copy of `createChildFile`.
Or ask us to support `setWritable` in the next IDE version.

But this is, likely, not the last limitation of dummy file system.
So introducing your own might be a better solution (starting with copying this one, for example).

0
Comment actions Permalink

Yes, its work for me. With extending of DummyFileSystem and writing my own implementation of VirtualFiles.

Thank you

0
Comment actions Permalink

Now i have one more question.

Is there any way to observe the applying of changes in DiffManager view?

I tried to use VirtualFileListener, but those events do not fire any of VirtualFileListener methods.

0
Comment actions Permalink

Events should be fired for com.intellij.openapi.editor.event.DocumentListener.
`VirtualFileListener.contentsChanged` should be notified when changes are saved on disk. Ex: on explicit "Save All (Ctrl+S)" action or IDE frame deactivation (if the corresponding option is enabled, which is ON by default).

See `com.intellij.openapi.fileEditor.FileDocumentManager.getDocument / getCachedDocument / getFile`.

https://www.jetbrains.org/intellij/sdk/docs/basics/virtual_file_system.html
https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/virtual_file.html
https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/documents.html

0
Comment actions Permalink

Thanks. Its works.

0

Please sign in to leave a comment.