2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.vcs
.update
;
18 import com
.intellij
.history
.Label
;
19 import com
.intellij
.history
.LocalHistory
;
20 import com
.intellij
.history
.LocalHistoryAction
;
21 import com
.intellij
.ide
.errorTreeView
.HotfixData
;
22 import com
.intellij
.openapi
.actionSystem
.AnActionEvent
;
23 import com
.intellij
.openapi
.actionSystem
.Presentation
;
24 import com
.intellij
.openapi
.application
.ApplicationManager
;
25 import com
.intellij
.openapi
.diagnostic
.Logger
;
26 import com
.intellij
.openapi
.options
.Configurable
;
27 import com
.intellij
.openapi
.progress
.ProcessCanceledException
;
28 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
29 import com
.intellij
.openapi
.progress
.ProgressManager
;
30 import com
.intellij
.openapi
.progress
.Task
;
31 import com
.intellij
.openapi
.project
.Project
;
32 import com
.intellij
.openapi
.project
.ex
.ProjectManagerEx
;
33 import com
.intellij
.openapi
.ui
.MessageType
;
34 import com
.intellij
.openapi
.util
.Ref
;
35 import com
.intellij
.openapi
.vcs
.*;
36 import com
.intellij
.openapi
.vcs
.actions
.AbstractVcsAction
;
37 import com
.intellij
.openapi
.vcs
.actions
.VcsContext
;
38 import com
.intellij
.openapi
.vcs
.changes
.RemoteRevisionsCache
;
39 import com
.intellij
.openapi
.vcs
.changes
.VcsDirtyScopeManager
;
40 import com
.intellij
.openapi
.vcs
.changes
.VcsDirtyScopeManagerImpl
;
41 import com
.intellij
.openapi
.vcs
.changes
.committed
.CommittedChangesAdapter
;
42 import com
.intellij
.openapi
.vcs
.changes
.committed
.CommittedChangesCache
;
43 import com
.intellij
.openapi
.vcs
.changes
.committed
.IntoSelfVirtualFileConvertor
;
44 import com
.intellij
.openapi
.vcs
.changes
.ui
.ChangesViewContentManager
;
45 import com
.intellij
.openapi
.vcs
.ex
.ProjectLevelVcsManagerEx
;
46 import com
.intellij
.openapi
.vcs
.versionBrowser
.CommittedChangeList
;
47 import com
.intellij
.openapi
.vfs
.VfsUtil
;
48 import com
.intellij
.openapi
.vfs
.VirtualFile
;
49 import com
.intellij
.openapi
.vfs
.VirtualFileManager
;
50 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
51 import com
.intellij
.util
.messages
.MessageBusConnection
;
52 import com
.intellij
.util
.ui
.OptionsDialog
;
53 import com
.intellij
.vcsUtil
.VcsUtil
;
54 import org
.jetbrains
.annotations
.NonNls
;
55 import org
.jetbrains
.annotations
.NotNull
;
56 import org
.jetbrains
.annotations
.Nullable
;
61 public abstract class AbstractCommonUpdateAction
extends AbstractVcsAction
{
62 private final static Logger LOG
= Logger
.getInstance("#com.intellij.openapi.vcs.update.AbstractCommonUpdateAction");
64 private final ActionInfo myActionInfo
;
65 private final ScopeInfo myScopeInfo
;
67 protected AbstractCommonUpdateAction(ActionInfo actionInfo
, ScopeInfo scopeInfo
) {
68 myActionInfo
= actionInfo
;
69 myScopeInfo
= scopeInfo
;
72 private String
getCompleteActionName(VcsContext dataContext
) {
73 return myActionInfo
.getActionName(myScopeInfo
.getScopeName(dataContext
, myActionInfo
));
76 protected void actionPerformed(final VcsContext context
) {
77 final Project project
= context
.getProject();
79 boolean showUpdateOptions
= myActionInfo
.showOptions(project
);
81 if (project
!= null) {
83 final FilePath
[] filePaths
= myScopeInfo
.getRoots(context
, myActionInfo
);
84 final FilePath
[] roots
= filterDescindingFiles(filterRoots(filePaths
, context
), project
);
85 if (roots
.length
== 0) {
89 final Map
<AbstractVcs
, Collection
<FilePath
>> vcsToVirtualFiles
= createVcsToFilesMap(roots
, project
);
91 if (showUpdateOptions
|| OptionsDialog
.shiftIsPressed(context
.getModifiers())) {
92 showOptionsDialog(vcsToVirtualFiles
, project
, context
);
95 for (AbstractVcs vcs
: vcsToVirtualFiles
.keySet()) {
96 final UpdateEnvironment updateEnvironment
= myActionInfo
.getEnvironment(vcs
);
97 if ((updateEnvironment
!= null) && (! updateEnvironment
.validateOptions(vcsToVirtualFiles
.get(vcs
)))) {
98 // messages already shown
103 if (ApplicationManager
.getApplication().isDispatchThread()) {
104 ApplicationManager
.getApplication().saveAll();
106 Task
.Backgroundable task
= new Updater(project
, roots
, vcsToVirtualFiles
);
107 ProgressManager
.getInstance().run(task
);
109 catch (ProcessCanceledException e1
) {
115 private boolean canGroupByChangelist(final Set
<AbstractVcs
> abstractVcses
) {
116 if (myActionInfo
.canGroupByChangelist()) {
117 for(AbstractVcs vcs
: abstractVcses
) {
118 if (vcs
.getCachingCommittedChangesProvider() != null) {
126 private static boolean someSessionWasCanceled(List
<UpdateSession
> updateSessions
) {
127 for (UpdateSession updateSession
: updateSessions
) {
128 if (updateSession
.isCanceled()) {
135 private static String
getAllFilesAreUpToDateMessage(FilePath
[] roots
) {
136 if (roots
.length
== 1 && !roots
[0].isDirectory()) {
137 return VcsBundle
.message("message.text.file.is.up.to.date");
140 return VcsBundle
.message("message.text.all.files.are.up.to.date");
144 private void showOptionsDialog(final Map
<AbstractVcs
, Collection
<FilePath
>> updateEnvToVirtualFiles
, final Project project
,
145 final VcsContext dataContext
) {
146 LinkedHashMap
<Configurable
, AbstractVcs
> envToConfMap
= createConfigurableToEnvMap(updateEnvToVirtualFiles
);
147 if (!envToConfMap
.isEmpty()) {
148 UpdateOrStatusOptionsDialog dialogOrStatus
= myActionInfo
.createOptionsDialog(project
, envToConfMap
,
149 myScopeInfo
.getScopeName(dataContext
,
151 dialogOrStatus
.show();
152 if (!dialogOrStatus
.isOK()) {
153 throw new ProcessCanceledException();
158 private LinkedHashMap
<Configurable
, AbstractVcs
> createConfigurableToEnvMap(Map
<AbstractVcs
, Collection
<FilePath
>> updateEnvToVirtualFiles
) {
159 LinkedHashMap
<Configurable
, AbstractVcs
> envToConfMap
= new LinkedHashMap
<Configurable
, AbstractVcs
>();
160 for (AbstractVcs vcs
: updateEnvToVirtualFiles
.keySet()) {
161 Configurable configurable
= myActionInfo
.getEnvironment(vcs
).createConfigurable(updateEnvToVirtualFiles
.get(vcs
));
162 if (configurable
!= null) {
163 envToConfMap
.put(configurable
, vcs
);
169 private Map
<AbstractVcs
,Collection
<FilePath
>> createVcsToFilesMap(FilePath
[] roots
, Project project
) {
170 HashMap
<AbstractVcs
, Collection
<FilePath
>> resultPrep
= new HashMap
<AbstractVcs
, Collection
<FilePath
>>();
172 for (FilePath file
: roots
) {
173 AbstractVcs vcs
= VcsUtil
.getVcsFor(project
, file
);
175 UpdateEnvironment updateEnvironment
= myActionInfo
.getEnvironment(vcs
);
176 if (updateEnvironment
!= null) {
177 if (!resultPrep
.containsKey(vcs
)) resultPrep
.put(vcs
, new HashSet
<FilePath
>());
178 resultPrep
.get(vcs
).add(file
);
183 final Map
<AbstractVcs
, Collection
<FilePath
>> result
= new HashMap
<AbstractVcs
, Collection
<FilePath
>>();
184 for (Map
.Entry
<AbstractVcs
, Collection
<FilePath
>> entry
: resultPrep
.entrySet()) {
185 final AbstractVcs vcs
= entry
.getKey();
186 final List
<FilePath
> paths
= new ArrayList
<FilePath
>(entry
.getValue());
187 final List
<VirtualFile
> files
= ObjectsConvertor
.convert(paths
, ObjectsConvertor
.FILEPATH_TO_VIRTUAL
, ObjectsConvertor
.NOT_NULL
);
188 result
.put(vcs
, ObjectsConvertor
.vf2fp(vcs
.filterUniqueRoots(files
, IntoSelfVirtualFileConvertor
.getInstance())));
194 private static boolean containsParent(FilePath
[] array
, FilePath file
) {
195 for (FilePath virtualFile
: array
) {
196 if (virtualFile
== file
) continue;
197 if (VfsUtil
.isAncestor(virtualFile
.getIOFile(), file
.getIOFile(), false)) return true;
203 private FilePath
[] filterRoots(FilePath
[] roots
, VcsContext vcsContext
) {
204 final ArrayList
<FilePath
> result
= new ArrayList
<FilePath
>();
205 final Project project
= vcsContext
.getProject();
206 for (FilePath file
: roots
) {
207 AbstractVcs vcs
= VcsUtil
.getVcsFor(project
, file
);
209 if (!myScopeInfo
.filterExistsInVcs() || AbstractVcs
.fileInVcsByFileStatus(project
, file
)) {
210 UpdateEnvironment updateEnvironment
= myActionInfo
.getEnvironment(vcs
);
211 if (updateEnvironment
!= null) {
216 final VirtualFile virtualFile
= file
.getVirtualFile();
217 if (virtualFile
!= null && virtualFile
.isDirectory()) {
218 final VirtualFile
[] vcsRoots
= ProjectLevelVcsManager
.getInstance(vcsContext
.getProject()).getAllVersionedRoots();
219 for(VirtualFile vcsRoot
: vcsRoots
) {
220 if (VfsUtil
.isAncestor(virtualFile
, vcsRoot
, false)) {
228 return result
.toArray(new FilePath
[result
.size()]);
231 protected abstract boolean filterRootsBeforeAction();
233 protected void update(VcsContext vcsContext
, Presentation presentation
) {
234 Project project
= vcsContext
.getProject();
236 if (project
!= null) {
238 String actionName
= getCompleteActionName(vcsContext
);
239 if (myActionInfo
.showOptions(project
) || OptionsDialog
.shiftIsPressed(vcsContext
.getModifiers())) {
243 presentation
.setText(actionName
);
245 presentation
.setVisible(true);
246 presentation
.setEnabled(true);
248 if (supportingVcsesAreEmpty(vcsContext
.getProject(), myActionInfo
)) {
249 presentation
.setVisible(false);
250 presentation
.setEnabled(false);
253 if (filterRootsBeforeAction()) {
254 FilePath
[] roots
= filterRoots(myScopeInfo
.getRoots(vcsContext
, myActionInfo
), vcsContext
);
255 if (roots
.length
== 0) {
256 presentation
.setVisible(false);
257 presentation
.setEnabled(false);
261 if (presentation
.isVisible() && presentation
.isEnabled() &&
262 ProjectLevelVcsManager
.getInstance(project
).isBackgroundVcsOperationRunning()) {
263 presentation
.setEnabled(false);
266 presentation
.setVisible(false);
267 presentation
.setEnabled(false);
271 protected boolean forceSyncUpdate(final AnActionEvent e
) {
275 private static boolean supportingVcsesAreEmpty(final Project project
, final ActionInfo actionInfo
) {
276 if (project
== null) return true;
277 final AbstractVcs
[] allActiveVcss
= ProjectLevelVcsManager
.getInstance(project
).getAllActiveVcss();
278 for (AbstractVcs activeVcs
: allActiveVcss
) {
279 if (actionInfo
.getEnvironment(activeVcs
) != null) return false;
284 private class Updater
extends Task
.Backgroundable
{
285 private final Project myProject
;
286 private final ProjectLevelVcsManagerEx myProjectLevelVcsManager
;
287 private UpdatedFiles myUpdatedFiles
;
288 private final FilePath
[] myRoots
;
289 private final Map
<AbstractVcs
, Collection
<FilePath
>> myVcsToVirtualFiles
;
290 private final Map
<HotfixData
, List
<VcsException
>> myGroupedExceptions
;
291 private final List
<UpdateSession
> myUpdateSessions
;
292 private int myUpdateNumber
;
294 // vcs name, context object
295 private final Map
<AbstractVcs
, SequentialUpdatesContext
> myContextInfo
;
296 private VcsDirtyScopeManager myDirtyScopeManager
;
298 private Label myBefore
;
299 private Label myAfter
;
301 public Updater(final Project project
, final FilePath
[] roots
, final Map
<AbstractVcs
, Collection
<FilePath
>> vcsToVirtualFiles
) {
302 super(project
, getTemplatePresentation().getText(), true, VcsConfiguration
.getInstance(project
).getUpdateOption());
304 myProjectLevelVcsManager
= ProjectLevelVcsManagerEx
.getInstanceEx(project
);
305 myDirtyScopeManager
= VcsDirtyScopeManager
.getInstance(myProject
);
307 myVcsToVirtualFiles
= vcsToVirtualFiles
;
309 myUpdatedFiles
= UpdatedFiles
.create();
310 myGroupedExceptions
= new HashMap
<HotfixData
, List
<VcsException
>>();
311 myUpdateSessions
= new ArrayList
<UpdateSession
>();
313 // create from outside without any context; context is created by vcses
314 myContextInfo
= new HashMap
<AbstractVcs
, SequentialUpdatesContext
>();
318 private void reset() {
319 myUpdatedFiles
= UpdatedFiles
.create();
320 myGroupedExceptions
.clear();
321 myUpdateSessions
.clear();
325 private void suspendIfNeeded() {
326 if (! myActionInfo
.canChangeFileStatus()) {
327 // i.e. for update but not for integrate or status
328 ((VcsDirtyScopeManagerImpl
) myDirtyScopeManager
).suspendMe();
332 private void releaseIfNeeded() {
333 if (! myActionInfo
.canChangeFileStatus()) {
334 // i.e. for update but not for integrate or status
335 ((VcsDirtyScopeManagerImpl
) myDirtyScopeManager
).reanimate();
339 public void run(@NotNull final ProgressIndicator indicator
) {
343 } catch (Throwable t
) {
345 if (t
instanceof Error
) {
347 } else if (t
instanceof RuntimeException
) {
348 throw ((RuntimeException
) t
);
350 throw new RuntimeException(t
);
354 private void runImpl(@NotNull final ProgressIndicator indicator
) {
355 ProjectManagerEx
.getInstanceEx().blockReloadingProjectOnExternalChanges();
356 myProjectLevelVcsManager
.startBackgroundVcsOperation();
358 myBefore
= LocalHistory
.putSystemLabel(myProject
, "Before update");
360 ProgressIndicator progressIndicator
= ProgressManager
.getInstance().getProgressIndicator();
363 int toBeProcessed
= myVcsToVirtualFiles
.size();
365 for (AbstractVcs vcs
: myVcsToVirtualFiles
.keySet()) {
366 final UpdateEnvironment updateEnvironment
= myActionInfo
.getEnvironment(vcs
);
367 updateEnvironment
.fillGroups(myUpdatedFiles
);
368 Collection
<FilePath
> files
= myVcsToVirtualFiles
.get(vcs
);
370 final SequentialUpdatesContext context
= myContextInfo
.get(vcs
);
371 final Ref
<SequentialUpdatesContext
> refContext
= new Ref
<SequentialUpdatesContext
>(context
);
372 UpdateSession updateSession
=
373 updateEnvironment
.updateDirectories(files
.toArray(new FilePath
[files
.size()]), myUpdatedFiles
, progressIndicator
, refContext
);
374 myContextInfo
.put(vcs
, refContext
.get());
376 if (progressIndicator
!= null) {
377 progressIndicator
.setFraction((double)processed
/ (double)toBeProcessed
);
378 progressIndicator
.setText2("");
380 final List
<VcsException
> exceptionList
= updateSession
.getExceptions();
381 gatherExceptions(vcs
, exceptionList
);
382 myUpdateSessions
.add(updateSession
);
386 if (progressIndicator
!= null) {
387 progressIndicator
.setText(VcsBundle
.message("progress.text.synchronizing.files"));
388 progressIndicator
.setText2("");
392 myAfter
= LocalHistory
.putSystemLabel(myProject
, "After update");
393 myProjectLevelVcsManager
.stopBackgroundVcsOperation();
398 private void gatherExceptions(final AbstractVcs vcs
, final List
<VcsException
> exceptionList
) {
399 final VcsExceptionsHotFixer fixer
= vcs
.getVcsExceptionsHotFixer();
401 putExceptions(null, exceptionList
);
403 putExceptions(fixer
.groupExceptions(ActionType
.update
, exceptionList
));
407 private void putExceptions(final Map
<HotfixData
, List
<VcsException
>> map
) {
408 for (Map
.Entry
<HotfixData
, List
<VcsException
>> entry
: map
.entrySet()) {
409 putExceptions(entry
.getKey(), entry
.getValue());
413 private void putExceptions(final HotfixData key
, @NotNull final List
<VcsException
> list
) {
414 if (list
.isEmpty()) return;
415 List
<VcsException
> exceptionList
= myGroupedExceptions
.get(key
);
416 if (exceptionList
== null) {
417 exceptionList
= new ArrayList
<VcsException
>();
418 myGroupedExceptions
.put(key
, exceptionList
);
420 exceptionList
.addAll(list
);
423 private void doVfsRefresh() {
424 final String actionName
= VcsBundle
.message("local.history.update.from.vcs");
425 final LocalHistoryAction action
= LocalHistory
.startAction(myProject
, actionName
);
427 LOG
.info("Calling refresh files after update for roots: " + Arrays
.toString(myRoots
));
428 RefreshVFsSynchronously
.updateAllChanged(myUpdatedFiles
);
432 LocalHistory
.putSystemLabel(myProject
, actionName
);
437 public NotificationInfo
getNotificationInfo() {
438 StringBuffer text
= new StringBuffer();
439 final List
<FileGroup
> groups
= myUpdatedFiles
.getTopLevelGroups();
440 for (FileGroup group
: groups
) {
441 appendGroup(text
, group
);
444 return new NotificationInfo("VCS Update", "VCS Update Finished", text
.toString(), true);
447 private void appendGroup(final StringBuffer text
, final FileGroup group
) {
448 final int s
= group
.getFiles().size();
450 if (text
.length() > 0) text
.append("\n");
451 text
.append(s
+ " Files " + group
.getUpdateName());
454 final List
<FileGroup
> list
= group
.getChildren();
455 for (FileGroup g
: list
) {
456 appendGroup(text
, g
);
460 public void onSuccess() {
468 private void onSuccessImpl() {
469 if (myProject
.isDisposed()) {
470 ProjectManagerEx
.getInstanceEx().unblockReloadingProjectOnExternalChanges();
473 boolean continueChain
= false;
474 for (SequentialUpdatesContext context
: myContextInfo
.values()) {
475 continueChain
|= (context
!= null) && (context
.shouldFail());
477 final boolean continueChainFinal
= continueChain
;
479 final boolean someSessionWasCancelled
= someSessionWasCanceled(myUpdateSessions
);
480 if (! someSessionWasCancelled
) {
481 for (final UpdateSession updateSession
: myUpdateSessions
) {
482 updateSession
.onRefreshFilesCompleted();
486 if (myActionInfo
.canChangeFileStatus()) {
487 final List
<VirtualFile
> files
= new ArrayList
<VirtualFile
>();
488 final RemoteRevisionsCache revisionsCache
= RemoteRevisionsCache
.getInstance(myProject
);
489 revisionsCache
.invalidate(myUpdatedFiles
);
490 UpdateFilesHelper
.iterateFileGroupFiles(myUpdatedFiles
, new UpdateFilesHelper
.Callback() {
491 public void onFile(final String filePath
, final String groupId
) {
492 @NonNls final String path
= VfsUtil
.pathToUrl(filePath
.replace(File
.separatorChar
, '/'));
493 final VirtualFile file
= VirtualFileManager
.getInstance().findFileByUrl(path
);
499 myDirtyScopeManager
.filesDirty(files
, null);
502 final boolean updateSuccess
= (! someSessionWasCancelled
) && (myGroupedExceptions
.isEmpty());
504 if (! someSessionWasCancelled
) {
505 ApplicationManager
.getApplication().invokeLater(new Runnable() {
507 if (myProject
.isDisposed()) {
508 ProjectManagerEx
.getInstanceEx().unblockReloadingProjectOnExternalChanges();
511 if (! myGroupedExceptions
.isEmpty()) {
512 if (continueChainFinal
) {
513 gatherContextInterruptedMessages();
515 AbstractVcsHelper
.getInstance(myProject
).showErrors(myGroupedExceptions
, VcsBundle
.message("message.title.vcs.update.errors",
516 getTemplatePresentation().getText()));
519 final ProgressIndicator indicator
= ProgressManager
.getInstance().getProgressIndicator();
520 if (indicator
!= null) {
521 indicator
.setText(VcsBundle
.message("progress.text.updating.done"));
525 final boolean noMerged
= myUpdatedFiles
.getGroupById(FileGroup
.MERGED_WITH_CONFLICT_ID
).isEmpty();
526 if (myUpdatedFiles
.isEmpty() && myGroupedExceptions
.isEmpty()) {
527 ToolWindowManager
.getInstance(myProject
).notifyByBalloon(
528 ChangesViewContentManager
.TOOLWINDOW_ID
, MessageType
.INFO
, getAllFilesAreUpToDateMessage(myRoots
));
530 else if (! myUpdatedFiles
.isEmpty()) {
531 showUpdateTree(continueChainFinal
&& updateSuccess
&& noMerged
);
533 final CommittedChangesCache cache
= CommittedChangesCache
.getInstance(myProject
);
534 cache
.processUpdatedFiles(myUpdatedFiles
);
537 ProjectManagerEx
.getInstanceEx().unblockReloadingProjectOnExternalChanges();
539 if (continueChainFinal
&& updateSuccess
) {
541 showContextInterruptedError();
543 // trigger next update; for CVS when updating from several branvhes simultaneously
545 ProgressManager
.getInstance().run(Updater
.this);
550 } else if (continueChain
) {
552 showContextInterruptedError();
553 ProjectManagerEx
.getInstanceEx().unblockReloadingProjectOnExternalChanges();
557 private void showContextInterruptedError() {
558 gatherContextInterruptedMessages();
559 AbstractVcsHelper
.getInstance(myProject
).showErrors(myGroupedExceptions
,
560 VcsBundle
.message("message.title.vcs.update.errors", getTemplatePresentation().getText()));
563 private void gatherContextInterruptedMessages() {
564 for (Map
.Entry
<AbstractVcs
, SequentialUpdatesContext
> entry
: myContextInfo
.entrySet()) {
565 final SequentialUpdatesContext context
= entry
.getValue();
566 if ((context
== null) || (! context
.shouldFail())) continue;
567 final VcsException exception
= new VcsException(context
.getMessageWhenInterruptedBeforeStart());
568 gatherExceptions(entry
.getKey(), Collections
.singletonList(exception
));
572 private void showUpdateTree(final boolean willBeContinued
) {
573 RestoreUpdateTree restoreUpdateTree
= RestoreUpdateTree
.getInstance(myProject
);
574 restoreUpdateTree
.registerUpdateInformation(myUpdatedFiles
, myActionInfo
);
575 final String text
= getTemplatePresentation().getText() + ((willBeContinued
|| (myUpdateNumber
> 1)) ?
("#" + myUpdateNumber
) : "");
576 final UpdateInfoTree updateInfoTree
= myProjectLevelVcsManager
.showUpdateProjectInfo(myUpdatedFiles
, text
, myActionInfo
);
578 updateInfoTree
.setBefore(myBefore
);
579 updateInfoTree
.setAfter(myAfter
);
581 // todo make temporal listener of changes reload
582 if (updateInfoTree
!= null) {
583 updateInfoTree
.setCanGroupByChangeList(canGroupByChangelist(myVcsToVirtualFiles
.keySet()));
584 final MessageBusConnection messageBusConnection
= myProject
.getMessageBus().connect();
585 messageBusConnection
.subscribe(CommittedChangesCache
.COMMITTED_TOPIC
, new CommittedChangesAdapter() {
586 public void incomingChangesUpdated(final List
<CommittedChangeList
> receivedChanges
) {
587 if (receivedChanges
!= null) {
588 updateInfoTree
.setChangeLists(receivedChanges
);
589 messageBusConnection
.disconnect();
596 public void onCancel() {