New Behavior for VCS Root related messages, How do I know when all VCS roots for the project have initialized?

Answered

New behaviour in intellij-community master branch. Beta still has the old behaviour for project initialization VCS messaging.

In my plugin I subscribe to ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED and ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED_IN_PLUGIN in projectOpened() of a project component.

Either one would cause getting updated VCS Roots for Git in the project. I also treat this message as signalling that project VCS roots have been updated..

Lately I noticed that plugin features relying on VCS roots are failing and traced it to the plugin not seeing any VCS Roots. Going deeper located that trying to get VCS roots on these notifications after project opening is useless because GitRepositoryManager.getRepositories() has no roots when the message is fired when the project is opened.

After project open, GitRepository.GIT_REPO_CHANGE messages are fired for each repository as it is initialized.

How do I know when ALL project VCS roots are initialized and I can start processing which relies on all project VCS roots to be known?

 

0
4 comments

Answer for posterity: register post startup activity with StartupManager. It is fired when all roots are loaded and indexing is complete.

0

Note, that vcs roots can be changed at any point.

If you're interested in GitRepositoryManager.getRepositories() updates, you can listen for `com.intellij.dvcs.repo.VcsRepositoryManager#VCS_REPOSITORY_MAPPING_UPDATED` topic.

>How do I know when ALL project VCS roots are initialized and I can start processing which relies on all project VCS roots to be known?
You can use `ProjectLevelVcsManagerImpl#addInitializationRequest` with `VcsInitObject.AFTER_COMMON` to be notified when vcs initialization activities are finished. But VcsRepositoryManager still might not be refreshed yet.
At this point you can get mapped roots using `ProjectLevelVcsManager#getRootsUnderVcs(GitVcs.getInstance(project))` and force their initialization with `GitRepositoryManager#getRepositoryForRoot`.

StartupManager will not guarantee, that everything is loaded.

0

Thanks Aleksey. I subscribe to the repository mapping update but previous versions used to fire this message AFTER VCS roots were updated. Last few SNAPSHOT builds fire it before.

Not an issue anymore. I fixed my code to register post startup activity which loads the VCS roots for my plugin and does its initialization at this point. I should have done it this way in the first place but alas, I wrote this code when I knew nothing of the IDE, its complex initialization and robust API. A lot of it was trial and error as I learned. 

Cleaning up this code consisted of deleting various state checks and moving execution to the post startup activity handler. Once I identified the issue, the fix was a five minute job.

All the recent IDE code cleanup and optimization is causing changes in behaviour, forcing me to cleanup old code which I have not looked at in years, literally.

Unfortunately for me, I am in the middle of a big code rip up and clean up myself, so when new behaviour causes failures, I cannot be sure if I introduced it in my cleanup or the IDE in its cleanup.

Makes figuring out what went wrong more difficult, which is my problem, not yours.

0

Aleksey, I tried your suggestion of registering `ProjectLevelVcsManagerImpl#addInitializationRequest` with `VcsInitObject.AFTER_COMMON` but when it fires GitRepositoryManager.getRepositories() has no repositories. On the other hand if I register StartupManager post startup activity, when it fires the git repositories are available.

I don't know if the former is a bug or a feature but it seems that post startup activity is the right place to get all VCS roots for the project, at least for git.

0

Please sign in to leave a comment.