summaryrefslogtreecommitdiff
path: root/plugins/svn4idea/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/svn4idea/src/org')
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java94
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java11
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java18
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java10
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.form (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.form)2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java)12
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java64
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/ConfigureBranchesAction.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java)4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagAction.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateBranchOrTagAction.java)4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.form (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.form)2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/CreateBranchOrTagDialog.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java)5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultBranchConfigInitializer.java155
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java113
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/InfoStorage.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java186
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SelectBranchPopup.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SelectBranchPopup.java)18
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigManager.java47
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfiguration.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfiguration.java)21
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationManager.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfigurationManager.java)207
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchItem.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchItem.java)2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchMapperManager.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchMapperManager.java)23
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnLoadedBranchesStorage.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java)28
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/UrlSerializationHelper.java111
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java103
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CompareWithBranchAction.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/LoadedRevisionsCache.java30
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java47
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/info/Info.java38
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SourceUrlCorrectionTask.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesActionPerformer.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java46
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java13
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java8
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java20
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java8
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/status/CmdStatusClient.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateRootOptionsPanel.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateEventHandler.java35
58 files changed, 796 insertions, 780 deletions
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
index 06138b345b74..c33dd38f2eba 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
@@ -105,7 +105,7 @@ public class RootsToWorkingCopies implements VcsListener {
@CalledInBackground
@Nullable
- public WorkingCopy getWcRoot(final VirtualFile root) {
+ public WorkingCopy getWcRoot(@NotNull VirtualFile root) {
assert (! ApplicationManager.getApplication().isDispatchThread()) || ApplicationManager.getApplication().isUnitTestMode();
synchronized (myLock) {
@@ -117,7 +117,7 @@ public class RootsToWorkingCopies implements VcsListener {
}
@Nullable
- private WorkingCopy calculateRoot(final VirtualFile root) {
+ private WorkingCopy calculateRoot(@NotNull VirtualFile root) {
File workingCopyRoot = SvnUtil.getWorkingCopyRootNew(new File(root.getPath()));
WorkingCopy workingCopy = null;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
index df545b0373a1..3f4ae40677ae 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
@@ -526,6 +526,7 @@ action.Subversion.integrate.changes.alien.commit.changelist.title=Integrated
action.Subversion.integrate.changes.dialog.add.wc.text=Add
action.Subversion.integrate.changes.dialog.remove.wc.text=Remove
action.Subversion.integrate.changes.message.files.up.to.date.text=All files are up to date
+action.Subversion.integrate.changes.collecting.changes.to.commit.task.title=Collecting changes to commit
action.Subversion.integrate.changes.error.unable.to.collect.changes.text=Error while collecting changes to commit: {0}
error.cannot.load.revisions=Can not load revision list
action.Subversion.integrate.changes.message.canceled.text=Integration was canceled
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
index 9ae90c722cb3..1fc5f9ce075a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
@@ -27,6 +27,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
+import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.lock.Lock;
import org.jetbrains.idea.svn.status.Status;
@@ -244,7 +245,13 @@ class SvnChangeProviderContext implements StatusReceiver {
myChangelistBuilder.processLocallyDeletedFile(createLocallyDeletedChange(filePath, status));
}
else if (status.is(StatusType.STATUS_IGNORED)) {
- if (!myVcs.isWcRoot(filePath)) {
+ if (filePath.getVirtualFile() == null) {
+ filePath.hardRefresh();
+ }
+ if (filePath.getVirtualFile() == null) {
+ LOG.error("No virtual file for ignored file: " + filePath.getPresentableUrl() + ", isNonLocal: " + filePath.isNonLocal());
+ }
+ else if (!myVcs.isWcRoot(filePath)) {
myChangelistBuilder.processIgnoredFile(filePath.getVirtualFile());
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
index 6f5013c4a929..9d8df6591268 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
@@ -30,6 +30,7 @@ import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.auth.SvnAuthenticationManager;
import org.jetbrains.idea.svn.auth.SvnAuthenticationProvider;
import org.jetbrains.idea.svn.auth.SvnInteractiveAuthenticationProvider;
+import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.config.SvnServerFileKeys;
import org.jetbrains.idea.svn.diff.DiffOptions;
import org.jetbrains.idea.svn.update.MergeRootInfo;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
index 11838314acbd..5c660643dc66 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
@@ -221,11 +221,16 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
}
public void realRefresh(final Runnable afterRefreshCallback) {
- final SvnVcs vcs = SvnVcs.getInstance(myProject);
- final VirtualFile[] roots = myHelper.executeDefended(myProject);
- final SvnRootsDetector rootsDetector = new SvnRootsDetector(vcs, this, myNestedCopiesHolder);
- // do not send additional request for nested copies when in init state
- rootsDetector.detectCopyRoots(roots, init(), afterRefreshCallback);
+ if (myProject.isDisposed()) {
+ afterRefreshCallback.run();
+ }
+ else {
+ final SvnVcs vcs = SvnVcs.getInstance(myProject);
+ final VirtualFile[] roots = myHelper.executeDefended(myProject);
+ final SvnRootsDetector rootsDetector = new SvnRootsDetector(vcs, this, myNestedCopiesHolder);
+ // do not send additional request for nested copies when in init state
+ rootsDetector.detectCopyRoots(roots, init(), afterRefreshCallback);
+ }
}
public void applyDetectionResult(@NotNull SvnRootsDetector.Result result) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java
index a5612a69172a..d4c98221a567 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java
@@ -19,22 +19,25 @@ import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.changes.VcsDirtyScope;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class SvnScopeZipper implements Runnable {
- private final VcsDirtyScope myIn;
- private final List<FilePath> myRecursiveDirs;
+
+ @NotNull private final VcsDirtyScope myIn;
+ @NotNull private final List<FilePath> myRecursiveDirs;
// instead of set and heavy equals of file path
- private final Map<String, MyDirNonRecursive> myNonRecursiveDirs;
- // those alone in their immediate parent
- private final List<FilePath> mySingleFiles;
+ @NotNull private final Map<String, MyDirNonRecursive> myNonRecursiveDirs;
- public SvnScopeZipper(final VcsDirtyScope in) {
+ public SvnScopeZipper(@NotNull VcsDirtyScope in) {
myIn = in;
- myRecursiveDirs = new ArrayList<FilePath>(in.getRecursivelyDirtyDirectories());
- myNonRecursiveDirs = new HashMap<String, MyDirNonRecursive>();
- mySingleFiles = new ArrayList<FilePath>();
+ 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<Map.Entry<String, MyDirNonRecursive>> iterator = myNonRecursiveDirs.entrySet().iterator(); iterator.hasNext();) {
- final Map.Entry<String, MyDirNonRecursive> 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<FilePath> getRecursiveDirs() {
return myRecursiveDirs;
}
+ @NotNull
public Map<String, MyDirNonRecursive> getNonRecursiveDirs() {
return myNonRecursiveDirs;
}
- public List<FilePath> 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<String, FilePath> myChildren;
+ @NotNull private final Map<String, FilePath> myChildren;
- private MyDirNonRecursive(final FilePath dir) {
+ private MyDirNonRecursive(@NotNull FilePath dir) {
myDir = dir;
- myChildren = new HashMap<String, FilePath>();
- }
-
- public boolean isInterestedInParent() {
- return myInterestedInParent;
- }
-
- public void setInterestedInParent(boolean interestedInParent) {
- myInterestedInParent = interestedInParent;
+ myChildren = ContainerUtil.newHashMap();
}
- public void add(final FilePath path) {
+ public void add(@NotNull FilePath path) {
myChildren.put(getKey(path), path);
}
+ @NotNull
public Collection<FilePath> 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<SVNURL, WorkingCopyFormat>(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<CommittedChangeList> {
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<CommittedChangeList> {
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<CommittedChangeList> {
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<CommittedChangeList> {
}
@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/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
index a615fd4e3afa..e40569d720de 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
@@ -70,7 +70,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
if (! svnRevision.isValid()) {
throw new VcsException("Can not get last changed revision for file: " + file.getPath() + "\nPlease run svn info for this file and file an issue.");
}
- return annotate(file, new SvnFileRevision(myVcs, currentRevision, currentRevision, null, null, null, null, null, file.getCharset()),
+ return annotate(file, new SvnFileRevision(myVcs, currentRevision, currentRevision, null, null, null, null, null),
lastChangedRevision.getRevisionNumber(), true);
}
@@ -438,7 +438,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
myProgress.checkCanceled();
myProgress.setText2(SvnBundle.message("progress.text2.revision.processed", logEntry.getRevision()));
}
- myResult.setRevision(logEntry.getRevision(), new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, myUrl, "", myCharset));
+ myResult.setRevision(logEntry.getRevision(), new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, myUrl, ""));
}
});
}
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<SvnAuthentica
/**
* Bases on presence of notifications!
*/
- public ThreeState isAuthenticatedFor(final VirtualFile vf) {
+ public ThreeState isAuthenticatedFor(@NotNull VirtualFile vf) {
final WorkingCopy wcCopy = myRootsToWorkingCopies.getWcRoot(vf);
if (wcCopy == null) return ThreeState.UNSURE;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.form
index a416aa145505..b68010c827db 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchConfigurationDialog.form
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.branchConfig.BranchConfigurationDialog">
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java b/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<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), 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;
+
+ 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;
+ }
- private BranchesLoader() {
+ public void run() {
+ try {
+ List<SvnBranchItem> branches = loadBranches();
+ myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(branches, myInfoReliability));
+ }
+ catch (VcsException e) {
+ showError(e);
+ }
+ catch (SVNException e) {
+ showError(e);
+ }
}
- public static List<SvnBranchItem> 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);
+ @NotNull
+ public List<SvnBranchItem> loadBranches() throws SVNException, VcsException {
+ final SvnConfiguration configuration = SvnConfiguration.getInstance(myProject);
+ final SvnVcs vcs = SvnVcs.getInstance(myProject);
+ SVNURL branchesUrl = SVNURL.parseURIEncoded(myUrl);
List<SvnBranchItem> result = new LinkedList<SvnBranchItem>();
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<SvnBranchItem> 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
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
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
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.dialogs.CreateBranchOrTagDialog">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.branchConfig.CreateBranchOrTagDialog">
<grid id="9287c" binding="myTopPanel" layout-manager="GridBagLayout">
<constraints>
<xy x="10" y="10" width="561" height="502"/>
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java b/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<SvnBranchConfigurationNew>(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<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(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<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(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<T> {
public T myT;
public InfoReliability myInfoReliability;
@@ -27,14 +24,15 @@ public class InfoStorage<T> {
myInfoReliability = infoReliability;
}
- public void accept(final InfoStorage<T> infoStorage, @Nullable final PairConsumer<T, T> callbackOnUpdate) {
- if (infoStorage.myInfoReliability.shouldOverride(myInfoReliability)) {
- if (callbackOnUpdate != null) {
- callbackOnUpdate.consume(myT, infoStorage.myT);
- }
+ public boolean accept(final InfoStorage<T> 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<VirtualFile, InfoStorage<SvnBranchConfigurationNew>>();
}
- public void updateForRoot(@NotNull final VirtualFile root, @NotNull final InfoStorage<SvnBranchConfigurationNew> config,
- @Nullable final PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> callbackOnUpdate) {
+ public void updateForRoot(@NotNull final VirtualFile root,
+ @NotNull final InfoStorage<SvnBranchConfigurationNew> config,
+ boolean reload) {
synchronized (myLock) {
+ final SvnBranchConfigurationNew previous;
+ boolean override;
final InfoStorage<SvnBranchConfigurationNew> 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<SvnBranchConfigurationNew>(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<List<SvnBranchItem>> 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<String> oldUrls = (prev == null) ? Collections.<String>emptySet() : new HashSet<String>(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<List<SvnBranchItem>>() {
- public void consume(List<SvnBranchItem> 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<List<SvnBranchItem>> 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<List<SvnBranchItem>> 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<SvnBranchItem> items = BranchesLoader.loadBranches(myProject, myUrl, myPassive);
- myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(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<SvnBranchConfigurationNew>(result, InfoReliability.defaultValues), null);
- }
- }
- }
-
public Map<VirtualFile, SvnBranchConfigurationNew> getMapCopy() {
synchronized (myLock) {
final Map<VirtualFile, SvnBranchConfigurationNew> result = new HashMap<VirtualFile, SvnBranchConfigurationNew>();
@@ -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
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<SvnBranchConfigurationNew> config,
- @Nullable final PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> callbackOnUpdate);
-
- void updateBranches(@NotNull VirtualFile root, @NotNull String branchesParent,
- @NotNull InfoStorage<List<SvnBranchItem>> items);
-
- @NotNull
- SvnBranchConfigurationNew getConfig(@NotNull VirtualFile root);
-
- void reloadBranches(@NotNull VirtualFile root, @NotNull String branchParentUrl,
- Consumer<List<SvnBranchItem>> callback);
- @Nullable
- @CalledInBackground
- SVNURL getWorkingBranchWithReload(final SVNURL svnurl, final VirtualFile root);
-
- Map<VirtualFile, SvnBranchConfigurationNew> getMapCopy();
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBranchConfiguration.java b/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<String> myBranchUrls;
+ @NotNull private List<String> myBranchUrls;
private boolean myUserinfoInUrl;
public SvnBranchConfiguration() {
myBranchUrls = new ArrayList<String>();
}
+ public SvnBranchConfiguration(String trunkUrl, @NotNull List<String> 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<String> branchUrls) {
+
+ public void setBranchUrls(@NotNull List<String> branchUrls) {
myBranchUrls = branchUrls;
Collections.sort(myBranchUrls);
}
@@ -53,6 +65,7 @@ public class SvnBranchConfiguration {
return myTrunkUrl;
}
+ @NotNull
public List<String> 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
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<SvnBranchConfigurationManager.ConfigurationBean> {
- 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<S
}
public static SvnBranchConfigurationManager getInstance(final Project project) {
- return PeriodicalTasksCloser.getInstance().safeGetService(project, SvnBranchConfigurationManager.class);
+ SvnBranchConfigurationManager result = PeriodicalTasksCloser.getInstance().safeGetService(project, SvnBranchConfigurationManager.class);
+
+ if (result != null) {
+ result.initialize();
+ }
+
+ return result;
}
public static class ConfigurationBean {
@@ -108,19 +110,18 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
}
private ConfigurationBean myConfigurationBean = new ConfigurationBean();
- private final SvnBranchConfigManager myBunch;
+ private final NewRootBunch myBunch;
public SvnBranchConfigurationNew get(@NotNull final VirtualFile vcsRoot) throws VcsException {
return myBunch.getConfig(vcsRoot);
}
- public SvnBranchConfigManager getSvnBranchConfigManager() {
+ public NewRootBunch getSvnBranchConfigManager() {
return myBunch;
}
public void setConfiguration(final VirtualFile vcsRoot, final SvnBranchConfigurationNew configuration) {
- myBunch.updateForRoot(vcsRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.setByUser),
- new BranchesPreloader(myProject, myBunch, vcsRoot, myBranchesLoader));
+ myBunch.updateForRoot(vcsRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.setByUser), true);
SvnBranchMapperManager.getInstance().notifyBranchesChanged(myProject, vcsRoot, configuration);
@@ -136,71 +137,33 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
for (VirtualFile root : myBunch.getMapCopy().keySet()) {
final String key = root.getPath();
final SvnBranchConfigurationNew configOrig = myBunch.getConfig(root);
- final SvnBranchConfiguration configuration = new SvnBranchConfiguration();
- configuration.setTrunkUrl(configOrig.getTrunkUrl());
- configuration.setUserinfoInUrl(configOrig.isUserinfoInUrl());
- configuration.setBranchUrls(configOrig.getBranchUrls());
- final HashMap<String, List<SvnBranchItem>> map = new HashMap<String, List<SvnBranchItem>>();
- final Map<String, InfoStorage<List<SvnBranchItem>>> 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<SvnBranchConfigurationNew, SvnBranchConfigurationNew> {
- 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<String> oldUrls = (prev == null) ? Collections.<String>emptySet() : new HashSet<String>(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<String, SvnBranchConfiguration> map = object.myConfigurationMap;
- final Map<String, SvnBranchConfiguration> newMap = new HashMap<String, SvnBranchConfiguration>(map.size(), 1);
+ @NotNull
+ private Set<Pair<VirtualFile, SvnBranchConfigurationNew>> resolveAllBranchPoints() {
final LocalFileSystem lfs = LocalFileSystem.getInstance();
-
- final Set<Pair<VirtualFile, SvnBranchConfigurationNew>> whatToInit = new HashSet<Pair<VirtualFile, SvnBranchConfigurationNew>>();
- for (Map.Entry<String, SvnBranchConfiguration> entry : map.entrySet()) {
+ final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject));
+ final Set<Pair<VirtualFile, SvnBranchConfigurationNew>> branchPointsToLoad = ContainerUtil.newHashSet();
+ for (Map.Entry<String, SvnBranchConfiguration> 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<S
if (stored != null && ! stored.isEmpty()) {
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(stored, InfoReliability.setByUser));
} else {
- whatToInit.add(Pair.create(root, newConfig));
+ branchPointsToLoad.add(Pair.create(root, newConfig));
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
}
}
- myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), null);
+ myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), false);
}
+ return branchPointsToLoad;
+ }
+
+ private void preloadBranches(@NotNull final Collection<Pair<VirtualFile, SvnBranchConfigurationNew>> branchPoints) {
((ProjectLevelVcsManagerImpl) myVcsManager).addInitializationRequest(VcsInitObject.BRANCHES, new Runnable() {
public void run() {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
try {
- for (Pair<VirtualFile, SvnBranchConfigurationNew> pair : whatToInit) {
- final BranchesPreloader branchesPreloader = new BranchesPreloader(myProject, myBunch, pair.getFirst(), myBranchesLoader);
- branchesPreloader.setAll(true);
- branchesPreloader.loadImpl(null, pair.getSecond());
+ for (Pair<VirtualFile, SvnBranchConfigurationNew> pair : branchPoints) {
+ myBunch.reloadBranches(pair.getFirst(), null, pair.getSecond());
}
}
catch (ProcessCanceledException e) {
@@ -247,9 +212,6 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
});
}
});
- object.myConfigurationMap.clear();
- object.myConfigurationMap.putAll(newMap);
- myConfigurationBean = object;
}
private List<SvnBranchItem> getStored(String branchUrl) {
@@ -259,93 +221,4 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
Collections.sort(items);
return items;
}
-
- private static class UrlSerializationHelper {
- private final SvnVcs myVcs;
-
- private UrlSerializationHelper(final SvnVcs vcs) {
- myVcs = vcs;
- }
-
- public SvnBranchConfiguration prepareForSerialization(final SvnBranchConfiguration configuration) {
- final Ref<Boolean> withUserInfo = new Ref<Boolean>();
- final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo);
-
- if (Boolean.FALSE.equals(withUserInfo.get())) {
- return configuration;
- }
-
- final List<String> branches = configuration.getBranchUrls();
- final List<String> newBranchesList = new ArrayList<String>(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<String> branches = configuration.getBranchUrls();
- final List<String> newBranchesList = new ArrayList<String>(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<Boolean> 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<String, InfoStorage<List<SvnBranchItem>>> 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
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
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<SvnBranc
public void put(final String url, final String value) {
myStateHolder.put(url, value);
- notifyWcRootsChanged(url, Collections.unmodifiableCollection(myStateHolder.get(url)));
}
public void remove(final String url, final File value) {
@@ -64,11 +63,6 @@ public class SvnBranchMapperManager implements PersistentStateComponent<SvnBranc
if (set != null) {
set.remove(value.getAbsolutePath());
}
- notifyWcRootsChanged(url, Collections.unmodifiableCollection(set));
- }
-
- private static void notifyWcRootsChanged(final String url, final Collection<String> 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<SvnBranc
return myMapping.get(key);
}
}
-
- public static interface WcRootsChangeConsumer {
- void rootsChanged(final String url, final Collection<String> roots);
- }
-
- public static final Topic<WcRootsChangeConsumer> WC_ROOTS_CHANGED =
- new Topic<WcRootsChangeConsumer>("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
index 8fe1fa52a938..041e33cc5ac7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnLoadedBranchesStorage.java
@@ -13,19 +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.PathManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.persistent.SmallMapSerializer;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
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 +37,13 @@ import java.util.*;
* Date: 8/24/11
* Time: 1:21 PM
*/
-public class SvnLoadedBrachesStorage {
+public class SvnLoadedBranchesStorage {
private final Object myLock;
private SmallMapSerializer<String, Map<String, Collection<SvnBranchItem>>> 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");
@@ -63,18 +61,6 @@ public class SvnLoadedBrachesStorage {
}
}
- public void put(final String url, final Collection<SvnBranchItem> items) {
- synchronized (myLock) {
- if (myState == null) return;
- Map<String, Collection<SvnBranchItem>> map = myState.get("");
- if (map == null) {
- map = new HashMap<String, Collection<SvnBranchItem>>();
- myState.put("", map);
- }
- map.put(url, items);
- }
- }
-
public void activate() {
synchronized (myLock) {
myState = new SmallMapSerializer<String, Map<String, Collection<SvnBranchItem>>>(myFile, new EnumeratorStringDescriptor(), createExternalizer());
@@ -83,15 +69,19 @@ public class SvnLoadedBrachesStorage {
public void deactivate() {
+ Map<String, Collection<SvnBranchItem>> branchLocationToBranchItemsMap = ContainerUtil.newHashMap();
SvnBranchConfigurationManager manager = SvnBranchConfigurationManager.getInstance(myProject);
Map<VirtualFile,SvnBranchConfigurationNew> mapCopy = manager.getSvnBranchConfigManager().getMapCopy();
for (Map.Entry<VirtualFile, SvnBranchConfigurationNew> entry : mapCopy.entrySet()) {
Map<String,InfoStorage<List<SvnBranchItem>>> branchMap = entry.getValue().getBranchMap();
for (Map.Entry<String, InfoStorage<List<SvnBranchItem>>> storageEntry : branchMap.entrySet()) {
- put(storageEntry.getKey(), storageEntry.getValue().getValue());
+ branchLocationToBranchItemsMap.put(storageEntry.getKey(), storageEntry.getValue().getValue());
}
}
synchronized (myLock) {
+ // TODO: Possibly implement optimization - do not perform save if there are no changes in branch locations and branch items
+ // ensure myState.put() is called - so myState will treat itself as dirty and myState.force() will invoke real persisting
+ myState.put("", branchLocationToBranchItemsMap);
myState.force();
myState = null;
}
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<Boolean> withUserInfo = new Ref<Boolean>();
+ final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo);
+
+ if (Boolean.FALSE.equals(withUserInfo.get())) {
+ return configuration;
+ }
+
+ final List<String> branches = configuration.getBranchUrls();
+ final List<String> newBranchesList = new ArrayList<String>(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<String> branches = configuration.getBranchUrls();
+ final List<String> newBranchesList = new ArrayList<String>(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<Boolean> 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<VcsException> exception,
final Set<String> feedback,
- final WorkingCopyFormat format)
+ @NotNull WorkingCopyFormat format)
throws VcsException {
if (committables.isEmpty()) {
return;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
index 602a6e8c460e..cfb4a935bc14 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
@@ -16,6 +16,9 @@
package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Stack;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.api.EventAction;
@@ -43,17 +46,13 @@ public class UpdateOutputLineConverter {
private final static String RECORDING_MERGE_INFO = "--- Recording mergeinfo";
private final static String UPDATING = "Updating";
- private final static String AT_REVISION = "At revision (\\d+)\\.";
- private final static String UPDATED_TO_REVISION = "Updated to revision (\\d+)\\.";
private final static String SKIPPED = "Skipped";
private final static String RESTORED = "Restored";
private final static String FETCHING_EXTERNAL = "Fetching external";
- private final static String EXTERNAL = "External at (\\d+)\\.";
- private final static String UPDATED_EXTERNAL = "Updated external to revision (\\d+)\\.";
-
- private final static Pattern ourAtRevision = Pattern.compile(AT_REVISION);
- private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION);
+
+ private final static Pattern ourAtRevision = Pattern.compile("At revision (\\d+)\\.");
+ private final static Pattern ourUpdatedToRevision = Pattern.compile("Updated to revision (\\d+)\\.");
private final static Pattern ourCheckedOutRevision = Pattern.compile("Checked out revision (\\d+)\\.");
// export from repository
@@ -61,8 +60,8 @@ public class UpdateOutputLineConverter {
// export from working copy
private final static Pattern ourExportComplete = Pattern.compile("Export complete\\.");
- private final static Pattern ourExternal = Pattern.compile(EXTERNAL);
- private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL);
+ private final static Pattern ourExternal = Pattern.compile("External at (\\d+)\\.");
+ private final static Pattern ourUpdatedExternal = Pattern.compile("Updated external to revision (\\d+)\\.");
private final static Pattern ourCheckedOutExternal = Pattern.compile("Checked out external at revision (\\d+)\\.");
private final static Pattern[] ourCompletePatterns =
@@ -70,15 +69,14 @@ public class UpdateOutputLineConverter {
ourCheckedOutExternal, ourExportComplete};
private final File myBase;
- private File myCurrentFile;
+ @NotNull private final Stack<File> myRootsUnderProcessing;
public UpdateOutputLineConverter(File base) {
myBase = base;
- // checkout output does not have special line like "Updating '.'" on start - so set current file directly
- // to correctly detect complete event
- myCurrentFile = base;
+ myRootsUnderProcessing = ContainerUtil.newStack();
}
+ @Nullable
public ProgressEvent convert(final String line) {
// TODO: Add direct processing of "Summary of conflicts" lines at the end of "svn update" output (if there are conflicts).
// TODO: Now it works ok because parseNormalLine could not determine necessary statuses from that and further lines
@@ -87,35 +85,45 @@ public class UpdateOutputLineConverter {
if (line.startsWith(MERGING) || line.startsWith(RECORDING_MERGE_INFO)) {
return null;
} else if (line.startsWith(UPDATING)) {
- myCurrentFile = parseForPath(line);
- return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.UPDATE_NONE, null, null);
+ myRootsUnderProcessing.push(parseForPath(line));
+ return createEvent(myRootsUnderProcessing.peek(), EventAction.UPDATE_NONE);
} else if (line.startsWith(RESTORED)) {
- myCurrentFile = parseForPath(line);
- return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.RESTORE, null, null);
+ return createEvent(parseForPath(line), EventAction.RESTORE);
} else if (line.startsWith(SKIPPED)) {
// called, for instance, when folder is not working copy
- myCurrentFile = parseForPath(line);
final String comment = parseComment(line);
- return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.SKIP,
- comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment), null);
+ return createEvent(parseForPath(line), -1, EventAction.SKIP,
+ comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment));
} else if (line.startsWith(FETCHING_EXTERNAL)) {
- myCurrentFile = parseForPath(line);
- return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.UPDATE_EXTERNAL, null, null);
+ myRootsUnderProcessing.push(parseForPath(line));
+ return createEvent(myRootsUnderProcessing.peek(), EventAction.UPDATE_EXTERNAL);
}
- for (int i = 0; i < ourCompletePatterns.length; i++) {
- final Pattern pattern = ourCompletePatterns[i];
+ for (final Pattern pattern : ourCompletePatterns) {
final long revision = matchAndGetRevision(pattern, line);
if (revision != -1) {
- // TODO: seems that myCurrentFile will not always be correct - complete update message could be right after complete externals update
- // TODO: check this and use Stack instead
- return new ProgressEvent(myCurrentFile, revision, null, null, EventAction.UPDATE_COMPLETED, null, null);
+ // checkout output does not have special line like "Updating '.'" on start - so stack could be empty and we should use myBase
+ File currentRoot = myRootsUnderProcessing.size() > 0 ? myRootsUnderProcessing.pop() : myBase;
+ return createEvent(currentRoot, revision, EventAction.UPDATE_COMPLETED, null);
}
}
return parseNormalString(line);
}
+ @NotNull
+ private static ProgressEvent createEvent(File file, @NotNull EventAction action) {
+ return createEvent(file, -1, action, null);
+ }
+
+ @NotNull
+ private static ProgressEvent createEvent(File file,
+ long revision,
+ @NotNull EventAction action,
+ @Nullable SVNErrorMessage error) {
+ return new ProgressEvent(file, revision, null, null, action, error, null);
+ }
+
private final static Set<Character> ourActions = new HashSet<Character>(Arrays.asList(new Character[] {'A', 'D', 'U', 'C', 'G', 'E', 'R'}));
@Nullable
@@ -134,7 +142,7 @@ public class UpdateOutputLineConverter {
final String path = line.substring(4).trim();
if (StringUtil.isEmptyOrSpaces(path)) return null;
- final File file = createFile(path);
+ final File file = SvnUtil.resolvePath(myBase, path);
if (StatusType.STATUS_OBSTRUCTED.equals(contentsStatus)) {
// obstructed
return new ProgressEvent(file, -1, contentsStatus, propertiesStatus, EventAction.UPDATE_SKIP_OBSTRUCTION, null, null);
@@ -157,12 +165,7 @@ public class UpdateOutputLineConverter {
return new ProgressEvent(file, -1, contentsStatus, propertiesStatus, action, null, null);
}
- private File createFile(String path) {
- return SvnUtil.resolvePath(myBase, path);
- }
-
- @Nullable
- private long matchAndGetRevision(final Pattern pattern, final String line) {
+ private static long matchAndGetRevision(final Pattern pattern, final String line) {
final Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
if (pattern == ourExportComplete) {
@@ -181,22 +184,26 @@ public class UpdateOutputLineConverter {
}
@Nullable
- private String parseComment(final String line) {
- final int idx = line.lastIndexOf("--");
- if (idx != -1 && idx < (line.length() - 2)) {
- return line.substring(idx + 2).trim();
- }
- return null;
+ private static String parseComment(final String line) {
+ int index = line.lastIndexOf("--");
+
+ return index != -1 && index < line.length() - 2 ? line.substring(index + 2).trim() : null;
}
@Nullable
- private File parseForPath(final String line) {
- final int idx1 = line.indexOf('\'');
- if (idx1 == -1) return null;
- final int idx2 = line.indexOf('\'', idx1 + 1);
- if (idx2 == -1) return null;
- final String substring = line.substring(idx1 + 1, idx2);
- if (".".equals(substring)) return myBase;
- return createFile(substring);
+ private File parseForPath(@NotNull String line) {
+ File result = null;
+ int start = line.indexOf('\'');
+
+ if (start != -1) {
+ int end = line.indexOf('\'', start + 1);
+
+ if (end != -1) {
+ String path = line.substring(start + 1, end);
+ result = SvnUtil.resolvePath(myBase, path);
+ }
+ }
+
+ return result;
}
}
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/dialogs/RepositoryBrowserComponent.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java
index 163be4922224..f7e54a64f0ad 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java
@@ -266,7 +266,7 @@ public class RepositoryBrowserComponent extends JPanel implements Disposable, Da
if (entry.getName().lastIndexOf('.') > 0 && !manager.getFileTypeByFileName(name).isBinary()) {
SVNURL url = node.getURL();
final SvnFileRevision revision = new SvnFileRevision(myVCS, SVNRevision.UNDEFINED, SVNRevision.HEAD, url.toString(),
- entry.getAuthor(), entry.getDate(), null, null, null);
+ entry.getAuthor(), entry.getDate(), null, null);
return new VcsVirtualFile(node.getSVNDirEntry().getName(), revision, VcsFileSystem.getInstance());
} else {
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/LoadedRevisionsCache.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/LoadedRevisionsCache.java
index 5da830f0ca87..7e1c9d155a0e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/LoadedRevisionsCache.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/LoadedRevisionsCache.java
@@ -22,13 +22,13 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.RepositoryLocation;
-import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.committed.ChangesBunch;
+import com.intellij.openapi.vcs.changes.committed.CommittedChangesAdapter;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesCache;
-import com.intellij.openapi.vcs.changes.committed.CommittedChangesListener;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.util.containers.SoftHashMap;
import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -51,7 +51,9 @@ public class LoadedRevisionsCache implements Disposable {
myMap = (ApplicationManager.getApplication().isUnitTestMode()) ? new HashMap<String, Bunch>() : new SoftHashMap<String, Bunch>();
myConnection = project.getMessageBus().connect();
- myConnection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesListener() {
+ myConnection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() {
+
+ @Override
public void changesLoaded(final RepositoryLocation location, final List<CommittedChangeList> changes) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
@@ -60,20 +62,6 @@ public class LoadedRevisionsCache implements Disposable {
}
});
}
-
- @Override
- public void changesCleared() {
- }
-
- @Override
- public void presentationChanged() {
- }
-
- public void incomingChangesUpdated(@Nullable final List<CommittedChangeList> receivedChanges) {
- }
-
- public void refreshErrorStatusChanged(@Nullable final VcsException lastError) {
- }
});
Disposer.register(myProject, this);
setRefreshTime(0);
@@ -90,18 +78,20 @@ public class LoadedRevisionsCache implements Disposable {
myRefreshTime = refreshTime;
}
}
-
- private void debugInfo(final List<CommittedChangeList> data, final boolean consistentWithPrevious, final Bunch bindTo) {
+
+ private static void debugInfo(@NotNull List<CommittedChangeList> data, final boolean consistentWithPrevious, final Bunch bindTo) {
LOG.debug(">>> cache internal >>> consistent: " + consistentWithPrevious + " bindTo: " + bindTo +
" oldest list: " + data.get(data.size() - 1).getNumber() + ", youngest list: " + data.get(0).getNumber());
}
public void dispose() {
+ // TODO: Seems that dispose could be removed as connection will be disposed anyway on project dispose and clearing map is not necessary
myConnection.disconnect();
myMap.clear();
}
- private List<List<CommittedChangeList>> split(final List<CommittedChangeList> list, final int size) {
+ @NotNull
+ private static List<List<CommittedChangeList>> split(final List<CommittedChangeList> list, final int size) {
final int listSize = list.size();
if (listSize < size) {
return Collections.singletonList(list);
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/SvnFileRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
index 007df92a403b..e636c9c0a8ef 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
@@ -22,10 +22,10 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Throwable2Computable;
import com.intellij.openapi.vcs.RepositoryLocation;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
@@ -37,7 +37,6 @@ import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -55,7 +54,6 @@ public class SvnFileRevision implements VcsFileRevision {
private final SVNRevision myRevision;
private final String myCopyFromPath;
private final List<SvnFileRevision> myMergeSources;
- private final Charset myCharset;
public SvnFileRevision(SvnVcs vcs,
SVNRevision pegRevision,
@@ -64,8 +62,7 @@ public class SvnFileRevision implements VcsFileRevision {
String author,
Date date,
String commitMessage,
- String copyFromPath, Charset charset) {
- myCharset = charset;
+ String copyFromPath) {
myRevisionNumber = new SvnRevisionNumber(revision);
myPegRevision = pegRevision;
myRevision = revision;
@@ -82,8 +79,7 @@ public class SvnFileRevision implements VcsFileRevision {
SVNRevision pegRevision,
LogEntry logEntry,
String url,
- String copyFromPath, Charset charset) {
- myCharset = charset;
+ String copyFromPath) {
final SVNRevision revision = SVNRevision.create(logEntry.getRevision());
myRevisionNumber = new SvnRevisionNumber(revision);
myPegRevision = pegRevision;
@@ -155,30 +151,37 @@ public class SvnFileRevision implements VcsFileRevision {
else {
loader.run();
}
- if (loader.getException() == null) {
+
+ VcsException exception = loader.getException();
+ if (exception == null) {
final byte[] contents = loader.getContents();
ContentRevisionCache.checkContentsSize(myURL, contents.length);
return contents;
}
else {
- final VcsException vcsException = loader.getException();
- LOG.info("Failed to load file '" + myURL + "' content at revision: " + myRevision + "\n" + vcsException.getMessage(), vcsException);
- throw vcsException;
+ LOG.info("Failed to load file '" + myURL + "' content at revision: " + myRevision + "\n" + exception.getMessage(), exception);
+ throw exception;
}
}
public byte[] getContent() throws IOException, VcsException {
- return ContentRevisionCache.getOrLoadAsBytes(myVCS.getProject(), VcsContextFactory.SERVICE.getInstance()
- .createFilePathOnNonLocal(myURL, false),
- getRevisionNumber(), myVCS.getKeyInstanceMethod(), ContentRevisionCache.UniqueType.REMOTE_CONTENT,
- new Throwable2Computable<byte[], VcsException, IOException>() {
- @Override
- public byte[] compute() throws VcsException, IOException {
- byte[] bytes = loadContent();
- return bytes;
- //return SvnUtil.decode(myCharset, bytes);
- }
- });
+ byte[] result;
+
+ if (SVNRevision.HEAD.equals(myRevision)) {
+ result = loadContent();
+ }
+ else {
+ result = ContentRevisionCache.getOrLoadAsBytes(myVCS.getProject(), VcsUtil.getFilePathOnNonLocal(myURL, false), getRevisionNumber(),
+ myVCS.getKeyInstanceMethod(), ContentRevisionCache.UniqueType.REMOTE_CONTENT,
+ new Throwable2Computable<byte[], VcsException, IOException>() {
+ @Override
+ public byte[] compute() throws VcsException, IOException {
+ return loadContent();
+ }
+ });
+ }
+
+ return result;
}
public String getCopyFromPath() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
index b23b57772535..2ff19fcc56e6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -614,7 +614,7 @@ public class SvnHistoryProvider
final SVNURL url = myRepositoryRoot.appendPath(myLastPath, true);
// final SVNURL url = entryPath != null ? myRepositoryRoot.appendPath(entryPath.getPath(), true) :
// myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false);
- return new SvnFileRevision(myVcs, myPegRevision, rev, url.toString(), author, date, message, copyPath, myCharset);
+ return new SvnFileRevision(myVcs, myPegRevision, rev, url.toString(), author, date, message, copyPath);
}
}
@@ -633,7 +633,7 @@ public class SvnHistoryProvider
throws SVNException {
final SVNURL url = entryPath == null ? myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false) :
myRepositoryRoot.appendPath(entryPath.getPath(), true);
- return new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, url.toString(), copyPath, null);
+ return new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, url.toString(), copyPath);
}
}
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..71fb0a9ec51f 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;
@@ -49,10 +51,10 @@ public class Info extends BaseNodeDescription {
private final String mySchedule;
private final SVNURL myCopyFromURL;
private final SVNRevision myCopyFromRevision;
- private final File myConflictOldFile;
- private final File myConflictNewFile;
- private final File myConflictWrkFile;
- private final File myPropConflictFile;
+ @Nullable private final File myConflictOldFile;
+ @Nullable private final File myConflictNewFile;
+ @Nullable private final File myConflictWrkFile;
+ @Nullable private final File myPropConflictFile;
private final Depth myDepth;
@Nullable private final TreeConflictDescription myTreeConflict;
@@ -69,8 +71,8 @@ public class Info extends BaseNodeDescription {
result =
new Info(info.getFile(), info.getURL(), info.getRepositoryRootURL(), info.getRevision().getNumber(), NodeKind.from(info.getKind()),
info.getRepositoryUUID(), info.getCommittedRevision().getNumber(), toString(info.getCommittedDate()), info.getAuthor(),
- info.getSchedule(), info.getCopyFromURL(), info.getCopyFromRevision().getNumber(), getPath(info.getConflictOldFile()),
- getPath(info.getConflictNewFile()), getPath(info.getConflictWrkFile()), getPath(info.getPropConflictFile()),
+ info.getSchedule(), info.getCopyFromURL(), info.getCopyFromRevision().getNumber(), getName(info.getConflictOldFile()),
+ getName(info.getConflictNewFile()), getName(info.getConflictWrkFile()), getName(info.getPropConflictFile()),
Lock.create(info.getLock()), Depth.from(info.getDepth()), TreeConflictDescription.create(info.getTreeConflict()));
}
@@ -89,10 +91,10 @@ public class Info extends BaseNodeDescription {
String schedule,
SVNURL copyFromURL,
long copyFromRevision,
- String conflictOld,
- String conflictNew,
- String conflictWorking,
- String propRejectFile,
+ @Nullable String conflictOldFileName,
+ @Nullable String conflictNewFileName,
+ @Nullable String conflictWorkingFileName,
+ @Nullable String propRejectFileName,
@Nullable Lock lock,
Depth depth,
@Nullable TreeConflictDescription treeConflict) {
@@ -115,10 +117,10 @@ public class Info extends BaseNodeDescription {
myLock = lock;
myTreeConflict = treeConflict;
- myConflictOldFile = resolveConflictFile(file, conflictOld);
- myConflictNewFile = resolveConflictFile(file, conflictNew);
- myConflictWrkFile = resolveConflictFile(file, conflictWorking);
- myPropConflictFile = resolveConflictFile(file, propRejectFile);
+ myConflictOldFile = resolveConflictFile(file, conflictOldFileName);
+ myConflictNewFile = resolveConflictFile(file, conflictNewFileName);
+ myConflictWrkFile = resolveConflictFile(file, conflictWorkingFileName);
+ myPropConflictFile = resolveConflictFile(file, propRejectFileName);
myIsRemote = false;
myDepth = depth;
@@ -175,14 +177,17 @@ public class Info extends BaseNodeDescription {
return myCommittedRevision;
}
+ @Nullable
public File getConflictNewFile() {
return myConflictNewFile;
}
+ @Nullable
public File getConflictOldFile() {
return myConflictOldFile;
}
+ @Nullable
public File getConflictWrkFile() {
return myConflictWrkFile;
}
@@ -222,6 +227,7 @@ public class Info extends BaseNodeDescription {
return myPath;
}
+ @Nullable
public File getPropConflictFile() {
return myPropConflictFile;
}
@@ -256,8 +262,8 @@ public class Info extends BaseNodeDescription {
}
@Nullable
- private static String getPath(@Nullable File file) {
- return file != null ? file.getPath() : null;
+ private static String getName(@Nullable File file) {
+ return file != null ? file.getName() : null;
}
@Nullable
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<String> caughtError = new Ref<String>();
+
+ @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 <entry> 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<Info>() {
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..ef3529aec092 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdateIntegrateEnvironment.java
@@ -46,7 +46,6 @@ public abstract class AbstractSvnUpdateIntegrateEnvironment implements UpdateEnv
protected final SvnVcs myVcs;
private final ProjectLevelVcsManager myVcsManager;
@NonNls public static final String REPLACED_ID = "replaced";
- @NonNls public static final String EXTERNAL_ID = "external";
protected AbstractSvnUpdateIntegrateEnvironment(final SvnVcs vcs) {
myVcs = vcs;
@@ -145,6 +144,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/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 554b2c29bc48..41bfd61fded1 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -89,8 +89,6 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
rev = updateClient.doUpdate(root, updateTo, configuration.getUpdateDepth(), configuration.isForceUpdate(), false);
}
- myPostUpdateFiles.setRevisions(root.getAbsolutePath(), myVcs, new SvnRevisionNumber(SVNRevision.create(rev)));
-
return rev;
}
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/src/org/jetbrains/idea/svn/update/UpdateEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateEventHandler.java
index fc552dbd1655..aff94e123a31 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateEventHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateEventHandler.java
@@ -16,10 +16,13 @@
package org.jetbrains.idea.svn.update;
import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.update.FileGroup;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.wm.StatusBar;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnFileUrlMapping;
@@ -32,11 +35,12 @@ import org.jetbrains.idea.svn.status.StatusType;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.util.SVNLogType;
import java.io.File;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -49,6 +53,10 @@ public class UpdateEventHandler implements ProgressTracker {
private final SvnVcs myVCS;
@Nullable private final SvnUpdateContext mySequentialUpdatesContext;
private final Map<File, SVNURL> myUrlToCheckForSwitch;
+ // pair.first - group id, pair.second - file path
+ // Stack is used to correctly handle cases when updates of externals occur during ordinary update, because these inner updates could have
+ // its own revisions.
+ private final Stack<List<Pair<String, String>>> myFilesWaitingForRevision;
protected String myText;
protected String myText2;
@@ -60,6 +68,11 @@ public class UpdateEventHandler implements ProgressTracker {
mySequentialUpdatesContext = sequentialUpdatesContext;
myExternalsCount = 1;
myUrlToCheckForSwitch = new HashMap<File, SVNURL>();
+ myFilesWaitingForRevision = ContainerUtil.newStack();
+ // It is more suitable to make this push while handling UPDATE_NONE event - for command line like "svn update <folder>" this event will
+ // be fired when update of <folder> is started. But it's not clear if this event won't be fired in other cases by SVNKit. So currently
+ // first push is made here. If further we want to support commands like "svn update <folder1> <folder2>" this logic should be revised.
+ myFilesWaitingForRevision.push(ContainerUtil.<Pair<String, String>>newArrayList());
}
public void addToSwitch(final File file, final SVNURL url) {
@@ -153,13 +166,8 @@ public class UpdateEventHandler implements ProgressTracker {
if (mySequentialUpdatesContext != null) {
mySequentialUpdatesContext.registerExternalRootBeingUpdated(event.getFile());
}
+ myFilesWaitingForRevision.push(ContainerUtil.<Pair<String, String>>newArrayList());
myExternalsCount++;
- if (myUpdatedFiles.getGroupById(AbstractSvnUpdateIntegrateEnvironment.EXTERNAL_ID) == null) {
- myUpdatedFiles.registerGroup(new FileGroup(SvnBundle.message("status.group.name.externals"),
- SvnBundle.message("status.group.name.externals"),
- false, AbstractSvnUpdateIntegrateEnvironment.EXTERNAL_ID, true));
- }
- addFileToGroup(AbstractSvnUpdateIntegrateEnvironment.EXTERNAL_ID, event);
myText = SvnBundle.message("progress.text.updating.external.location", event.getFile().getAbsolutePath());
}
else if (event.getAction() == EventAction.RESTORE) {
@@ -168,6 +176,7 @@ public class UpdateEventHandler implements ProgressTracker {
}
else if (event.getAction() == EventAction.UPDATE_COMPLETED && event.getRevision() >= 0) {
possiblySwitched(event);
+ setRevisionForWaitingFiles(event.getRevision());
myExternalsCount--;
myText2 = SvnBundle.message("progres.text2.updated.to.revision", event.getRevision());
if (myExternalsCount == 0) {
@@ -218,12 +227,22 @@ public class UpdateEventHandler implements ProgressTracker {
protected void addFileToGroup(final String id, final ProgressEvent event) {
final FileGroup fileGroup = myUpdatedFiles.getGroupById(id);
final String path = event.getFile().getAbsolutePath();
- fileGroup.add(path, SvnVcs.getKey(), new SvnRevisionNumber(SVNRevision.create(event.getRevision())));
+ myFilesWaitingForRevision.peek().add(Pair.create(id, path));
if (event.getErrorMessage() != null) {
fileGroup.addError(path, event.getErrorMessage().getMessage());
}
}
+ private void setRevisionForWaitingFiles(long revisionNumber) {
+ SvnRevisionNumber revision = new SvnRevisionNumber(SVNRevision.create(revisionNumber));
+
+ for (Pair<String, String> pair : myFilesWaitingForRevision.pop()) {
+ FileGroup fileGroup = myUpdatedFiles.getGroupById(pair.getFirst());
+
+ fileGroup.add(pair.getSecond(), SvnVcs.getKey(), revision);
+ }
+ }
+
public void checkCancelled() throws SVNCancelException {
if (myProgressIndicator != null) {
myProgressIndicator.checkCanceled();