diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java index c6b0daa0852d..938021c03e55 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java @@ -229,7 +229,8 @@ public abstract class ProjectLevelVcsManager { public abstract boolean isBackgroundVcsOperationRunning(); public abstract List getRootsUnderVcsWithoutFiltering(final AbstractVcs vcs); - public abstract VirtualFile[] getRootsUnderVcs(AbstractVcs vcs); + + public abstract VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs); /** * Also includes into list all modules under roots diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AbstractRefreshablePanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AbstractRefreshablePanel.java index 070a4e95587a..fe20806a8ed4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AbstractRefreshablePanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AbstractRefreshablePanel.java @@ -49,7 +49,7 @@ public abstract class AbstractRefreshablePanel implements RefreshablePanel myDetailsLoader; private final BackgroundTaskQueue myQueue; - private boolean myDisposed; + private volatile boolean myDisposed; protected AbstractRefreshablePanel(final Project project, final String loadingTitle, final BackgroundTaskQueue queue) { myQueue = queue; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java index 7d4156873d7c..b7a42218e3e6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java @@ -150,7 +150,7 @@ public class ChangesBrowserNode extends DefaultMutableTreeNode { public List getAllObjectsUnder(final Class clazz) { List changes = new ArrayList(); - final Enumeration enumeration = depthFirstEnumeration(); + final Enumeration enumeration = preorderEnumeration(); while (enumeration.hasMoreElements()) { ChangesBrowserNode child = (ChangesBrowserNode)enumeration.nextElement(); final Object value = child.getUserObject(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index e699383321ae..84ca76e1d89f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -661,7 +661,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override @NotNull - public VirtualFile[] getRootsUnderVcs(AbstractVcs vcs) { + public VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs) { return myMappingsToRoots.getRootsUnderVcs(vcs); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/MappingsToRoots.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/MappingsToRoots.java index 677c26e6d9f1..1be3cbf0cda3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/MappingsToRoots.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/MappingsToRoots.java @@ -42,7 +42,7 @@ public class MappingsToRoots { } @NotNull - public VirtualFile[] getRootsUnderVcs(final AbstractVcs vcs) { + public VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs) { List result = myMappings.getMappingsAsFilesUnderVcs(vcs); final AbstractVcs.RootsConvertor convertor = vcs.getCustomConvertor(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java index 5ff541ebc67d..57754f0190cc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java @@ -273,7 +273,7 @@ public class NewMappings { return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath()); } - public List getMappingsAsFilesUnderVcs(final AbstractVcs vcs) { + public List getMappingsAsFilesUnderVcs(@NotNull AbstractVcs vcs) { final List result = new ArrayList(); final String vcsName = vcs.getName(); diff --git a/plugins/svn4idea/src/META-INF/plugin.xml b/plugins/svn4idea/src/META-INF/plugin.xml index e831d0550a80..5a441dc89565 100644 --- a/plugins/svn4idea/src/META-INF/plugin.xml +++ b/plugins/svn4idea/src/META-INF/plugin.xml @@ -76,7 +76,7 @@ - + @@ -122,16 +122,16 @@ - + - - + + myRecursiveDirs; - // instead of set and heavy equals of file path - private final Map myNonRecursiveDirs; - // those alone in their immediate parent - private final List mySingleFiles; - public SvnScopeZipper(final VcsDirtyScope in) { + @NotNull private final VcsDirtyScope myIn; + @NotNull private final List myRecursiveDirs; + // instead of set and heavy equals of file path + @NotNull private final Map myNonRecursiveDirs; + + public SvnScopeZipper(@NotNull VcsDirtyScope in) { myIn = in; - myRecursiveDirs = new ArrayList(in.getRecursivelyDirtyDirectories()); - myNonRecursiveDirs = new HashMap(); - mySingleFiles = new ArrayList(); + myRecursiveDirs = ContainerUtil.newArrayList(in.getRecursivelyDirtyDirectories()); + myNonRecursiveDirs = ContainerUtil.newHashMap(); } public void run() { @@ -46,85 +49,72 @@ public class SvnScopeZipper implements Runnable { final VirtualFile vFile = file.getVirtualFile(); // todo take care about this 'not valid' - right now keeping things as they used to be final MyDirNonRecursive me = createOrGet(file); - me.setInterestedInParent(true); if (vFile != null && vFile.isValid()) { for (VirtualFile child : vFile.getChildren()) { me.add(new FilePathImpl(child)); } } } - final FilePath parent = file.getParentPath(); - if (parent != null) { - final MyDirNonRecursive item = createOrGet(parent); - item.add(file); + else { + final FilePath parent = file.getParentPath(); + if (parent != null) { + final MyDirNonRecursive item = createOrGet(parent); + item.add(file); + } } } - - // move alone files into a separate list - /*for (Iterator> iterator = myNonRecursiveDirs.entrySet().iterator(); iterator.hasNext();) { - final Map.Entry entry = iterator.next(); - final MyDirNonRecursive item = entry.getValue(); - if ((! item.isInterestedInParent()) && (item.getChildrenList().size() == 1)) { - iterator.remove(); - mySingleFiles.add(item.getChildrenList().iterator().next()); - } - }*/ } - private MyDirNonRecursive createOrGet(final FilePath parent) { - final String key = getKey(parent); - final MyDirNonRecursive result = myNonRecursiveDirs.get(key); - if (result != null) return result; - final MyDirNonRecursive newItem = new MyDirNonRecursive(parent); - myNonRecursiveDirs.put(key, newItem); - return newItem; + @NotNull + private MyDirNonRecursive createOrGet(@NotNull FilePath parent) { + String key = getKey(parent); + MyDirNonRecursive result = myNonRecursiveDirs.get(key); + + if (result == null) { + result = new MyDirNonRecursive(parent); + myNonRecursiveDirs.put(key, result); + } + + return result; } + @NotNull public List getRecursiveDirs() { return myRecursiveDirs; } + @NotNull public Map getNonRecursiveDirs() { return myNonRecursiveDirs; } - public List getSingleFiles() { - return mySingleFiles; + public static String getKey(@NotNull FilePath path) { + return path.getPresentableUrl(); } static class MyDirNonRecursive { - private boolean myInterestedInParent; - private final FilePath myDir; + + @NotNull private final FilePath myDir; // instead of set and heavy equals of file path - private final Map myChildren; + @NotNull private final Map myChildren; - private MyDirNonRecursive(final FilePath dir) { + private MyDirNonRecursive(@NotNull FilePath dir) { myDir = dir; - myChildren = new HashMap(); + myChildren = ContainerUtil.newHashMap(); } - public boolean isInterestedInParent() { - return myInterestedInParent; - } - - public void setInterestedInParent(boolean interestedInParent) { - myInterestedInParent = interestedInParent; - } - - public void add(final FilePath path) { + public void add(@NotNull FilePath path) { myChildren.put(getKey(path), path); } + @NotNull public Collection getChildrenList() { return myChildren.values(); } + @NotNull public FilePath getDir() { return myDir; } } - - public static String getKey(final FilePath path) { - return path.getPresentableUrl(); - } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index 43407f4b2064..aaf46003c1dd 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -49,6 +49,7 @@ import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.api.EventAction; import org.jetbrains.idea.svn.api.ProgressEvent; import org.jetbrains.idea.svn.api.ProgressTracker; +import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.browse.DirectoryEntry; import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer; @@ -58,11 +59,15 @@ import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.status.Status; import org.tmatesoft.sqljet.core.SqlJetException; import org.tmatesoft.sqljet.core.table.SqlJetDb; -import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNErrorMessage; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration; -import org.tmatesoft.svn.core.wc.*; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNWCUtil; import org.tmatesoft.svn.core.wc2.SvnOperationFactory; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -343,7 +348,7 @@ public class SvnUtil { for (T committable : committables) { final RootUrlInfo path = vcs.getSvnFileUrlMapping().getWcRootForFilePath(convertor.convert(committable)); if (path == null) { - result.putValue(new Pair(null, null), committable); + result.putValue(Pair.create((SVNURL)null, WorkingCopyFormat.UNKNOWN), committable); } else { result.putValue(Pair.create(path.getRepositoryUrlUrl(), path.getFormat()), committable); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index b44fd16f979f..e5018f3319d5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -68,6 +68,7 @@ import org.jetbrains.idea.svn.api.CmdClientFactory; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.api.SvnKitClientFactory; import org.jetbrains.idea.svn.auth.SvnAuthenticationNotifier; +import org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage; import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment; import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider; import org.jetbrains.idea.svn.commandLine.SvnBindException; @@ -81,7 +82,6 @@ import org.jetbrains.idea.svn.history.SvnHistoryProvider; import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.info.InfoConsumer; import org.jetbrains.idea.svn.properties.PropertyClient; -import org.jetbrains.idea.svn.properties.PropertyData; import org.jetbrains.idea.svn.properties.PropertyValue; import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment; import org.jetbrains.idea.svn.status.Status; @@ -89,7 +89,10 @@ import org.jetbrains.idea.svn.status.StatusType; import org.jetbrains.idea.svn.svnkit.SvnKitManager; import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment; import org.jetbrains.idea.svn.update.SvnUpdateEnvironment; -import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.wc.SVNAdminUtil; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -145,7 +148,7 @@ public class SvnVcs extends AbstractVcs { private final RootsToWorkingCopies myRootsToWorkingCopies; private final SvnAuthenticationNotifier myAuthNotifier; - private final SvnLoadedBrachesStorage myLoadedBranchesStorage; + private final SvnLoadedBranchesStorage myLoadedBranchesStorage; private final SvnExecutableChecker myChecker; @@ -157,7 +160,7 @@ public class SvnVcs extends AbstractVcs { private final boolean myLogExceptions; - public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) { + public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBranchesStorage storage) { super(project, VCS_NAME); myLoadedBranchesStorage = storage; @@ -723,9 +726,10 @@ public class SvnVcs extends AbstractVcs { return WorkingCopyFormat.UNKNOWN.equals(format) ? SvnFormatSelector.findRootAndGetFormat(ioFile) : format; } - public boolean isWcRoot(FilePath filePath) { + public boolean isWcRoot(@NotNull FilePath filePath) { boolean isWcRoot = false; - WorkingCopy wcRoot = myRootsToWorkingCopies.getWcRoot(filePath.getVirtualFile()); + VirtualFile file = filePath.getVirtualFile(); + WorkingCopy wcRoot = file != null ? myRootsToWorkingCopies.getWcRoot(file) : null; if (wcRoot != null) { isWcRoot = wcRoot.getFile().getAbsolutePath().equals(filePath.getIOFile().getAbsolutePath()); } @@ -917,7 +921,7 @@ public class SvnVcs extends AbstractVcs { } @Override - public boolean isVcsBackgroundOperationsAllowed(VirtualFile root) { + public boolean isVcsBackgroundOperationsAllowed(@NotNull VirtualFile root) { // TODO: Currently myAuthNotifier.isAuthenticatedFor directly uses SVNKit to check credentials - so assume for now that background // TODO: operations are always allowed for command line. As sometimes this leads to errors - for instance, incoming changes are not // TODO: displayed in "Incoming" tab - incoming changes are collected using command line but not displayed because diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java index ff0f158f32a8..468399e93679 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java @@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnBundle; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.integrate.MergerFactory; import org.jetbrains.idea.svn.integrate.SelectedCommittedStuffChecker; import org.jetbrains.idea.svn.integrate.SvnIntegrateChangesActionPerformer; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java index ddd9bd572f0e..ee4f807c2570 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java @@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsRunnable; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.SvnRevisionNumber; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.SvnVcs; @@ -33,7 +34,6 @@ import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.properties.PropertyClient; import org.jetbrains.idea.svn.properties.PropertyValue; -import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -162,8 +162,8 @@ public class SvnMergeProvider implements MergeProvider { File ioFile = new File(file.getPath()); PropertyClient client = vcs.getFactory(ioFile).createPropertyClient(); - PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile), SVNProperty.MIME_TYPE, false, SVNRevision.WORKING); - if (value != null && SVNProperty.isBinaryMimeType(value.toString())) { + PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_MIME_TYPE, false, SVNRevision.WORKING); + if (value != null && isBinaryMimeType(value.toString())) { return true; } } @@ -173,4 +173,8 @@ public class SvnMergeProvider implements MergeProvider { return false; } + + private static boolean isBinaryMimeType(@NotNull String mimeType) { + return !mimeType.startsWith("text/"); + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java index 57c835daef2f..ffc21a011334 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java @@ -223,7 +223,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl -
+ diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.java similarity index 95% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.java index 50ddd9615d41..0e0fce947088 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.idea.svn.dialogs; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.actionSystem.ActionToolbarPosition; import com.intellij.openapi.project.Project; @@ -32,12 +32,8 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; -import org.jetbrains.idea.svn.branchConfig.InfoReliability; -import org.jetbrains.idea.svn.branchConfig.InfoStorage; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.commandLine.SvnBindException; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; +import org.jetbrains.idea.svn.dialogs.SelectLocationDialog; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNURLUtil; @@ -59,7 +55,7 @@ public class BranchConfigurationDialog extends DialogWrapper { private JList myLocationList; private JPanel myListPanel; private JLabel myErrorPrompt; - private final SvnBranchConfigManager mySvnBranchConfigManager; + private final NewRootBunch mySvnBranchConfigManager; private final VirtualFile myRoot; public BranchConfigurationDialog(@NotNull final Project project, @@ -115,7 +111,7 @@ public class BranchConfigurationDialog extends DialogWrapper { if (!configuration.getBranchUrls().contains(selectedUrl)) { configuration .addBranches(selectedUrl, new InfoStorage>(new ArrayList(), InfoReliability.empty)); - mySvnBranchConfigManager.reloadBranches(myRoot, selectedUrl, null); + mySvnBranchConfigManager.reloadBranchesAsync(myRoot, selectedUrl, InfoReliability.setByUser); listModel.fireItemAdded(); myLocationList.setSelectedIndex(listModel.getSize() - 1); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java index 10f4574c7f39..ba0288da9699 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,16 @@ package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.SvnConfiguration; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.browse.DirectoryEntry; import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.wc.SVNLogClient; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -33,27 +35,60 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -public class BranchesLoader { +/** + * @author Konstantin Kolosovsky. + */ +public class BranchesLoader implements Runnable { + @NotNull private final Project myProject; + @NotNull private final NewRootBunch myBunch; + @NotNull private final VirtualFile myRoot; + @NotNull private final String myUrl; + @NotNull private final InfoReliability myInfoReliability; + private final boolean myPassive; - private BranchesLoader() { + public BranchesLoader(@NotNull Project project, + @NotNull NewRootBunch bunch, + @NotNull String url, + @NotNull InfoReliability infoReliability, + @NotNull VirtualFile root, + boolean passive) { + myProject = project; + myBunch = bunch; + myUrl = url; + myInfoReliability = infoReliability; + myRoot = root; + myPassive = passive; } - public static List loadBranches(final Project project, final String url, boolean passive) throws SVNException, - VcsException { - final SvnConfiguration configuration = SvnConfiguration.getInstance(project); - final SvnVcs vcs = SvnVcs.getInstance(project); - SVNURL branchesUrl = SVNURL.parseURIEncoded(url); + public void run() { + try { + List branches = loadBranches(); + myBunch.updateBranches(myRoot, myUrl, new InfoStorage>(branches, myInfoReliability)); + } + catch (VcsException e) { + showError(e); + } + catch (SVNException e) { + showError(e); + } + } + + @NotNull + public List loadBranches() throws SVNException, VcsException { + final SvnConfiguration configuration = SvnConfiguration.getInstance(myProject); + final SvnVcs vcs = SvnVcs.getInstance(myProject); + SVNURL branchesUrl = SVNURL.parseURIEncoded(myUrl); List result = new LinkedList(); SvnTarget target = SvnTarget.fromURL(branchesUrl); - if (!passive) { + if (!myPassive) { // TODO: Implement ability to specify interactive/non-interactive auth mode for clients DirectoryEntryConsumer handler = createConsumer(branchesUrl, result); vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, handler); } else { ISVNDirEntryHandler handler = createHandler(branchesUrl, result); - SVNLogClient client = vcs.getSvnKitManager().createLogClient(configuration.getPassiveAuthenticationManager(project)); + SVNLogClient client = vcs.getSvnKitManager().createLogClient(configuration.getPassiveAuthenticationManager(myProject)); client .doList(target.getURL(), target.getPegRevision(), SVNRevision.HEAD, false, SVNDepth.IMMEDIATES, SVNDirEntry.DIRENT_ALL, handler); } @@ -62,6 +97,13 @@ public class BranchesLoader { return result; } + private void showError(Exception e) { + // already logged inside + if (InfoReliability.setByUser.equals(myInfoReliability)) { + VcsBalloonProblemNotifier.showOverChangesView(myProject, "Branches load error: " + e.getMessage(), MessageType.ERROR); + } + } + @NotNull private static ISVNDirEntryHandler createHandler(@NotNull final SVNURL branchesUrl, @NotNull final List result) { return new ISVNDirEntryHandler() { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/ConfigureBranchesAction.java similarity index 94% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/ConfigureBranchesAction.java index 1993a1caa0fe..3615c4b4792d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/ConfigureBranchesAction.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn.actions; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -28,7 +27,6 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import icons.SvnIcons; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog; import org.jetbrains.idea.svn.history.SvnChangeList; public class ConfigureBranchesAction extends AnAction implements DumbAware { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateBranchOrTagAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagAction.java similarity index 98% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateBranchOrTagAction.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagAction.java index c6f633416a15..da1557922a44 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateBranchOrTagAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagAction.java @@ -15,7 +15,7 @@ */ -package org.jetbrains.idea.svn.actions; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.Application; @@ -35,10 +35,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnStatusUtil; import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.actions.BasicAction; import org.jetbrains.idea.svn.checkin.CommitEventHandler; import org.jetbrains.idea.svn.checkin.IdeaCommitHandler; import org.jetbrains.idea.svn.commandLine.SvnBindException; -import org.jetbrains.idea.svn.dialogs.CreateBranchOrTagDialog; import org.jetbrains.idea.svn.update.AutoSvnUpdater; import org.jetbrains.idea.svn.update.SingleRootSwitcher; import org.tmatesoft.svn.core.SVNErrorCode; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.form similarity index 99% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.form rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.form index 6dfcae6c9f6f..96eaeaaf2c4c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.form +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.form @@ -1,5 +1,5 @@ - + diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.java similarity index 98% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.java index a09de54fdbc4..95ae986dd72d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn.dialogs; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.icons.AllIcons; import com.intellij.openapi.diagnostic.Logger; @@ -33,10 +33,9 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.RootUrlInfo; -import org.jetbrains.idea.svn.SvnBranchConfigurationManager; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; +import org.jetbrains.idea.svn.dialogs.SelectLocationDialog; import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.update.SvnRevisionPanel; import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultBranchConfigInitializer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultBranchConfigInitializer.java new file mode 100644 index 000000000000..37b78459448c --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultBranchConfigInitializer.java @@ -0,0 +1,155 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn.branchConfig; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.SvnUtil; +import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.api.Depth; +import org.jetbrains.idea.svn.browse.DirectoryEntry; +import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.internal.util.SVNPathUtil; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.util.ArrayList; +import java.util.List; + +/** +* @author Konstantin Kolosovsky. +*/ +public class DefaultBranchConfigInitializer implements Runnable { + + private static final Logger LOG = Logger.getInstance(DefaultBranchConfigInitializer.class); + + @NonNls private static final String DEFAULT_TRUNK_NAME = "trunk"; + @NonNls private static final String DEFAULT_BRANCHES_NAME = "branches"; + @NonNls private static final String DEFAULT_TAGS_NAME = "tags"; + + @NotNull private final Project myProject; + @NotNull private final NewRootBunch myBunch; + @NotNull private final VirtualFile myRoot; + + public DefaultBranchConfigInitializer(@NotNull Project project, @NotNull NewRootBunch bunch, @NotNull VirtualFile root) { + myProject = project; + myRoot = root; + myBunch = bunch; + } + + public void run() { + SvnBranchConfigurationNew configuration = getDefaultConfiguration(); + + if (configuration != null) { + for (String url : configuration.getBranchUrls()) { + myBunch.reloadBranchesAsync(myRoot, url, InfoReliability.defaultValues); + } + + myBunch.updateForRoot(myRoot, new InfoStorage(configuration, InfoReliability.defaultValues), false); + } + } + + @Nullable + public SvnBranchConfigurationNew getDefaultConfiguration() { + SvnBranchConfigurationNew result = null; + SvnVcs vcs = SvnVcs.getInstance(myProject); + SVNURL rootUrl = SvnUtil.getUrl(vcs, VfsUtilCore.virtualToIoFile(myRoot)); + + if (rootUrl != null) { + try { + result = getDefaultConfiguration(vcs, rootUrl); + } + catch (SVNException e) { + LOG.info(e); + } + catch (VcsException e) { + LOG.info(e); + } + } + else { + LOG.info("Directory is not a working copy: " + myRoot.getPresentableUrl()); + } + + return result; + } + + @NotNull + private static SvnBranchConfigurationNew getDefaultConfiguration(@NotNull SvnVcs vcs, @NotNull SVNURL url) + throws SVNException, VcsException { + SvnBranchConfigurationNew result = new SvnBranchConfigurationNew(); + result.setTrunkUrl(url.toString()); + + SVNURL branchLocationsParent = getBranchLocationsParent(url); + if (branchLocationsParent != null) { + SvnTarget target = SvnTarget.fromURL(branchLocationsParent); + + vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, createHandler(result, target.getURL())); + } + + return result; + } + + @Nullable + private static SVNURL getBranchLocationsParent(@NotNull SVNURL url) throws SVNException { + while (!hasEmptyName(url) && !hasDefaultName(url)) { + url = url.removePathTail(); + } + + return hasDefaultName(url) ? url.removePathTail() : null; + } + + private static boolean hasEmptyName(@NotNull SVNURL url) { + return StringUtil.isEmpty(SVNPathUtil.tail(url.getPath())); + } + + private static boolean hasDefaultName(@NotNull SVNURL url) { + String name = SVNPathUtil.tail(url.getPath()); + + return name.equalsIgnoreCase(DEFAULT_TRUNK_NAME) || + name.equalsIgnoreCase(DEFAULT_BRANCHES_NAME) || + name.equalsIgnoreCase(DEFAULT_TAGS_NAME); + } + + @NotNull + private static DirectoryEntryConsumer createHandler(@NotNull final SvnBranchConfigurationNew result, @NotNull final SVNURL rootPath) { + return new DirectoryEntryConsumer() { + + @Override + public void consume(final DirectoryEntry entry) throws SVNException { + if (entry.isDirectory()) { + SVNURL childUrl = rootPath.appendPath(entry.getName(), false); + + if (StringUtil.endsWithIgnoreCase(entry.getName(), DEFAULT_TRUNK_NAME)) { + result.setTrunkUrl(childUrl.toString()); + } + else { + result.addBranches(childUrl.toString(), + new InfoStorage>(new ArrayList(0), InfoReliability.defaultValues)); + } + } + } + }; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java deleted file mode 100644 index d52798e6bfc3..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn.branchConfig; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.api.Depth; -import org.jetbrains.idea.svn.browse.DirectoryEntry; -import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer; -import org.jetbrains.idea.svn.info.Info; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; -import org.tmatesoft.svn.core.*; -import org.tmatesoft.svn.core.internal.util.SVNPathUtil; -import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc2.SvnTarget; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -public class DefaultConfigLoader { - - private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.DefaultConfigLoader"); - - @NonNls private static final String DEFAULT_TRUNK_NAME = "trunk"; - @NonNls private static final String DEFAULT_BRANCHES_NAME = "branches"; - @NonNls private static final String DEFAULT_TAGS_NAME = "tags"; - - private DefaultConfigLoader() { - } - - @Nullable - public static SvnBranchConfigurationNew loadDefaultConfiguration(final Project project, final VirtualFile vcsRoot) { - try { - final SvnVcs vcs = SvnVcs.getInstance(project); - - File rootFile = new File(vcsRoot.getPath()); - final Info info = vcs.getInfo(rootFile); - if (info == null || info.getURL() == null) { - LOG.info("Directory is not a working copy: " + vcsRoot.getPresentableUrl()); - return null; - } - SVNURL baseUrl = info.getURL(); - - final SvnBranchConfigurationNew result = new SvnBranchConfigurationNew(); - result.setTrunkUrl(baseUrl.toString()); - while(true) { - final String s = SVNPathUtil.tail(baseUrl.getPath()); - if (s.equalsIgnoreCase(DEFAULT_TRUNK_NAME) || s.equalsIgnoreCase(DEFAULT_BRANCHES_NAME) || s.equalsIgnoreCase(DEFAULT_TAGS_NAME)) { - SVNURL rootPath = baseUrl.removePathTail(); - SvnTarget target = SvnTarget.fromURL(rootPath); - - vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, createHandler(result, rootPath)); - break; - } - if (SVNPathUtil.removeTail(baseUrl.getPath()).length() == 0) { - break; - } - baseUrl = baseUrl.removePathTail(); - } - return result; - } - catch (SVNException e) { - LOG.info(e); - return null; - } - catch (VcsException e) { - LOG.info(e); - return null; - } - } - - @NotNull - private static DirectoryEntryConsumer createHandler(final SvnBranchConfigurationNew result, final SVNURL rootPath) { - return new DirectoryEntryConsumer() { - - @Override - public void consume(final DirectoryEntry entry) throws SVNException { - if (entry.isDirectory()) { - SVNURL childUrl = rootPath.appendPath(entry.getName(), false); - - if (StringUtil.endsWithIgnoreCase(entry.getName(), DEFAULT_TRUNK_NAME)) { - result.setTrunkUrl(childUrl.toString()); - } - else { - result.addBranches(childUrl.toString(), - new InfoStorage>(new ArrayList(0), InfoReliability.defaultValues)); - } - } - } - }; - } -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/InfoStorage.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/InfoStorage.java index 493721e3a8d1..fe10696768c1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/InfoStorage.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/InfoStorage.java @@ -15,9 +15,6 @@ */ package org.jetbrains.idea.svn.branchConfig; -import com.intellij.util.PairConsumer; -import org.jetbrains.annotations.Nullable; - public class InfoStorage { public T myT; public InfoReliability myInfoReliability; @@ -27,14 +24,15 @@ public class InfoStorage { myInfoReliability = infoReliability; } - public void accept(final InfoStorage infoStorage, @Nullable final PairConsumer callbackOnUpdate) { - if (infoStorage.myInfoReliability.shouldOverride(myInfoReliability)) { - if (callbackOnUpdate != null) { - callbackOnUpdate.consume(myT, infoStorage.myT); - } + public boolean accept(final InfoStorage infoStorage) { + boolean override = infoStorage.myInfoReliability.shouldOverride(myInfoReliability); + + if (override) { myT = infoStorage.myT; myInfoReliability = infoStorage.myInfoReliability; } + + return override; } public T getValue() { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java index 2c7444ed85b0..6f7f4185a815 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java @@ -15,31 +15,23 @@ */ package org.jetbrains.idea.svn.branchConfig; -import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManagerQueue; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.CalledInBackground; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Consumer; -import com.intellij.util.PairConsumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; +import org.jetbrains.idea.svn.SvnVcs; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; // synch is here -public class NewRootBunch implements SvnBranchConfigManager { +public class NewRootBunch { private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.NewRootBunch"); private final Object myLock = new Object(); private final Project myProject; @@ -52,17 +44,31 @@ public class NewRootBunch implements SvnBranchConfigManager { myMap = new HashMap>(); } - public void updateForRoot(@NotNull final VirtualFile root, @NotNull final InfoStorage config, - @Nullable final PairConsumer callbackOnUpdate) { + public void updateForRoot(@NotNull final VirtualFile root, + @NotNull final InfoStorage config, + boolean reload) { synchronized (myLock) { + final SvnBranchConfigurationNew previous; + boolean override; final InfoStorage existing = myMap.get(root); + if (existing == null) { + previous = null; + override = true; myMap.put(root, config); - if (callbackOnUpdate != null) { - callbackOnUpdate.consume(null, config.getValue()); - } - } else { - existing.accept(config, callbackOnUpdate); + } + else { + previous = existing.getValue(); + override = existing.accept(config); + } + + if (reload && override) { + myBranchesLoader.run(new Runnable() { + @Override + public void run() { + reloadBranches(root, previous, config.getValue()); + } + }); } } } @@ -88,17 +94,44 @@ public class NewRootBunch implements SvnBranchConfigManager { result = new SvnBranchConfigurationNew(); myMap.put(root, new InfoStorage(result, InfoReliability.empty)); myBranchesLoader.run(new DefaultBranchConfigInitializer(myProject, this, root)); - } else { + } + else { result = value.getValue(); } return result; } } - public void reloadBranches(@NotNull final VirtualFile root, @NotNull final String branchParentUrl, - final Consumer> callback) { - ApplicationManager.getApplication().executeOnPooledThread(new BranchesLoadRunnable(myProject, this, branchParentUrl, - InfoReliability.setByUser, root, callback, true)); + public void reloadBranchesAsync(@NotNull final VirtualFile root, + @NotNull final String branchLocation, + @NotNull final InfoReliability reliability) { + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + reloadBranches(root, branchLocation, reliability, true); + } + }); + } + + public void reloadBranches(@NotNull VirtualFile root, @Nullable SvnBranchConfigurationNew prev, @NotNull SvnBranchConfigurationNew next) { + final Set oldUrls = (prev == null) ? Collections.emptySet() : new HashSet(prev.getBranchUrls()); + final SvnVcs vcs = SvnVcs.getInstance(myProject); + if (!vcs.isVcsBackgroundOperationsAllowed(root)) return; + + for (String newBranchUrl : next.getBranchUrls()) { + // check if cancel had been put + if (!vcs.isVcsBackgroundOperationsAllowed(root)) return; + if (!oldUrls.contains(newBranchUrl)) { + reloadBranches(root, newBranchUrl, InfoReliability.defaultValues, true); + } + } + } + + public void reloadBranches(@NotNull VirtualFile root, + @NotNull String branchLocation, + @NotNull InfoReliability reliability, + boolean passive) { + new BranchesLoader(myProject, this, branchLocation, reliability, root, passive).run(); } @Nullable @@ -108,28 +141,11 @@ public class NewRootBunch implements SvnBranchConfigManager { try { final SvnBranchConfigurationNew configuration = myMap.get(root).getValue(); final String group = configuration.getGroupToLoadToReachUrl(svnurl); - final Runnable runnable = new Runnable() { - public void run() { - final SvnBranchConfigurationNew reloadedConfiguration = myMap.get(root).getValue(); - try { - result.set(reloadedConfiguration.getWorkingBranch(svnurl)); - } - catch (SVNException e) { - // - } - } - }; - if (group == null) { - runnable.run(); - } else { - new BranchesLoadRunnable(myProject, this, group, InfoReliability.setByUser, root, - new Consumer>() { - public void consume(List svnBranchItems) { - runnable.run(); - } - }, true).run(); + if (group != null) { + reloadBranches(root, group, InfoReliability.setByUser, true); } + result.set(myMap.get(root).getValue().getWorkingBranch(svnurl)); } catch (SVNException e) { // @@ -137,88 +153,6 @@ public class NewRootBunch implements SvnBranchConfigManager { return result.get(); } - public static class BranchesLoadRunnable implements Runnable { - private final Project myProject; - private final SvnBranchConfigManager myBunch; - private final VirtualFile myRoot; - @Nullable - private final Consumer> myCallback; - private final String myUrl; - private final InfoReliability myInfoReliability; - private boolean myPassive; - - public BranchesLoadRunnable(final Project project, - final SvnBranchConfigManager bunch, - final String url, - final InfoReliability infoReliability, - final VirtualFile root, - @Nullable final Consumer> callback, - boolean passive) { - myProject = project; - myBunch = bunch; - myUrl = url; - myInfoReliability = infoReliability; - myRoot = root; - myCallback = callback; - myPassive = passive; - } - - public void run() { - boolean callbackCalled = false; - try { - final List items = BranchesLoader.loadBranches(myProject, myUrl, myPassive); - myBunch.updateBranches(myRoot, myUrl, new InfoStorage>(items, myInfoReliability)); - if (myCallback != null) { - myCallback.consume(items); - callbackCalled = true; - } - } - catch (VcsException e) { - showError(e); - } - catch (SVNException e) { - showError(e); - } - finally { - // callback must be called by contract - if (myCallback != null && (! callbackCalled)) { - myCallback.consume(null); - } - } - } - - private void showError(Exception e) { - // already logged inside - if (InfoReliability.setByUser.equals(myInfoReliability)) { - VcsBalloonProblemNotifier.showOverChangesView(myProject, "Branches load error: " + e.getMessage(), MessageType.ERROR); - } - } - } - - private static class DefaultBranchConfigInitializer implements Runnable { - private final Project myProject; - private final SvnBranchConfigManager myBunch; - private final VirtualFile myRoot; - - private DefaultBranchConfigInitializer(final Project project, final SvnBranchConfigManager bunch, final VirtualFile root) { - myProject = project; - myRoot = root; - myBunch = bunch; - } - - public void run() { - final SvnBranchConfigurationNew result = DefaultConfigLoader.loadDefaultConfiguration(myProject, myRoot); - if (result != null) { - final Application application = ApplicationManager.getApplication(); - for (String url : result.getBranchUrls()) { - application.executeOnPooledThread(new BranchesLoadRunnable(myProject, myBunch, url, InfoReliability.defaultValues, myRoot, null, - true)); - } - myBunch.updateForRoot(myRoot, new InfoStorage(result, InfoReliability.defaultValues), null); - } - } - } - public Map getMapCopy() { synchronized (myLock) { final Map result = new HashMap(); @@ -228,4 +162,4 @@ public class NewRootBunch implements SvnBranchConfigManager { return result; } } -} +} \ No newline at end of file diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SelectBranchPopup.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SelectBranchPopup.java similarity index 94% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SelectBranchPopup.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SelectBranchPopup.java index 5e634f3b9b87..445ce4e9afe3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SelectBranchPopup.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SelectBranchPopup.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn.actions; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -30,13 +30,10 @@ import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.*; -import org.jetbrains.idea.svn.branchConfig.InfoReliability; -import org.jetbrains.idea.svn.branchConfig.NewRootBunch; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; -import org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; +import org.jetbrains.idea.svn.RootUrlInfo; +import org.jetbrains.idea.svn.SvnBundle; +import org.jetbrains.idea.svn.SvnFileUrlMapping; +import org.jetbrains.idea.svn.SvnVcs; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; @@ -221,8 +218,9 @@ public class SelectBranchPopup { @Override protected void runImpl(@NotNull ProgressIndicator indicator) { - final SvnBranchConfigManager manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager(); - new NewRootBunch.BranchesLoadRunnable(myProject, manager, selectedBranchesHolder, InfoReliability.setByUser, myVcsRoot, null, false).run(); + final NewRootBunch manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager(); + + manager.reloadBranches(myVcsRoot, selectedBranchesHolder, InfoReliability.setByUser, false); } }); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigManager.java deleted file mode 100644 index 0a47a7771171..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigManager.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn.branchConfig; - -import com.intellij.openapi.vcs.CalledInBackground; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Consumer; -import com.intellij.util.PairConsumer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; -import org.tmatesoft.svn.core.SVNURL; - -import java.util.List; -import java.util.Map; - -public interface SvnBranchConfigManager { - void updateForRoot(@NotNull VirtualFile root, @NotNull InfoStorage config, - @Nullable final PairConsumer callbackOnUpdate); - - void updateBranches(@NotNull VirtualFile root, @NotNull String branchesParent, - @NotNull InfoStorage> items); - - @NotNull - SvnBranchConfigurationNew getConfig(@NotNull VirtualFile root); - - void reloadBranches(@NotNull VirtualFile root, @NotNull String branchParentUrl, - Consumer> callback); - @Nullable - @CalledInBackground - SVNURL getWorkingBranchWithReload(final SVNURL svnurl, final VirtualFile root); - - Map getMapCopy(); -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfiguration.java similarity index 70% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfiguration.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfiguration.java index c167fd868531..0c6138fd08c2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfiguration.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfiguration.java @@ -14,24 +14,36 @@ * limitations under the License. */ -package org.jetbrains.idea.svn; +package org.jetbrains.idea.svn.branchConfig; + +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** + * Default constructor and setters are necessary for serialization purposes. + * * @author yole */ +@SuppressWarnings("UnusedDeclaration") public class SvnBranchConfiguration { private String myTrunkUrl; - private List myBranchUrls; + @NotNull private List myBranchUrls; private boolean myUserinfoInUrl; public SvnBranchConfiguration() { myBranchUrls = new ArrayList(); } + public SvnBranchConfiguration(String trunkUrl, @NotNull List branchUrls, boolean userinfoInUrl) { + myTrunkUrl = trunkUrl; + myBranchUrls = branchUrls; + Collections.sort(myBranchUrls); + myUserinfoInUrl = userinfoInUrl; + } + public boolean isUserinfoInUrl() { return myUserinfoInUrl; } @@ -39,8 +51,8 @@ public class SvnBranchConfiguration { public void setUserinfoInUrl(final boolean userinfoInUrl) { myUserinfoInUrl = userinfoInUrl; } - - public void setBranchUrls(final List branchUrls) { + + public void setBranchUrls(@NotNull List branchUrls) { myBranchUrls = branchUrls; Collections.sort(myBranchUrls); } @@ -53,6 +65,7 @@ public class SvnBranchConfiguration { return myTrunkUrl; } + @NotNull public List getBranchUrls() { return myBranchUrls; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfigurationManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationManager.java similarity index 51% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfigurationManager.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationManager.java index f13ed5a97a03..772e5edd2755 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfigurationManager.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.idea.svn; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.application.ApplicationManager; @@ -27,7 +27,6 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressManagerQueue; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.committed.VcsConfigurationChangeListener; @@ -35,14 +34,10 @@ import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; import com.intellij.openapi.vcs.impl.VcsInitObject; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.PairConsumer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.branchConfig.*; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNURL; +import org.jetbrains.idea.svn.SvnVcs; import java.io.File; import java.util.*; @@ -58,15 +53,16 @@ import java.util.*; )} ) public class SvnBranchConfigurationManager implements PersistentStateComponent { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnBranchConfigurationManager"); + private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager"); private final Project myProject; private final ProjectLevelVcsManager myVcsManager; - private final SvnLoadedBrachesStorage myStorage; + private final SvnLoadedBranchesStorage myStorage; private final ProgressManagerQueue myBranchesLoader; + private boolean myIsInitialized; public SvnBranchConfigurationManager(final Project project, final ProjectLevelVcsManager vcsManager, - final SvnLoadedBrachesStorage storage) { + final SvnLoadedBranchesStorage storage) { myProject = project; myVcsManager = vcsManager; myStorage = storage; @@ -91,7 +87,13 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent(configuration, InfoReliability.setByUser), - new BranchesPreloader(myProject, myBunch, vcsRoot, myBranchesLoader)); + myBunch.updateForRoot(vcsRoot, new InfoStorage(configuration, InfoReliability.setByUser), true); SvnBranchMapperManager.getInstance().notifyBranchesChanged(myProject, vcsRoot, configuration); @@ -136,71 +137,33 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent> map = new HashMap>(); - final Map>> origMap = configOrig.getBranchMap(); - for (String origKey : origMap.keySet()) { - map.put(origKey, origMap.get(origKey).getValue()); - } + final SvnBranchConfiguration configuration = + new SvnBranchConfiguration(configOrig.getTrunkUrl(), configOrig.getBranchUrls(), configOrig.isUserinfoInUrl()); + result.myConfigurationMap.put(key, helper.prepareForSerialization(configuration)); } result.mySupportsUserInfoFilter = true; return result; } - private static class BranchesPreloader implements PairConsumer { - private final Project myProject; - private final VirtualFile myRoot; - private final ProgressManagerQueue myQueue; - private final SvnBranchConfigManager myBunch; - private boolean myAll; + public void loadState(ConfigurationBean object) { + myConfigurationBean = object; + } - public BranchesPreloader(Project project, @NotNull final SvnBranchConfigManager bunch, VirtualFile root, - final ProgressManagerQueue queue) { - myBunch = bunch; - myProject = project; - myRoot = root; - myQueue = queue; - } + private synchronized void initialize() { + if (!myIsInitialized) { + myIsInitialized = true; - public void consume(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) { - myQueue.run(new Runnable() { - public void run() { - loadImpl(prev, next); - } - }); - } - - protected void loadImpl(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) { - final Set oldUrls = (prev == null) ? Collections.emptySet() : new HashSet(prev.getBranchUrls()); - final SvnVcs vcs = SvnVcs.getInstance(myProject); - if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return; - - for (String newBranchUrl : next.getBranchUrls()) { - // check if cancel had been put - if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return; - if (myAll || (! oldUrls.contains(newBranchUrl))) { - new NewRootBunch.BranchesLoadRunnable(myProject, myBunch, newBranchUrl, InfoReliability.defaultValues, myRoot, null, true).run(); - } - } - } - - public void setAll(boolean all) { - myAll = all; + preloadBranches(resolveAllBranchPoints()); } } - public void loadState(final ConfigurationBean object) { - final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject)); - final Map map = object.myConfigurationMap; - final Map newMap = new HashMap(map.size(), 1); + @NotNull + private Set> resolveAllBranchPoints() { final LocalFileSystem lfs = LocalFileSystem.getInstance(); - - final Set> whatToInit = new HashSet>(); - for (Map.Entry entry : map.entrySet()) { + final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject)); + final Set> branchPointsToLoad = ContainerUtil.newHashSet(); + for (Map.Entry entry : myConfigurationBean.myConfigurationMap.entrySet()) { final SvnBranchConfiguration configuration = entry.getValue(); final VirtualFile root = lfs.refreshAndFindFileByIoFile(new File(entry.getKey())); if (root == null) { @@ -222,22 +185,24 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent>(stored, InfoReliability.setByUser)); } else { - whatToInit.add(Pair.create(root, newConfig)); + branchPointsToLoad.add(Pair.create(root, newConfig)); newConfig.addBranches(branchUrl, new InfoStorage>(new ArrayList(), InfoReliability.empty)); } } - myBunch.updateForRoot(root, new InfoStorage(newConfig, InfoReliability.setByUser), null); + myBunch.updateForRoot(root, new InfoStorage(newConfig, InfoReliability.setByUser), false); } + return branchPointsToLoad; + } + + private void preloadBranches(@NotNull final Collection> branchPoints) { ((ProjectLevelVcsManagerImpl) myVcsManager).addInitializationRequest(VcsInitObject.BRANCHES, new Runnable() { public void run() { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { public void run() { try { - for (Pair pair : whatToInit) { - final BranchesPreloader branchesPreloader = new BranchesPreloader(myProject, myBunch, pair.getFirst(), myBranchesLoader); - branchesPreloader.setAll(true); - branchesPreloader.loadImpl(null, pair.getSecond()); + for (Pair pair : branchPoints) { + myBunch.reloadBranches(pair.getFirst(), null, pair.getSecond()); } } catch (ProcessCanceledException e) { @@ -247,9 +212,6 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent getStored(String branchUrl) { @@ -259,93 +221,4 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent withUserInfo = new Ref(); - final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo); - - if (Boolean.FALSE.equals(withUserInfo.get())) { - return configuration; - } - - final List branches = configuration.getBranchUrls(); - final List newBranchesList = new ArrayList(branches.size()); - for (String s : branches) { - newBranchesList.add(serializeUrl(s, withUserInfo)); - } - - final SvnBranchConfiguration result = new SvnBranchConfiguration(); - result.setTrunkUrl(trunkUrl); - result.setBranchUrls(newBranchesList); - result.setUserinfoInUrl(withUserInfo.isNull() ? false : withUserInfo.get()); - return result; - } - - public SvnBranchConfiguration afterDeserialization(final String path, final SvnBranchConfiguration configuration) { - if (! configuration.isUserinfoInUrl()) { - return configuration; - } - final String userInfo = getUserInfo(path); - if (userInfo == null) { - return configuration; - } - - final String newTrunkUrl = deserializeUrl(configuration.getTrunkUrl(), userInfo); - final List branches = configuration.getBranchUrls(); - final List newBranchesList = new ArrayList(branches.size()); - for (String s : branches) { - newBranchesList.add(deserializeUrl(s, userInfo)); - } - - final SvnBranchConfiguration result = new SvnBranchConfiguration(); - result.setTrunkUrl(newTrunkUrl); - result.setBranchUrls(newBranchesList); - result.setUserinfoInUrl(userInfo != null && userInfo.length() > 0); - return result; - } - - private static String serializeUrl(final String url, final Ref withUserInfo) { - if (Boolean.FALSE.equals(withUserInfo.get())) { - return url; - } - try { - final SVNURL svnurl = SVNURL.parseURIEncoded(url); - if (withUserInfo.isNull()) { - final String userInfo = svnurl.getUserInfo(); - withUserInfo.set((userInfo != null) && (userInfo.length() > 0)); - } - if (withUserInfo.get()) { - return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), true) - .toString(); - } - } - catch (SVNException e) { - // - } - return url; - } - - @Nullable - private String getUserInfo(final String path) { - final SVNURL svnurl = myVcs.getSvnFileUrlMapping().getUrlForFile(new File(path)); - return svnurl != null ? svnurl.getUserInfo() : null; - } - - private static String deserializeUrl(final String url, final String userInfo) { - try { - final SVNURL svnurl = SVNURL.parseURIEncoded(url); - return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), - true).toString(); - } catch (SVNException e) { - return url; - } - } - } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java index 4102210a657a..3ce3c986c8ae 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java @@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.info.Info; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; @@ -98,7 +97,7 @@ public class SvnBranchConfigurationNew { LOG.info("Branches list not updated for : '" + branchParentName + "; since config has changed."); return; } - current.accept(items, null); + current.accept(items); } public Map>> getBranchMap() { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchItem.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchItem.java similarity index 97% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchItem.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchItem.java index f9e428d1becf..a0bd0868b6d2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchItem.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchItem.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn.integrate; +package org.jetbrains.idea.svn.branchConfig; import java.util.Date; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchMapperManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchMapperManager.java similarity index 75% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchMapperManager.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchMapperManager.java index e82e363f598a..f9f99bea1e17 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchMapperManager.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchMapperManager.java @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn; +package org.jetbrains.idea.svn.branchConfig; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.messages.Topic; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import java.io.File; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * Holds what working copies we have for URLs @@ -56,7 +56,6 @@ public class SvnBranchMapperManager implements PersistentStateComponent roots) { - ApplicationManager.getApplication().getMessageBus().syncPublisher(WC_ROOTS_CHANGED).rootsChanged(url, roots); } public void notifyBranchesChanged(final Project project, final VirtualFile vcsRoot, final SvnBranchConfigurationNew configuration) { @@ -104,11 +98,4 @@ public class SvnBranchMapperManager implements PersistentStateComponent roots); - } - - public static final Topic WC_ROOTS_CHANGED = - new Topic("SVN_WC_ROOTS_CHANGED", WcRootsChangeConsumer.class); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnLoadedBranchesStorage.java similarity index 94% rename from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java rename to plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnLoadedBranchesStorage.java index 8fe1fa52a938..76ae7cae3d7a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnLoadedBranchesStorage.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.svn; +package org.jetbrains.idea.svn.branchConfig; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.project.Project; @@ -23,9 +23,6 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.branchConfig.InfoStorage; -import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; import java.io.DataInput; import java.io.DataOutput; @@ -39,13 +36,13 @@ import java.util.*; * Date: 8/24/11 * Time: 1:21 PM */ -public class SvnLoadedBrachesStorage { +public class SvnLoadedBranchesStorage { private final Object myLock; private SmallMapSerializer>> myState; private final File myFile; private final Project myProject; - public SvnLoadedBrachesStorage(final Project project) { + public SvnLoadedBranchesStorage(final Project project) { myProject = project; final File vcsFile = new File(PathManager.getSystemPath(), "vcs"); File file = new File(vcsFile, "svn_branches"); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/UrlSerializationHelper.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/UrlSerializationHelper.java new file mode 100644 index 000000000000..36c16f33a0fc --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/UrlSerializationHelper.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn.branchConfig; + +import com.intellij.openapi.util.Ref; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.SvnUtil; +import org.jetbrains.idea.svn.SvnVcs; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** +* @author Konstantin Kolosovsky. +*/ +public class UrlSerializationHelper { + private final SvnVcs myVcs; + + public UrlSerializationHelper(final SvnVcs vcs) { + myVcs = vcs; + } + + public SvnBranchConfiguration prepareForSerialization(final SvnBranchConfiguration configuration) { + final Ref withUserInfo = new Ref(); + final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo); + + if (Boolean.FALSE.equals(withUserInfo.get())) { + return configuration; + } + + final List branches = configuration.getBranchUrls(); + final List newBranchesList = new ArrayList(branches.size()); + for (String s : branches) { + newBranchesList.add(serializeUrl(s, withUserInfo)); + } + + return new SvnBranchConfiguration(trunkUrl, newBranchesList, withUserInfo.isNull() ? false : withUserInfo.get()); + } + + public SvnBranchConfiguration afterDeserialization(final String path, final SvnBranchConfiguration configuration) { + if (! configuration.isUserinfoInUrl()) { + return configuration; + } + final String userInfo = getUserInfo(path); + if (userInfo == null) { + return configuration; + } + + final String newTrunkUrl = deserializeUrl(configuration.getTrunkUrl(), userInfo); + final List branches = configuration.getBranchUrls(); + final List newBranchesList = new ArrayList(branches.size()); + for (String s : branches) { + newBranchesList.add(deserializeUrl(s, userInfo)); + } + + return new SvnBranchConfiguration(newTrunkUrl, newBranchesList, userInfo.length() > 0); + } + + private static String serializeUrl(final String url, final Ref withUserInfo) { + if (Boolean.FALSE.equals(withUserInfo.get())) { + return url; + } + try { + final SVNURL svnurl = SVNURL.parseURIEncoded(url); + if (withUserInfo.isNull()) { + final String userInfo = svnurl.getUserInfo(); + withUserInfo.set((userInfo != null) && (userInfo.length() > 0)); + } + if (withUserInfo.get()) { + return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), true) + .toString(); + } + } + catch (SVNException e) { + // + } + return url; + } + + @Nullable + private String getUserInfo(final String path) { + final SVNURL svnurl = myVcs.getSvnFileUrlMapping().getUrlForFile(new File(path)); + return svnurl != null ? svnurl.getUserInfo() : null; + } + + private static String deserializeUrl(final String url, final String userInfo) { + try { + final SVNURL svnurl = SVNURL.parseURIEncoded(url); + return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), + true).toString(); + } catch (SVNException e) { + return url; + } + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index c9a843501253..3f43d7452b5e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -124,7 +124,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { String comment, List exception, final Set feedback, - final WorkingCopyFormat format) + @NotNull WorkingCopyFormat format) throws VcsException { if (committables.isEmpty()) { return; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java index 9ca5b89d517a..1b48f9d70e5b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java @@ -45,7 +45,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; import org.jetbrains.idea.svn.actions.CleanupWorker; -import org.jetbrains.idea.svn.actions.SelectBranchPopup; +import org.jetbrains.idea.svn.branchConfig.BranchConfigurationDialog; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.api.ClientFactory; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java index cd504be56077..437e7f57e464 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java @@ -41,7 +41,6 @@ import org.jetbrains.idea.svn.properties.PropertyConsumer; import org.jetbrains.idea.svn.properties.PropertyData; import org.jetbrains.idea.svn.properties.PropertyValue; import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -309,7 +308,7 @@ public class PropertiesComponent extends JPanel { PropertyValue propValue = null; try { propValue = myVcs.getFactory(myFile).createPropertyClient() - .getProperty(SvnTarget.fromFile(myFile), SVNProperty.KEYWORDS, false, SVNRevision.WORKING); + .getProperty(SvnTarget.fromFile(myFile), SvnPropertyKeys.SVN_KEYWORDS, false, SVNRevision.WORKING); } catch (VcsException e1) { // show erorr message diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CompareWithBranchAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CompareWithBranchAction.java index a8e0ca9e5e7a..278c7d0b5e1c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CompareWithBranchAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CompareWithBranchAction.java @@ -26,7 +26,7 @@ import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.*; -import org.jetbrains.idea.svn.actions.SelectBranchPopup; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; /** diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java index 83642894711e..4712a080ad36 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java @@ -48,7 +48,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.actions.ConfigureBranchesAction; +import org.jetbrains.idea.svn.branchConfig.ConfigureBranchesAction; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.commandLine.SvnBindException; import org.jetbrains.idea.svn.status.Status; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java index c6ed3c59a5c7..d4b48281f7ca 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java @@ -24,10 +24,10 @@ import com.intellij.util.NullableFunction; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.SvnBranchMapperManager; +import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnUtil; -import org.jetbrains.idea.svn.actions.SelectBranchPopup; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches; import org.jetbrains.idea.svn.integrate.IntegratedSelectedOptionsDialog; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java index e0ab6ff02ae5..bbac377776b8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java @@ -23,10 +23,11 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; +import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.dialogs.WCInfo; import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; +import org.jetbrains.idea.svn.branchConfig.SvnBranchItem; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import java.io.File; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/info/Info.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/info/Info.java index 96dbdbbcbc99..2162faa45906 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/info/Info.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/info/Info.java @@ -35,6 +35,8 @@ import java.util.Date; */ public class Info extends BaseNodeDescription { + public static final String SCHEDULE_ADD = "add"; + private final File myFile; private final String myPath; private final SVNURL myURL; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java index 3b2184c22484..7ff6e71ab75a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java @@ -32,6 +32,7 @@ import com.intellij.util.PlatformIcons; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; +import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager; import org.jetbrains.idea.svn.info.Info; import org.tmatesoft.svn.core.SVNURL; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SourceUrlCorrectionTask.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SourceUrlCorrectionTask.java index 39d51de62943..99d4696ede3f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SourceUrlCorrectionTask.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SourceUrlCorrectionTask.java @@ -18,7 +18,7 @@ package org.jetbrains.idea.svn.integrate; import com.intellij.util.continuation.ContinuationContext; import com.intellij.util.continuation.Where; import org.jetbrains.annotations.NotNull; -import org.jetbrains.idea.svn.SvnBranchConfigurationManager; +import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager; import org.jetbrains.idea.svn.dialogs.MergeContext; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesActionPerformer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesActionPerformer.java index e07fac011c9e..2ccd2242db10 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesActionPerformer.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesActionPerformer.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnConfiguration; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.actions.SelectBranchPopup; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java index 5dd6f24b10ba..0dd27d442ae5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java @@ -19,7 +19,9 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; @@ -28,6 +30,7 @@ import com.intellij.openapi.vcs.changes.InvokeAfterUpdateMode; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vcs.update.*; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; @@ -330,18 +333,37 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable { }); } - final SvnChangeProvider provider = new SvnChangeProvider(myVcs); - final GatheringChangelistBuilder clb = new GatheringChangelistBuilder(myVcs, myAccomulatedFiles); - try { - provider.getChanges(dirtyScope, clb, ProgressManager.getInstance().getProgressIndicator(), null); - } catch (VcsException e) { - Messages.showErrorDialog(SvnBundle.message("action.Subversion.integrate.changes.error.unable.to.collect.changes.text", - e.getMessage()), myTitle); - return; - } + new Task.Backgroundable(myVcs.getProject(), + SvnBundle.message("action.Subversion.integrate.changes.collecting.changes.to.commit.task.title")) { - if (! clb.getChanges().isEmpty()) { - CommitChangeListDialog.commitAlienChanges(myProject, clb.getChanges(), myVcs, myMerger.getComment(), myMerger.getComment()); - } + private final GatheringChangelistBuilder changesBuilder = new GatheringChangelistBuilder(myVcs, myAccomulatedFiles); + private final Ref caughtError = new Ref(); + + @Override + public void run(@NotNull ProgressIndicator indicator) { + indicator.setIndeterminate(true); + if (!myVcs.getProject().isDisposed()) { + final SvnChangeProvider provider = new SvnChangeProvider(myVcs); + + try { + provider.getChanges(dirtyScope, changesBuilder, indicator, null); + } + catch (VcsException e) { + caughtError.set(SvnBundle.message("action.Subversion.integrate.changes.error.unable.to.collect.changes.text", e.getMessage())); + } + } + } + + @Override + public void onSuccess() { + if (!caughtError.isNull()) { + VcsBalloonProblemNotifier.showOverVersionControlView(myVcs.getProject(), caughtError.get(), MessageType.ERROR); + } + else if (!changesBuilder.getChanges().isEmpty()) { + CommitChangeListDialog + .commitAlienChanges(myProject, changesBuilder.getChanges(), myVcs, myMerger.getComment(), myMerger.getComment()); + } + } + }.queue(); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java index 701bb2575001..f69aac4a4133 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java @@ -19,11 +19,15 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.VcsException; import com.intellij.util.containers.MultiMap; +import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.history.SvnChangeList; import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.properties.PropertyValue; -import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNMergeRange; +import org.tmatesoft.svn.core.SVNMergeRangeList; +import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNMergeInfoUtil; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -209,7 +213,8 @@ public class BranchInfo { SvnTarget target = SvnTarget.fromURL(branchUrl); try { - mergeinfoProperty = myVcs.getFactory(target).createPropertyClient().getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.create(targetRevision)); + mergeinfoProperty = myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, + SVNRevision.create(targetRevision)); } catch (VcsException e) { LOG.info(e); @@ -283,13 +288,13 @@ public class BranchInfo { // look in WC SvnTarget target = SvnTarget.fromFile(pathFile, SVNRevision.WORKING); mergeinfoProperty = - myVcs.getFactory(target).createPropertyClient().getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.WORKING); + myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.WORKING); } else { // in repo myMixedRevisionsFound = true; SvnTarget target = SvnTarget.fromURL(svnInfo.getURL()); mergeinfoProperty = myVcs.getFactory(target).createPropertyClient() - .getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.create(targetRevisionCorrected)); + .getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.create(targetRevisionCorrected)); } } catch (VcsException e) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java index 225bc6ad0396..b17d3317a801 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java @@ -21,12 +21,16 @@ import com.intellij.openapi.vcs.AreaMap; import com.intellij.openapi.vcs.VcsException; import com.intellij.util.PairProcessor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.dialogs.MergeContext; import org.jetbrains.idea.svn.properties.PropertyConsumer; import org.jetbrains.idea.svn.properties.PropertyData; import org.jetbrains.idea.svn.properties.PropertyValue; -import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNMergeRange; +import org.tmatesoft.svn.core.SVNMergeRangeList; +import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNMergeInfoUtil; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -83,7 +87,7 @@ public class OneRecursiveShotMergeInfoWorker implements MergeInfoWorker { File path = new File(myMergeContext.getWcInfo().getPath()); myMergeContext.getVcs().getFactory(path).createPropertyClient() - .getProperty(SvnTarget.fromFile(path), SVNProperty.MERGE_INFO, SVNRevision.WORKING, depth, handler); + .getProperty(SvnTarget.fromFile(path), SvnPropertyKeys.MERGE_INFO, SVNRevision.WORKING, depth, handler); } public SvnMergeInfoCache.MergeCheckResult isMerged(final String relativeToRepoURLPath, final long revisionNumber) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java index e053776d14ce..f00c4bd7341d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java @@ -1,5 +1,7 @@ package org.jetbrains.idea.svn.properties; +import com.intellij.openapi.diagnostic.Attachment; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +32,8 @@ import java.util.Map; */ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { + private static final Logger LOG = Logger.getInstance(CmdPropertyClient.class); + @Nullable @Override public PropertyValue getProperty(@NotNull SvnTarget target, @@ -57,7 +61,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { parameters.add("--xml"); CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null); - PropertyData data = parseSingleProperty(target, command.getOutput()); + PropertyData data = parseSingleProperty(target, command); return data != null ? data.getValue() : null; } @@ -74,7 +78,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { fillListParameters(target, revision, depth, parameters, false); CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null); - parseOutput(target, command.getOutput(), handler); + parseOutput(target, command, handler); } @Override @@ -86,7 +90,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { fillListParameters(target, revision, depth, parameters, true); CommandExecutor command = execute(myVcs, target, SvnCommandName.proplist, parameters, null); - parseOutput(target, command.getOutput(), handler); + parseOutput(target, command, handler); } @Override @@ -183,7 +187,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } @Nullable - private PropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException { + private PropertyData parseSingleProperty(SvnTarget target, @NotNull CommandExecutor command) throws VcsException { final PropertyData[] data = new PropertyData[1]; PropertyConsumer handler = new PropertyConsumer() { @Override @@ -202,14 +206,14 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } }; - parseOutput(target, output, handler); + parseOutput(target, command, handler); return data[0]; } - private static void parseOutput(SvnTarget target, String output, PropertyConsumer handler) throws VcsException { + private static void parseOutput(SvnTarget target, @NotNull CommandExecutor command, PropertyConsumer handler) throws VcsException { try { - Properties properties = CommandUtil.parse(output, Properties.class); + Properties properties = CommandUtil.parse(command.getOutput(), Properties.class); if (properties != null) { for (Target childInfo : properties.targets) { @@ -227,6 +231,8 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } } catch (JAXBException e) { + LOG.error("Could not parse properties. Command: " + command.getCommandText() + ", Warning: " + command.getErrorOutput(), + new Attachment("output.xml", command.getOutput())); throw new VcsException(e); } catch (SVNException e) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java index 7b09461b3766..16904b673b5f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java @@ -37,8 +37,10 @@ import org.jetbrains.idea.svn.info.Info; import org.jetbrains.idea.svn.properties.PropertiesMap; import org.jetbrains.idea.svn.properties.PropertyConsumer; import org.jetbrains.idea.svn.properties.PropertyData; -import org.tmatesoft.svn.core.*; -import org.tmatesoft.svn.core.wc.*; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; @@ -312,7 +314,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment { if (info.isFile()) { doRevert(file, false); } else { - if (SVNProperty.SCHEDULE_ADD.equals(info.getSchedule())) { + if (Info.SCHEDULE_ADD.equals(info.getSchedule())) { doRevert(file, true); } else { boolean is17OrGreater = is17OrGreaterCopy(file, info); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/status/CmdStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/status/CmdStatusClient.java index 4030c83005ea..8100d73da220 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/status/CmdStatusClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/status/CmdStatusClient.java @@ -103,6 +103,7 @@ public class CmdStatusClient extends BaseSvnClient implements StatusClient { // so it does not contain any element and current parsing logic returns null PortableStatus status = new PortableStatus(); + status.setFile(path); status.setPath(path.getAbsolutePath()); status.setContentsStatus(StatusType.STATUS_NORMAL); status.setInfoGetter(new Getter() { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java index b4e788c75260..42bc3890e1d0 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java @@ -145,6 +145,7 @@ public abstract class AbstractSvnUpdateIntegrateEnvironment implements UpdateEnv } public void onRefreshFilesCompleted() { + // TODO: why do we need to mark all roots as dirty here??? dirtyRoots(); for (Runnable groupWorker : myGroupWorkers) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateRootOptionsPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateRootOptionsPanel.java index d232fdc3037f..9103c845ae75 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateRootOptionsPanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateRootOptionsPanel.java @@ -22,7 +22,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.vcs.FilePath; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; -import org.jetbrains.idea.svn.actions.SelectBranchPopup; +import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.dialogs.SelectLocationDialog; import org.jetbrains.idea.svn.history.SvnChangeList; diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnQuickMergeTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnQuickMergeTest.java index 6853141b8d45..a663e13d3b29 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnQuickMergeTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnQuickMergeTest.java @@ -36,9 +36,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.SvnTestCase; import org.jetbrains.idea.svn.branchConfig.InfoReliability; import org.jetbrains.idea.svn.branchConfig.InfoStorage; +import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; import org.jetbrains.idea.svn.dialogs.*; -import org.jetbrains.idea.svn.integrate.SvnBranchItem; +import org.jetbrains.idea.svn.branchConfig.SvnBranchItem; import org.jetbrains.idea.svn.mergeinfo.MergeChecker; import org.junit.Before; import org.junit.Test;