IncomingChanges

I had understood from a former reply from Dmitry that to be able to feed information into the incoming changes section of the UI , one had to implement (and have it returned by the VCS implementation) the CommittedChangesProvider interface.

I've created an implementation of it, and set breakpoints in all methods, but when debugging the VCS plugin and requesting incoming changes no breakpoints are triggered.

IDEA shows one changelist though, where every file of the project is present with apparently the status "added". I have no idea where this one comes from. It has my Windows user as author, and this is not a valid user on any of the vcses I use.
The reported date may well be the project creation date, not sure of it and it has not comment.

Pressing the refresh button doesn't trigger my CommittedChangesProvider implementation to be called

21 comments

Hello Thibaut,

I had understood from a former reply from Dmitry that to be able to
feed information into the incoming changes section of the UI , one
had to implement (and have it returned by the VCS implementation) the
CommittedChangesProvider interface.


You'll need to implement CachingCommittedChangesProvider, which is derived
from CommittedChangesProvider.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

I'm currently trying to implement this ... but I don't find it as easy/immediate as the other part of the VCS API.

Here is an exception I get and I don't understand why
It happens right after the writeChangeList method is called on the CommittedChangesProvider

java.lang.NullPointerException
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile.a(ChangesCacheFile.java:291)
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile.writeChanges(ChangesCacheFile.java:352)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache$4.compute(CommittedChangesCache.java:5)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache$4.compute(CommittedChangesCache.java:4)
at com.intellij.openapi.application.impl.ApplicationImpl$12.run(ApplicationImpl.java:3)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:210)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:136)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache.a(CommittedChangesCache.java:53)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache.a(CommittedChangesCache.java:217)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache.access$1100(CommittedChangesCache.java:260)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache$10.run(CommittedChangesCache.java:9)
at com.intellij.openapi.progress.BackgroundTaskQueue$1.run(BackgroundTaskQueue.java:49)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$5.run(ProgressManagerImpl.java:1)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:10)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:25)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:36)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$6.run(ProgressManagerImpl.java:5)
at com.intellij.openapi.application.impl.ApplicationImpl$5.run(ApplicationImpl.java:9)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
at java.util.concurrent.FutureTask.run(FutureTask.java:123)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:3)


Current implementation of org.intellij.vcs.mks.incoming.MksCommittedChangesProvider#writeChangeList method just writes the number of changes (and readChangeList is symmetric).

0

This was probably due to the fact that my CommittedChangeList implementation was returning null for its vcs ...

I seem to have the same problem with the CommittedChangeList#getCommitDate method
which caused exceptions while IDEA was sorting the lists.

I guess those methods should be annotated as @NotNull

0

I'm still working on this.

My current concern is that IDEA mandates that change lists have a commit date : this is not supported in all vcs I guess, currently I'm using the most recent change in a change list ( the change list is not committed atomically).

For some cases though, I don't know the date of the change, especially for drop operations (this would need a vcs operation per file , which I believe would be too expensive).

It may be that I'm not using the incoming changes the right way : I don't expect it to show a project history, but rather to show which files have been updated in the repository (and thus what needs updating/merging)

Any advice ?

0

Hello Thibaut,

My current concern is that IDEA mandates that change lists have a
commit date : this is not supported in all vcs I guess, currently I'm
using the most recent change in a change list ( the change list is not
committed atomically).

For some cases though, I don't know the date of the change, especially
for drop operations (this would need a vcs operation per file , which
I believe would be too expensive).

It may be that I'm not using the incoming changes the right way : I
don't expect it to show a project history, but rather to show which
files have been updated in the repository (and thus what needs
updating/merging)

Any advice ?


Maybe you just need to implement the "Check Project Status" action though
AbstractVcs.getStatusEnvironment()?

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

When is this called and what does IDEA does with the result ?

Will this allow the user to view which resources will be updated BEFORE the update takes place ?

0

Hello Thibaut,

When is this called and what does IDEA does with the result ?


This is called by an explicit project action (Check Project Status), and
the results are displayed in a toolwindow.

Will this allow the user to view which resources will be updated
BEFORE the update takes place ?


Yes, but this will not show the yellow "outdated version" bars.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Dmitry, from what I read in the Svn plugin, the com.intellij.openapi.vcs.update.UpdateEnvironment#fillGroups method is responsible for scanning all files that needs to be updated.

It seems to distinguish files depending on what action is needed (merge, drop, ....).

There's something I miss though : you can invoke this action via right clicking on a directory or file, but the content of the selection is not supplied to fillGroups : is the Vcs expected to check status for all the current project content roots ?

0

Hello Thibaut,

Dmitry, from what I read in the Svn plugin, the
com.intellij.openapi.vcs.update.UpdateEnvironment#fillGroups method is
responsible for scanning all files that needs to be updated.

It seems to distinguish files depending on what action is needed
(merge, drop, ....).

There's something I miss though : you can invoke this action via right
clicking on a directory or file, but the content of the selection is
not supplied to fillGroups : is the Vcs expected to check status for
all the current project content roots ?


No, the fillGroups() method is called after the files have been retrieved.
The actual status checking is done in updateDirectories().

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

According to svn plugin, i want to believe you, but the strange thing is that IDEA calls the following methods in the given order when triggering the action

MksVcs.getStatusEnvironment
MksUpdateEnvironment.fillGroups 1193125281202
MksUpdateEnvironment.updateDirectories 1193125281202
MksUpdateEnvironment.getExceptions 1193125281742
MksUpdateEnvironment.isCanceled 1193125282824
MksUpdateEnvironment.onRefreshFilesCompleted 1193125282824
MksUpdateEnvironment.isCanceled 1193125282824


(numbers are currentTimeMillis())


