public boolean move(VirtualFile file, VirtualFile toDir) throws IOException { File srcFile = getIOFile(file); File dstFile = new File(getIOFile(toDir), file.getName()); final SvnVcs vcs = getVCS(toDir); final SvnVcs sourceVcs = getVCS(file); if (vcs == null && sourceVcs == null) return false; if (vcs == null) { return false; } FileDocumentManager.getInstance().saveAllDocuments(); if (sourceVcs == null) { return createItem(toDir, file.getName(), file.isDirectory(), true); } if (isPendingAdd(vcs.getProject(), toDir)) { myMovedFiles.add(new MovedFileInfo(sourceVcs.getProject(), srcFile, dstFile)); return true; } else { final VirtualFile oldParent = file.getParent(); myFilesToRefresh.add(oldParent); myFilesToRefresh.add(toDir); return doMove(sourceVcs, srcFile, dstFile); } }
private static boolean isUndo(SvnVcs vcs) { if (vcs == null || vcs.getProject() == null) { return false; } Project p = vcs.getProject(); return UndoManager.getInstance(p).isUndoInProgress(); }
/** * delete file or directory (both 'undo' and 'do' modes) unversioned: do nothing, return false * obstructed: do nothing, return false external or wc root: do nothing, return false missing: do * nothing, return false * * <p>versioned: schedule for deletion, return true added: schedule for deletion (make * unversioned), return true copied, but not scheduled: schedule for deletion, return true * replaced: schedule for deletion, return true * * <p>deleted: do nothing, return true (strange) */ public boolean delete(VirtualFile file) throws IOException { final SvnVcs vcs = getVCS(file); if (vcs != null && SvnUtil.isAdminDirectory(file)) { return true; } if (vcs == null) return false; final VcsShowConfirmationOption.Value value = vcs.getDeleteConfirmation().getValue(); if (VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY.equals(value)) return false; final File ioFile = getIOFile(file); if (!SvnUtil.isSvnVersioned(vcs.getProject(), ioFile.getParentFile())) { return false; } if (SvnUtil.isWorkingCopyRoot(ioFile)) { return false; } SVNStatus status = getFileStatus(vcs, ioFile); if (status == null || SvnVcs.svnStatusIsUnversioned(status) || SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_OBSTRUCTED) || SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING) || SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_EXTERNAL) || SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_IGNORED)) { return false; } else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { if (isUndo(vcs)) { moveToUndoStorage(file); } return true; } else { if (vcs != null) { if (isAboveSourceOfCopyOrMove(vcs.getProject(), ioFile)) { myDeletedFiles.putValue(vcs.getProject(), ioFile); return true; } if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED)) { try { createRevertAction(vcs, ioFile, false).execute(); } catch (SVNException e) { // ignore } } else { myDeletedFiles.putValue(vcs.getProject(), ioFile); // packages deleted from disk should not be deleted from svn (IDEADEV-16066) if (file.isDirectory() || isUndo(vcs)) return true; } } return false; } }
public byte[] loadContent() throws IOException, VcsException { ContentLoader loader = new ContentLoader(myURL, myRevision, myPegRevision); if (ApplicationManager.getApplication().isDispatchThread() && !myRevision.isLocal()) { ProgressManager.getInstance() .runProcessWithProgressSynchronously( loader, SvnBundle.message("progress.title.loading.file.content"), false, myVCS.getProject()); } else { loader.run(); } VcsException exception = loader.getException(); if (exception == null) { final byte[] contents = loader.getContents(); ContentRevisionCache.checkContentsSize(myURL, contents.length); return contents; } else { LOG.info( "Failed to load file '" + myURL + "' content at revision: " + myRevision + "\n" + exception.getMessage(), exception); throw exception; } }
@Override public void apply( @NotNull MultiMap<VirtualFile, TextFilePatchInProgress> patchGroups, @Nullable LocalChangeList localList, @Nullable String fileName, @Nullable TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) { final List<FilePatch> patches; try { patches = ApplyPatchSaveToFileExecutor.patchGroupsToOneGroup(patchGroups, myBaseDir); } catch (IOException e) { myInner.handleException(e, true); return; } final PatchApplier<BinaryFilePatch> patchApplier = new PatchApplier<BinaryFilePatch>( myVcs.getProject(), myBaseDir, patches, localList, null, null); patchApplier.execute(false, true); // 3 boolean thereAreCreations = false; for (FilePatch patch : patches) { if (patch.isNewFile() || !Comparing.equal(patch.getAfterName(), patch.getBeforeName())) { thereAreCreations = true; break; } } if (thereAreCreations) { // restore deletion of old directory: myInner.next(new DirectoryAddition()); // 2 } appendResolveConflictToContext(myInner); // 1 appendTailToContextLast(myInner); // 4 myInner.ping(); }
public SvnKitManager(@NotNull SvnVcs vcs) { myVcs = vcs; myProject = myVcs.getProject(); myConfiguration = myVcs.getSvnConfiguration(); refreshSSLProperty(); }
private boolean sameRoot(final SvnVcs vcs, final VirtualFile srcDir, final VirtualFile dstDir) { final UUIDHelper helper = new UUIDHelper(vcs); final String srcUUID = helper.getRepositoryUUID(vcs.getProject(), srcDir); final String dstUUID = helper.getRepositoryUUID(vcs.getProject(), dstDir); return srcUUID != null && dstUUID != null && srcUUID.equals(dstUUID); }
public void execute() { int ok = Messages.showOkCancelDialog( myVcs.getProject(), (myChange.isMoved() ? SvnBundle.message( "confirmation.resolve.tree.conflict.merge.moved", myOldPresentation, myNewPresentation) : SvnBundle.message( "confirmation.resolve.tree.conflict.merge.renamed", myOldPresentation, myNewPresentation)), TreeConflictRefreshablePanel.TITLE, Messages.getQuestionIcon()); if (Messages.OK != ok) return; FileDocumentManager.getInstance().saveAllDocuments(); // final String name = "Merge changes from theirs for: " + myOldPresentation; final Continuation fragmented = Continuation.createFragmented(myVcs.getProject(), false); fragmented.addExceptionHandler( VcsException.class, new Consumer<VcsException>() { @Override public void consume(VcsException e) { myWarnings.add(e); if (e.isWarning()) { return; } AbstractVcsHelper.getInstance(myVcs.getProject()) .showErrors(myWarnings, TreeConflictRefreshablePanel.TITLE); } }); final List<TaskDescriptor> tasks = new SmartList<TaskDescriptor>(); tasks.add( myDescription.isDirectory() ? new PreloadChangesContentsForDir() : new PreloadChangesContentsForFile()); tasks.add(new ConvertTextPaths()); tasks.add(new PatchCreator()); tasks.add(new SelectPatchesInApplyPatchDialog()); tasks.add(new SelectBinaryFiles()); fragmented.run(tasks); }
/** * add file or directory: * * <p>parent directory is: unversioned: do nothing, return false versioned: entry is: null: create * entry, schedule for addition missing: do nothing, return false deleted, 'do' mode: try to * create entry and it schedule for addition if kind is the same, otherwise do nothing, return * false. deleted: 'undo' mode: try to revert non-recursively, if kind is the same, otherwise do * nothing, return false. anything else: return false. */ private boolean createItem( VirtualFile dir, String name, boolean directory, final boolean recursive) { SvnVcs vcs = getVCS(dir); if (vcs == null) { return false; } final VcsShowConfirmationOption.Value value = vcs.getAddConfirmation().getValue(); if (VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY.equals(value)) return false; if (isUndo(vcs) && SvnUtil.isAdminDirectory(dir, name)) { return false; } File ioDir = getIOFile(dir); boolean pendingAdd = isPendingAdd(vcs.getProject(), dir); if (!SvnUtil.isSvnVersioned(vcs.getProject(), ioDir) && !pendingAdd) { return false; } final File targetFile = new File(ioDir, name); SVNStatus status = getFileStatus(vcs, targetFile); if (status == null || status.getContentsStatus() == SVNStatusType.STATUS_NONE || status.getContentsStatus() == SVNStatusType.STATUS_UNVERSIONED) { myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); return false; } else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING)) { return false; } else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { SVNNodeKind kind = status.getKind(); // kind differs. if (directory && kind != SVNNodeKind.DIR || !directory && kind != SVNNodeKind.FILE) { return false; } try { if (isUndo(vcs)) { createRevertAction(vcs, targetFile, false).execute(); return true; } myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); return false; } catch (SVNException e) { SVNFileUtil.deleteAll(targetFile, true); return false; } } return false; }
private boolean doMove(@NotNull SvnVcs vcs, final File src, final File dst) { long srcTime = src.lastModified(); try { final boolean isUndo = isUndo(vcs); final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs, src); WorkingCopyFormat format = vcs.getWorkingCopyFormat(src); final boolean is17OrLater = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format); if (is17OrLater) { SVNStatus srcStatus = getFileStatus(vcs, src); final File toDir = dst.getParentFile(); SVNStatus dstStatus = getFileStatus(vcs, toDir); final boolean srcUnversioned = srcStatus == null || SvnVcs.svnStatusIsUnversioned(srcStatus); if (srcUnversioned && (dstStatus == null || SvnVcs.svnStatusIsUnversioned(dstStatus))) { return false; } if (srcUnversioned) { SVNStatus dstWasStatus = getFileStatus(vcs, dst); if (dstWasStatus == null || SvnVcs.svnStatusIsUnversioned(dstWasStatus)) { return false; } } if (for17move(vcs, src, dst, isUndo, srcStatus)) return false; } else { if (for16move(vcs, src, dst, isUndo)) return false; } if (!isUndo && list != null) { SvnChangelistListener.putUnderList(vcs.getProject(), list, dst); } dst.setLastModified(srcTime); } catch (SVNException e) { addToMoveExceptions(vcs.getProject(), e); return false; } catch (VcsException e) { addToMoveExceptions(vcs.getProject(), e); return false; } return true; }
public SvnAuthenticationManager getManager(final AuthManagerType type, final SvnVcs vcs) { if (AuthManagerType.active.equals(type)) { return getInteractiveManager(vcs); } else if (AuthManagerType.passive.equals(type)) { return getPassiveAuthenticationManager(vcs.getProject()); } else if (AuthManagerType.usual.equals(type)) { return getAuthenticationManager(vcs); } throw new IllegalArgumentException(); }
public SvnAuthenticationManager getInteractiveManager(final SvnVcs svnVcs) { if (myInteractiveManager == null) { myInteractiveManager = new SvnAuthenticationManager(svnVcs.getProject(), new File(getConfigurationDirectory())); myInteractiveManager.setRuntimeStorage(RUNTIME_AUTH_CACHE); myInteractiveProvider = new SvnInteractiveAuthenticationProvider(svnVcs, myInteractiveManager); myInteractiveManager.setAuthenticationProvider(myInteractiveProvider); } return myInteractiveManager; }
public SvnAuthenticationManager getAuthenticationManager(final SvnVcs svnVcs) { if (myAuthManager == null) { // reloaded when configuration directory changes myAuthManager = new SvnAuthenticationManager(svnVcs.getProject(), new File(getConfigurationDirectory())); Disposer.register( svnVcs.getProject(), new Disposable() { @Override public void dispose() { myAuthManager = null; } }); getInteractiveManager(svnVcs); // to init myAuthManager.setAuthenticationProvider( new SvnAuthenticationProvider(svnVcs, myInteractiveProvider, RUNTIME_AUTH_CACHE)); myAuthManager.setRuntimeStorage(RUNTIME_AUTH_CACHE); } return myAuthManager; }
private boolean getAddedFilesPlaceOption() { final SvnConfiguration configuration = SvnConfiguration.getInstance(myVcs.getProject()); boolean add = Boolean.TRUE.equals(configuration.isKeepNewFilesAsIsForTreeConflictMerge()); if (configuration.isKeepNewFilesAsIsForTreeConflictMerge() != null) { return add; } if (!containAdditions(myTheirsChanges) && !containAdditions(myTheirsBinaryChanges)) { return false; } return Messages.YES == MessageDialogBuilder.yesNo( TreeConflictRefreshablePanel.TITLE, "Keep newly created file(s) in their original place?") .yesText("Keep") .noText("Move") .doNotAsk( new DialogWrapper.DoNotAskOption() { @Override public boolean isToBeShown() { return true; } @Override public void setToBeShown(boolean value, int exitCode) { if (!value) { if (exitCode == 0) { // yes configuration.setKeepNewFilesAsIsForTreeConflictMerge(true); } else { configuration.setKeepNewFilesAsIsForTreeConflictMerge(false); } } } @Override public boolean canBeHidden() { return true; } @Override public boolean shouldSaveOptionsOnCancel() { return true; } @NotNull @Override public String getDoNotShowMessage() { return CommonBundle.message("dialog.options.do.not.ask"); } }) .show(); }
@Override public void reportAppendableHistory( FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException { // we need + 1 rows to be reported to further detect that number of rows exceeded the limit reportAppendableHistory( path, partner, null, null, VcsConfiguration.getInstance(myVcs.getProject()).MAXIMUM_HISTORY_ROWS + 1, null, false); }
@Nullable public String getContent() throws VcsException { try { if (myUseBaseRevision) { return ContentRevisionCache.getOrLoadCurrentAsString( myVcs.getProject(), myFile, myVcs.getKeyInstanceMethod(), new CurrentRevisionProvider() { @Override public VcsRevisionNumber getCurrentRevision() throws VcsException { return getRevisionNumber(); } @Override public Pair<VcsRevisionNumber, byte[]> get() throws VcsException, IOException { return Pair.create(getRevisionNumber(), getUpToDateBinaryContent()); } }) .getSecond(); } else { return ContentRevisionCache.getOrLoadAsString( myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(), ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, new Throwable2Computable<byte[], VcsException, IOException>() { @Override public byte[] compute() throws VcsException, IOException { return getUpToDateBinaryContent(); } }); } } catch (IOException e) { throw new VcsException(e); } }
public void reportAppendableHistory( FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException { final FilePath committedPath = ChangesUtil.getCommittedPath(myVcs.getProject(), path); final LogLoader logLoader; if (path.isNonLocal()) { logLoader = new RepositoryLoader(myVcs, path); } else { logLoader = new LocalLoader(myVcs, path); } try { logLoader.preliminary(); } catch (SVNCancelException e) { return; } catch (SVNException e) { throw new VcsException(e); } logLoader.initSupports15(); final MyHistorySession historySession = new MyHistorySession( Collections.<VcsFileRevision>emptyList(), committedPath, Boolean.TRUE.equals(logLoader.mySupport15), null); final Ref<Boolean> sessionReported = new Ref<Boolean>(); final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) { indicator.setText(SvnBundle.message("progress.text2.collecting.history", path.getName())); } final Consumer<VcsFileRevision> consumer = new Consumer<VcsFileRevision>() { public void consume(VcsFileRevision vcsFileRevision) { if (!Boolean.TRUE.equals(sessionReported.get())) { partner.reportCreatedEmptySession(historySession); sessionReported.set(true); } partner.acceptRevision(vcsFileRevision); } }; logLoader.setConsumer(consumer); logLoader.load(); logLoader.check(); }
public void detectCopyRoots(final VirtualFile[] roots, final boolean clearState) { final Getter<Boolean> cancelGetter = new Getter<Boolean>() { public Boolean get() { return myVcs.getProject().isDisposed(); } }; for (final VirtualFile vcsRoot : roots) { final List<Real> foundRoots = ForNestedRootChecker.getAllNestedWorkingCopies(vcsRoot, myVcs, false, cancelGetter); if (foundRoots.isEmpty()) { myLonelyRoots.add(vcsRoot); } // filter out bad(?) items for (Real foundRoot : foundRoots) { final SVNURL repoRoot = foundRoot.getInfo().getRepositoryRootURL(); if (repoRoot == null) { LOG.info( "Error: cannot find repository URL for versioned folder: " + foundRoot.getFile().getPath()); } else { myRepositoryRoots.register(repoRoot); myTopRoots.add( new RootUrlInfo( repoRoot, foundRoot.getInfo().getURL(), SvnFormatSelector.getWorkingCopyFormat(foundRoot.getInfo().getFile()), foundRoot.getFile(), vcsRoot)); } } } if (!SvnConfiguration.getInstance(myVcs.getProject()).DETECT_NESTED_COPIES) { myApplier.apply(myVcs, myTopRoots, myLonelyRoots); } else { addNestedRoots(clearState); } }
private Collection<FilePath> chooseBinaryFiles(List<Change> converted, Set<FilePath> paths) { String singleMessage = ""; if (paths.size() == 1) { final Change change = converted.get(0); final FileStatus status = change.getFileStatus(); final FilePath path = ChangesUtil.getFilePath(change); final String stringPath = TreeConflictRefreshablePanel.filePath(path); if (FileStatus.DELETED.equals(status)) { singleMessage = "Delete binary file " + stringPath + " (according to theirs changes)?"; } else if (FileStatus.ADDED.equals(status)) { singleMessage = "Create binary file " + stringPath + " (according to theirs changes)?"; } else { singleMessage = "Apply changes to binary file " + stringPath + " (according to theirs changes)?"; } } return AbstractVcsHelper.getInstance(myVcs.getProject()) .selectFilePathsToProcess( new ArrayList<FilePath>(paths), TreeConflictRefreshablePanel.TITLE, "Select binary files to patch", TreeConflictRefreshablePanel.TITLE, singleMessage, new VcsShowConfirmationOption() { @Override public Value getValue() { return null; } @Override public void setValue(Value value) {} @Override public boolean isPersistent() { return false; } }); }
public byte[] getContent() throws IOException, VcsException { byte[] result; if (SVNRevision.HEAD.equals(myRevision)) { result = loadContent(); } else { result = ContentRevisionCache.getOrLoadAsBytes( myVCS.getProject(), VcsUtil.getFilePathOnNonLocal(myURL, false), getRevisionNumber(), myVCS.getKeyInstanceMethod(), ContentRevisionCache.UniqueType.REMOTE_CONTENT, new Throwable2Computable<byte[], VcsException, IOException>() { @Override public byte[] compute() throws VcsException, IOException { return loadContent(); } }); } return result; }
private static void addRecursively(final SvnVcs activeVcs, final VirtualFile file) throws SVNException { final SVNWCClient wcClient = activeVcs.createWCClient(); final SvnExcludingIgnoredOperation operation = new SvnExcludingIgnoredOperation( activeVcs.getProject(), new SvnExcludingIgnoredOperation.Operation() { public void doOperation(final VirtualFile virtualFile) throws SVNException { final File ioFile = new File(virtualFile.getPath()); final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) { indicator.checkCanceled(); indicator.setText( SvnBundle.message( "share.or.import.add.progress.text", virtualFile.getPath())); } wcClient.doAdd(ioFile, true, false, false, SVNDepth.EMPTY, false, false); } }, SVNDepth.INFINITY); operation.execute(file); }
@Nullable public File copy(final VirtualFile file, final VirtualFile toDir, final String copyName) throws IOException { SvnVcs vcs = getVCS(toDir); if (vcs == null) { vcs = getVCS(file); } if (vcs == null) { return null; } File srcFile = new File(file.getPath()); File destFile = new File(new File(toDir.getPath()), copyName); final boolean dstDirUnderControl = SvnUtil.isSvnVersioned(vcs.getProject(), destFile.getParentFile()); if (!dstDirUnderControl && !isPendingAdd(vcs.getProject(), toDir)) { return null; } if (!SvnUtil.isSvnVersioned(vcs.getProject(), srcFile.getParentFile())) { myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); return null; } final SVNStatus fileStatus = getFileStatus(vcs, srcFile); if (fileStatus != null && SvnVcs.svnStatusIs(fileStatus, SVNStatusType.STATUS_ADDED)) { myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); return null; } if (sameRoot(vcs, file.getParent(), toDir)) { myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, srcFile, false)); return null; } myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); return null; }
public void reportAppendableHistory( FilePath path, final VcsAppendableHistorySessionPartner partner, @Nullable final SVNRevision from, @Nullable final SVNRevision to, final int limit, SVNRevision peg, final boolean forceBackwards) throws VcsException { FilePath committedPath = path; Change change = ChangeListManager.getInstance(myVcs.getProject()).getChange(path); if (change != null) { final ContentRevision beforeRevision = change.getBeforeRevision(); final ContentRevision afterRevision = change.getAfterRevision(); if (beforeRevision != null && afterRevision != null && !beforeRevision.getFile().equals(afterRevision.getFile()) && afterRevision.getFile().equals(path)) { committedPath = beforeRevision.getFile(); } // revision can be VcsRevisionNumber.NULL if (peg == null && change.getBeforeRevision() != null && change.getBeforeRevision().getRevisionNumber() instanceof SvnRevisionNumber) { peg = ((SvnRevisionNumber) change.getBeforeRevision().getRevisionNumber()).getRevision(); } } final boolean showMergeSources = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate(); final LogLoader logLoader; if (path.isNonLocal()) { logLoader = new RepositoryLoader( myVcs, committedPath, from, to, limit, peg, forceBackwards, showMergeSources); } else { logLoader = new LocalLoader(myVcs, committedPath, from, to, limit, peg, showMergeSources); } try { logLoader.preliminary(); } catch (SVNCancelException e) { throw new VcsException(e); } catch (SVNException e) { throw new VcsException(e); } logLoader.check(); if (showMergeSources) { logLoader.initSupports15(); } final SvnHistorySession historySession = new SvnHistorySession( myVcs, Collections.<VcsFileRevision>emptyList(), committedPath, showMergeSources && Boolean.TRUE.equals(logLoader.mySupport15), null, false, !path.isNonLocal()); final Ref<Boolean> sessionReported = new Ref<Boolean>(); final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) { indicator.setText(SvnBundle.message("progress.text2.collecting.history", path.getName())); } final Consumer<VcsFileRevision> consumer = new Consumer<VcsFileRevision>() { @Override public void consume(VcsFileRevision vcsFileRevision) { if (!Boolean.TRUE.equals(sessionReported.get())) { partner.reportCreatedEmptySession(historySession); sessionReported.set(true); } partner.acceptRevision(vcsFileRevision); } }; logLoader.setConsumer(consumer); logLoader.load(); logLoader.check(); }
private void addNestedRoots(final boolean clearState) { final List<VirtualFile> basicVfRoots = ObjectsConvertor.convert( myTopRoots, new Convertor<RootUrlInfo, VirtualFile>() { public VirtualFile convert(final RootUrlInfo real) { return real.getVirtualFile(); } }); final ChangeListManager clManager = ChangeListManager.getInstance(myVcs.getProject()); if (clearState) { // clear what was reported before (could be for currently-not-existing roots) myGate.get(); } clManager.invokeAfterUpdate( new Runnable() { public void run() { final List<RootUrlInfo> nestedRoots = new ArrayList<RootUrlInfo>(); final NestedCopiesData data = myGate.get(); for (NestedCopiesBuilder.MyPointInfo info : data.getSet()) { if (NestedCopyType.external.equals(info.getType()) || NestedCopyType.switched.equals(info.getType())) { final File infoFile = new File(info.getFile().getPath()); boolean copyFound = false; for (RootUrlInfo topRoot : myTopRoots) { if (topRoot.getIoFile().equals(infoFile)) { topRoot.setType(info.getType()); copyFound = true; break; } } if (copyFound) { continue; } try { final SVNStatus svnStatus = SvnUtil.getStatus(myVcs, infoFile); if (svnStatus.getURL() == null) continue; info.setUrl(svnStatus.getURL()); info.setFormat(WorkingCopyFormat.getInstance(svnStatus.getWorkingCopyFormat())); } catch (Exception e) { continue; } } for (RootUrlInfo topRoot : myTopRoots) { if (VfsUtil.isAncestor(topRoot.getVirtualFile(), info.getFile(), true)) { final SVNURL repoRoot = myRepositoryRoots.ask(info.getUrl()); if (repoRoot != null) { final RootUrlInfo rootInfo = new RootUrlInfo( repoRoot, info.getUrl(), info.getFormat(), info.getFile(), topRoot.getRoot()); rootInfo.setType(info.getType()); nestedRoots.add(rootInfo); } break; } } } // check those top roots which ARE externals, but that was not detected due to they // itself were the status request target // new SvnNestedTypeRechecker(myVcs.getProject(), myTopRoots).run(); myTopRoots.addAll(nestedRoots); myApplier.apply(myVcs, myTopRoots, myLonelyRoots); } }, InvokeAfterUpdateMode.SILENT_CALLBACK_POOLED, null, new Consumer<VcsDirtyScopeManager>() { public void consume(VcsDirtyScopeManager vcsDirtyScopeManager) { if (clearState) { vcsDirtyScopeManager.filesDirty(null, basicVfRoots); } } }, null); }