ANd if I set a breakpoint in both updateDirectories and fillgroups, fillgroups is called first

0

Hello Thibaut,

According to svn plugin, i want to believe you, but the strange thing
is that IDEA calls the following methods in the given order when
triggering the action

MksVcs.getStatusEnvironment
MksUpdateEnvironment.fillGroups 1193125281202
MksUpdateEnvironment.updateDirectories 1193125281202
MksUpdateEnvironment.getExceptions 1193125281742
MksUpdateEnvironment.isCanceled 1193125282824
MksUpdateEnvironment.onRefreshFilesCompleted 1193125282824
MksUpdateEnvironment.isCanceled 1193125282824
(numbers are currentTimeMillis())

ANd if I set a breakpoint in both updateDirectories and fillgroups,
fillgroups is called first


Sorry, I wasn't quite correct. fillGroups() is used to register additional
file status groups that your VCS supports, in addition to the standard groups
created in UpdatedFiles.create(). It doesn't perform any scanning.

I'll add javadoc for this API.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

so this would explain why the elements i add to
- updatedFiles.getGroupById(FileGroup.CREATED_ID)
- updatedFiles.getGroupById(FileGroup.REMOVED_FROM_REPOSITORY_ID)

are not displayed in the result status window ?
The only ones i'm seeing are the ones in
- updatedFiles.getGroupById(FileGroup.CHANGED_ON_SERVER_ID)

Not sure if it makes sense, but when executing
for (FileGroup fileGroup : updatedFiles.getTopLevelGroups()) {
System.out.println(fileGroup);
}
I only see CHANGED_ON_SERVER 35 items
MODIFIED 0 items
SKIPPED 0 items
MERGED_WITH_CONFLICTS 0 items
MERGED 0 items
UNKNOWN 0 items
LOCALLY_ADDED 0 items
LOCALLY_REMOVED 0 items


and if executing afterwards
System.out.println(updatedFiles.getGroupById(FileGroup.REMOVED_FROM_REPOSITORY_ID));
System.out.println(updatedFiles.getGroupById(FileGroup.CREATED_ID));

I see the files I've added in those groups
REMOVED_FROM_REPOSITORY 1 items
CREATED 58 items

0

BTW this thread is probably eligible for inclusion in http://www.jetbrains.net/confluence/display/IDEADEV/PluginDevelopmentFAQ :)

0

Dmitry, any idea what I should be doing to have added/deleted from repo files reported in the result window ?

0

Hello Thibaut,

so this would explain why the elements i add to
- updatedFiles.getGroupById(FileGroup.CREATED_ID)
- updatedFiles.getGroupById(FileGroup.REMOVED_FROM_REPOSITORY_ID)
are not displayed in the result status window ?
The only ones i'm seeing are the ones in
- updatedFiles.getGroupById(FileGroup.CHANGED_ON_SERVER_ID)


You shouldn't put any files in CHANGED_ON_SERVER group, as it's a container
for other groups. Files modified on server should be placed in the UPDATED
group.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Thanks , this indeed works !

0

Is it expected, that after the CommittedChangesProvider returns the list of changelists with their changes, the Vcs DiffProvider seems to be invoked for every change ?

edit: if this may help here is the stack of the call
java.lang.Exception
at org.intellij.vcs.mks.sicommands.GetRevisionInfo.]]>(GetRevisionInfo.java:25)
at org.intellij.vcs.mks.MksDiffProvider.getRevisionInfo(MksDiffProvider.java:39)
at org.intellij.vcs.mks.MksDiffProvider.getCurrentRevision(MksDiffProvider.java:29)
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile$2.create(ChangesCacheFile.java:1)
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile$2.create(ChangesCacheFile.java:2)
at com.intellij.util.containers.FactoryMap.get(FactoryMap.java:43)
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile.a(ChangesCacheFile.java:428)
at com.intellij.openapi.vcs.changes.committed.ChangesCacheFile.refreshIncomingChanges(ChangesCacheFile.java:222)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache.refreshIncomingChanges(CommittedChangesCache.java:116)
at com.intellij.openapi.vcs.changes.committed.CommittedChangesCache$8.run(CommittedChangesCache.java:6)
at com.intellij.openapi.progress.BackgroundTaskQueue$1.run(BackgroundTaskQueue.java:49)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$5.run(ProgressManagerImpl.java:1)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:10)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:25)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:36)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$6.run(ProgressManagerImpl.java:5)
at com.intellij.openapi.application.impl.ApplicationImpl$5.run(ApplicationImpl.java:9)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
at java.util.concurrent.FutureTask.run(FutureTask.java:123)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:3)

Message was edited by:
Thibaut

0

Hello Thibaut,

Is it expected, that after the CommittedChangesProvider returns the
list of changelists with their changes, the Vcs DiffProvider seems to
be invoked for every change ?


Yes. The version of the file that you have locally is retrieved through DiffProvider
and then compared to the version in CommittedChangeList to see if you already
have this change locally.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

In this case, there's something I don't understand : when the CommittedChangesProvider creates the changes in the Changelist, what is the base revision that should be used to create those Changes ?

The way I've implemented it is I create changes where the fromRevision is the local revision, and the toRevision is the repository one.

Here is a code extract
state is my internal state holder


Message was edited by:
Thibaut

0

Hello Thibaut,

In this case, there's something I don't understand : when the
CommittedChangesProvider creates the changes in the Changelist, what
is the base revision that should be used to create those Changes ?

The way I've implemented it is I create changes where the fromRevision
is the local revision, and the toRevision is the repository one.


This is not correct. For every file change committed in the requested range,
a Change must be returned which has the N-1 revision as the beforeRevision
and the N revision as the afterRevision. Local revisions do not come into
play at all.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Please sign in to leave a comment.