summaryrefslogtreecommitdiff
path: root/plugins/svn4idea/src/org/jetbrains/idea/svn
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/svn4idea/src/org/jetbrains/idea/svn')
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/NestedCopiesBuilder.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/StatusReceiver.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/StatusWalkerPartner.java11
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java11
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnEditFileProvider.java6
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java109
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java21
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java22
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java104
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java31
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SetPropertyAction.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java18
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java8
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java13
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/config/SvnConfigureProxiesDialog.java12
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java25
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java37
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java16
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java27
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java69
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SetPropertyDialog.java30
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CmdDiffClient.java54
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DiffClient.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DirectoryWithBranchComparer.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/diff/SvnKitDiffClient.java31
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnDiffFromHistoryHandler.java80
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java31
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java17
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java77
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java106
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java24
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java33
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java33
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java53
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java53
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java109
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java23
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitAdminAreaFactorySelector.java137
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitManager.java3
47 files changed, 1032 insertions, 490 deletions
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/NestedCopiesBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/NestedCopiesBuilder.java
index d0eafb77bc4b..062666fbd402 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/NestedCopiesBuilder.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/NestedCopiesBuilder.java
@@ -86,6 +86,10 @@ public class NestedCopiesBuilder implements StatusReceiver {
}
}
+ @Override
+ public void finish() {
+ }
+
public Set<NestedCopyInfo> getCopies() {
return mySet;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusReceiver.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusReceiver.java
index ac165c48f5c3..f6515de0ebf1 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusReceiver.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusReceiver.java
@@ -29,4 +29,5 @@ public interface StatusReceiver extends EventListener {
void processUnversioned(final VirtualFile vFile);
void processCopyRoot(VirtualFile file, SVNURL url, WorkingCopyFormat format, SVNURL rootURL);
void bewareRoot(VirtualFile vf, SVNURL url);
+ void finish();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusWalkerPartner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusWalkerPartner.java
index 367ae1bc4619..690eb1e76ee3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusWalkerPartner.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/StatusWalkerPartner.java
@@ -15,12 +15,11 @@
*/
package org.jetbrains.idea.svn;
-import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -34,14 +33,14 @@ import org.tmatesoft.svn.core.wc.ISVNStatusFileProvider;
public class StatusWalkerPartner {
private final SvnVcs myVcs;
private final ChangeListManager myClManager;
- private final FileIndexFacade myExcludedFileIndex;
+ private final ProjectLevelVcsManager myVcsManager;
private final ProgressIndicator myIndicator;
private ISVNStatusFileProvider myFileProvider;
public StatusWalkerPartner(final SvnVcs vcs, final ProgressIndicator pi) {
myVcs = vcs;
myClManager = ChangeListManager.getInstance(myVcs.getProject());
- myExcludedFileIndex = PeriodicalTasksCloser.getInstance().safeGetService(myVcs.getProject(), FileIndexFacade.class);
+ myVcsManager = ProjectLevelVcsManager.getInstance(myVcs.getProject());
myIndicator = pi;
}
@@ -75,12 +74,12 @@ public class StatusWalkerPartner {
}
}
- public boolean isExcluded(final VirtualFile vFile) {
+ public boolean isIgnoredByVcs(final VirtualFile vFile) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
if (myVcs.getProject().isDisposed()) throw new ProcessCanceledException();
- return myExcludedFileIndex.isExcludedFile(vFile);
+ return myVcsManager.isIgnored(vFile);
}
});
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
index 073826f6b035..41461ed623c6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
@@ -95,6 +95,8 @@ public class SvnChangeProvider implements ChangeProvider {
walker.go(item.getDir(), Depth.IMMEDIATES);
}
+ statusReceiver.getMulticaster().finish();
+
processCopiedAndDeleted(context, dirtyScope);
processUnsaved(dirtyScope, addGate, context);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
index 716abbe1b20b..9ae90c722cb3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
@@ -48,6 +49,7 @@ class SvnChangeProviderContext implements StatusReceiver {
private Map<FilePath, String> myCopyFromURLs = null;
private final SvnVcs myVcs;
private final SvnBranchConfigurationManager myBranchConfigurationManager;
+ private final List<File> filesToRefresh = ContainerUtil.newArrayList();
private final ProgressIndicator myProgress;
@@ -79,6 +81,11 @@ class SvnChangeProviderContext implements StatusReceiver {
public void bewareRoot(VirtualFile vf, SVNURL url) {
}
+ @Override
+ public void finish() {
+ LocalFileSystem.getInstance().refreshIoFiles(filesToRefresh, true, false, null);
+ }
+
public ChangelistBuilder getBuilder() {
return myChangelistBuilder;
}
@@ -302,7 +309,7 @@ class SvnChangeProviderContext implements StatusReceiver {
*
* @param filePath the path of a changed file.
*/
- private static void loadEntriesFile(final FilePath filePath) {
+ private void loadEntriesFile(final FilePath filePath) {
final FilePath parentPath = filePath.getParentPath();
if (parentPath == null) {
return;
@@ -313,9 +320,11 @@ class SvnChangeProviderContext implements StatusReceiver {
}
}
- private static void refreshDotSvnAndEntries(FilePath filePath) {
+ private void refreshDotSvnAndEntries(FilePath filePath) {
final File svn = new File(filePath.getPath(), SvnUtil.SVN_ADMIN_DIR_NAME);
- LocalFileSystem.getInstance().refreshIoFiles(Arrays.asList(svn, new File(svn, SvnUtil.ENTRIES_FILE_NAME)), true, false, null);
+
+ filesToRefresh.add(svn);
+ filesToRefresh.add(new File(svn, SvnUtil.ENTRIES_FILE_NAME));
}
// seems here we can only have a tree conflict; which can be marked on either path (?)
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
index 49ea87d44f6e..5f5edd12eea7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
@@ -34,14 +34,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.history.LatestExistentSearcher;
-import org.jetbrains.idea.svn.info.InfoConsumer;
import org.jetbrains.idea.svn.info.Info;
+import org.jetbrains.idea.svn.info.InfoConsumer;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.jetbrains.idea.svn.status.Status;
import org.jetbrains.idea.svn.status.StatusType;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
@@ -162,11 +162,12 @@ public class SvnDiffProvider extends DiffProviderEx implements DiffProvider, Dif
}
}
+ @Nullable
private String getCommitMessage(File path) throws VcsException {
- SVNPropertyData property =
+ PropertyValue property =
myVcs.getFactory(path).createPropertyClient().getProperty(SvnTarget.fromFile(path), COMMIT_MESSAGE, true, SVNRevision.BASE);
- return property != null ? SVNPropertyValue.getPropertyAsString(property.getValue()) : null;
+ return PropertyValue.toString(property);
}
private static ItemLatestState defaultResult() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnEditFileProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnEditFileProvider.java
index 64248892614a..c8b47aa0928e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnEditFileProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnEditFileProvider.java
@@ -19,7 +19,7 @@ import com.intellij.openapi.vcs.EditFileProvider;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.idea.svn.properties.PropertyClient;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -42,10 +42,10 @@ public class SvnEditFileProvider implements EditFileProvider {
ioFiles[i] = new File(files[i].getPath());
PropertyClient client = myVCS.getFactory(ioFiles[i]).createPropertyClient();
- SVNPropertyData property = client.getProperty(SvnTarget.fromFile(ioFiles[i], SVNRevision.WORKING), SvnPropertyKeys.SVN_NEEDS_LOCK,
+ PropertyValue property = client.getProperty(SvnTarget.fromFile(ioFiles[i], SVNRevision.WORKING), SvnPropertyKeys.SVN_NEEDS_LOCK,
false, SVNRevision.WORKING);
- if (property == null || property.getValue() == null) {
+ if (property == null) {
throw new VcsException(SvnBundle.message("exception.text.file.miss.svn", ioFiles[i].getName()));
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
index 1719f781a34a..977c6add0c1f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
@@ -15,122 +15,15 @@
*/
package org.jetbrains.idea.svn;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.tmatesoft.svn.core.SVNErrorCode;
-import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.internal.wc.admin.ISVNAdminAreaFactorySelector;
import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminAreaFactory;
import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-public class SvnFormatSelector implements ISVNAdminAreaFactorySelector {
-
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFormatSelector");
-
- public Collection getEnabledFactories(File path, Collection factories, boolean writeAccess) throws SVNException {
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- return factories;
- }
-
- if (! writeAccess) {
- return factories;
- }
-
- Collection result = null;
- final WorkingCopyFormat presetFormat = SvnWorkingCopyFormatHolder.getPresetFormat();
- if (presetFormat != null) {
- result = format2Factories(presetFormat, factories);
- }
-
- if (result == null) {
- final WorkingCopyFormat format = getWorkingCopyFormat(path);
- result = format2Factories(format, factories);
- }
-
- if (result == null) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY));
- }
- return result;
- }
-
- @Nullable
- static Collection format2Factories(final WorkingCopyFormat format, final Collection factories) {
- if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
- return factories;
- } else if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
- return factoriesFor16(factories);
- } else if (WorkingCopyFormat.ONE_DOT_FIVE.equals(format)) {
- return factoriesFor15(factories);
- } else if (WorkingCopyFormat.ONE_DOT_FOUR.equals(format)) {
- return factoriesFor14(factories);
- } else if (WorkingCopyFormat.ONE_DOT_THREE.equals(format)) {
- return factoriesFor13(factories);
- }
- return null;
- }
-
- private static Collection<SVNAdminAreaFactory> factoriesFor13(final Collection factories) {
- for (Iterator iterator = factories.iterator(); iterator.hasNext();) {
- final SVNAdminAreaFactory factory = (SVNAdminAreaFactory) iterator.next();
- final int supportedVersion = factory.getSupportedVersion();
- if (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) {
- return Collections.singletonList(factory);
- }
- }
- return Collections.emptyList();
- }
-
- private static Collection<SVNAdminAreaFactory> factoriesFor14(final Collection factories) {
- final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
- for (Iterator iterator = factories.iterator(); iterator.hasNext();) {
- final SVNAdminAreaFactory factory = (SVNAdminAreaFactory) iterator.next();
- final int supportedVersion = factory.getSupportedVersion();
- if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion)) {
- result.add(factory);
- }
- }
- return result;
- }
-
- private static Collection<SVNAdminAreaFactory> factoriesFor15(final Collection factories) {
- final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
- for (Iterator iterator = factories.iterator(); iterator.hasNext();) {
- final SVNAdminAreaFactory factory = (SVNAdminAreaFactory) iterator.next();
- final int supportedVersion = factory.getSupportedVersion();
- if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_FIVE.getFormat() == supportedVersion)) {
- result.add(factory);
- }
- }
- return result;
- }
-
- private static Collection<SVNAdminAreaFactory> factoriesFor16(final Collection factories) {
- final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
- for (Iterator iterator = factories.iterator(); iterator.hasNext();) {
- final SVNAdminAreaFactory factory = (SVNAdminAreaFactory) iterator.next();
- final int supportedVersion = factory.getSupportedVersion();
- if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_FIVE.getFormat() == supportedVersion) ||
- (WorkingCopyFormat.ONE_DOT_SIX.getFormat() == supportedVersion)) {
- result.add(factory);
- }
- }
- return result;
- }
+public class SvnFormatSelector {
@NotNull
public static WorkingCopyFormat findRootAndGetFormat(final File path) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
index 1b1cd00589d0..13c15b23efa8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
@@ -103,7 +103,7 @@ public class SvnRecursiveStatusWalker {
if (e.contains(SVNErrorCode.WC_NOT_DIRECTORY) || e.contains(SVNErrorCode.WC_NOT_FILE)) {
final VirtualFile virtualFile = path.getVirtualFile();
if (virtualFile != null) {
- if (! myPartner.isExcluded(virtualFile)) {
+ if (! myPartner.isIgnoredByVcs(virtualFile)) {
// self is unversioned
myReceiver.processUnversioned(virtualFile);
@@ -184,15 +184,20 @@ public class SvnRecursiveStatusWalker {
}
};
if (Depth.EMPTY.equals(newDepth)) {
- directoryFilter = Processor.TRUE;
+ // just process immediate children - so only root directory itself should satisfy filter
+ directoryFilter = new Processor<File>() {
+ @Override
+ public boolean process(File file) {
+ return FileUtil.filesEqual(ioFile, file);
+ }
+ };
processor = new Processor<File>() {
@Override
public boolean process(File file) {
- // here we deal only with immediate children - so ignored on IDEA level for children is not important - we nevertheless do not go into
- // other levels
- if (! FileUtil.filesEqual(ioFile, file)) return true;
- if (! FileUtil.filesEqual(ioFile, file.getParentFile())) return false;
- return checkDirProcessor.process(file);
+ // TODO: check if we should still call checkDirProcessor() here - or we really could not check ignore settings but just call
+ // TODO: myReceiver.processUnversioned() for all immediate children
+ // here we deal only with immediate children - so ignored on IDEA level for children is not important
+ return FileUtil.filesEqual(ioFile, file) || checkDirProcessor.process(file);
}
};
} else {
@@ -278,7 +283,7 @@ public class SvnRecursiveStatusWalker {
@Override
public Boolean compute() {
if (myProject.isDisposed()) return null;
- return myPartner.isExcluded(vFile);
+ return myPartner.isIgnoredByVcs(vFile);
}
});
if (Boolean.TRUE.equals(excluded)) return;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index 5010ac580750..b44fd16f979f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -81,6 +81,8 @@ 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;
import org.jetbrains.idea.svn.status.StatusType;
@@ -89,7 +91,6 @@ import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.wc.SVNAdminUtil;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -108,8 +109,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
private static final VcsKey ourKey = createKey(VCS_NAME);
public static final Topic<Runnable> WC_CONVERTED = new Topic<Runnable>("WC_CONVERTED", Runnable.class);
- private final Map<String, Map<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>>> myPropertyCache =
- new SoftHashMap<String, Map<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>>>();
+ private final Map<String, Map<String, Pair<PropertyValue, Trinity<Long, Long, Long>>>> myPropertyCache =
+ new SoftHashMap<String, Map<String, Pair<PropertyValue, Trinity<Long, Long, Long>>>>();
private final SvnConfiguration myConfiguration;
private final SvnEntriesFileListener myEntriesFileListener;
@@ -567,9 +568,9 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
@Nullable
- public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws VcsException {
- Map<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>> cachedMap = myPropertyCache.get(keyForVf(file));
- final Pair<SVNPropertyValue, Trinity<Long, Long, Long>> cachedValue = cachedMap == null ? null : cachedMap.get(propName);
+ public PropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws VcsException {
+ Map<String, Pair<PropertyValue, Trinity<Long, Long, Long>>> cachedMap = myPropertyCache.get(keyForVf(file));
+ final Pair<PropertyValue, Trinity<Long, Long, Long>> cachedValue = cachedMap == null ? null : cachedMap.get(propName);
final File ioFile = new File(file.getPath());
final Trinity<Long, Long, Long> tsTrinity = getTimestampForPropertiesChange(ioFile, file.isDirectory());
@@ -582,17 +583,16 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
PropertyClient client = getFactory(ioFile).createPropertyClient();
- final SVNPropertyData value = client.getProperty(SvnTarget.fromFile(ioFile, SVNRevision.WORKING), propName, false, SVNRevision.WORKING);
- final SVNPropertyValue propValue = value == null ? null : value.getValue();
+ final PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile, SVNRevision.WORKING), propName, false, SVNRevision.WORKING);
if (cachedMap == null) {
- cachedMap = new HashMap<String, Pair<SVNPropertyValue, Trinity<Long, Long, Long>>>();
+ cachedMap = new HashMap<String, Pair<PropertyValue, Trinity<Long, Long, Long>>>();
myPropertyCache.put(keyForVf(file), cachedMap);
}
- cachedMap.put(propName, Pair.create(propValue, tsTrinity));
+ cachedMap.put(propName, Pair.create(value, tsTrinity));
- return propValue;
+ return value;
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java
index 97e6a618ba7c..395dc36b7371 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java
@@ -19,12 +19,15 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diff.DiffManager;
import com.intellij.openapi.diff.SimpleContent;
import com.intellij.openapi.diff.SimpleDiffRequest;
+import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsDataKeys;
@@ -34,17 +37,20 @@ import com.intellij.openapi.vcs.changes.ChangesUtil;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
-import org.jetbrains.idea.svn.SvnRevisionNumber;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.history.SvnRepositoryContentRevision;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+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.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+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;
@@ -69,8 +75,6 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
@Override
public void update(final AnActionEvent e) {
final DataContext dataContext = e.getDataContext();
- final Project project = CommonDataKeys.PROJECT.getData(dataContext);
-
final Presentation presentation = e.getPresentation();
final Change[] data = VcsDataKeys.CHANGES.getData(dataContext);
boolean showAction = checkThatChangesAreUnderSvn(data);
@@ -78,38 +82,23 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
presentation.setEnabled(showAction);
}
- private boolean checkThatChangesAreUnderSvn(Change[] data) {
- boolean showAction = false;
- if (data != null) {
- for (Change change : data) {
- final ContentRevision before = change.getBeforeRevision();
- if (before != null) {
- showAction = showAction || before instanceof MarkerVcsContentRevision && SvnVcs.getKey().equals(((MarkerVcsContentRevision)before).getVcsKey());
- }
- final ContentRevision after = change.getAfterRevision();
- if (after != null) {
- showAction = showAction || after instanceof MarkerVcsContentRevision && SvnVcs.getKey().equals(((MarkerVcsContentRevision)after).getVcsKey());
+ private static boolean checkThatChangesAreUnderSvn(@Nullable Change[] changes) {
+ boolean result = false;
+
+ if (changes != null) {
+ result = ContainerUtil.or(changes, new Condition<Change>() {
+ @Override
+ public boolean value(Change change) {
+ return isUnderSvn(change.getBeforeRevision()) || isUnderSvn(change.getAfterRevision());
}
- if (showAction) break;
- }
+ });
}
- return showAction;
- }
- private boolean enabled(final Project project, final Change[] changes) {
- final boolean noChange = (project == null) || (changes == null) || (changes.length != 1);
- if (noChange) {
- return false;
- } else {
- final Change change = changes[0];
-
- final ContentRevision revision = (change.getBeforeRevision() != null) ? change.getBeforeRevision() : change.getAfterRevision();
- if ((revision == null) || (! (revision.getRevisionNumber() instanceof SvnRevisionNumber))) {
- return false;
- }
+ return result;
+ }
- return checkVcs(project, change);
- }
+ private static boolean isUnderSvn(@Nullable ContentRevision revision) {
+ return revision instanceof MarkerVcsContentRevision && SvnVcs.getKey().equals(((MarkerVcsContentRevision)revision).getVcsKey());
}
protected boolean checkVcs(final Project project, final Change change) {
@@ -146,7 +135,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
private final String myErrorTitle;
private CalculateAndShow(@Nullable final Project project, final Change change, final String errorTitle) {
- super(project, SvnBundle.message("fetching.properties.contents.progress.title"), true, Backgroundable.DEAF);
+ super(project, SvnBundle.message("fetching.properties.contents.progress.title"), true, PerformInBackgroundOption.DEAF);
myChange = change;
myErrorTitle = errorTitle;
}
@@ -179,7 +168,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
}
if (myBeforeContent != null && myAfterContent != null && myBeforeRevisionValue != null && myAfterRevision != null) {
final SimpleDiffRequest diffRequest = new SimpleDiffRequest(myProject, getDiffWindowTitle(myChange));
- if (compareRevisions(myBeforeRevisionValue, myAfterRevision) >= 0) {
+ if (compareRevisions(myBeforeRevisionValue, myAfterRevision) > 0) {
// before ahead
diffRequest.setContents(new SimpleContent(myAfterContent), new SimpleContent(myBeforeContent));
diffRequest.setContentTitles(revisionToString(myAfterRevision), revisionToString(myBeforeRevisionValue));
@@ -194,7 +183,8 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
}
}
- private String getDiffWindowTitle(final Change change) {
+ @NotNull
+ private static String getDiffWindowTitle(@NotNull Change change) {
if (change.isMoved() || change.isRenamed()) {
final FilePath beforeFilePath = ChangesUtil.getBeforePath(change);
final FilePath afterFilePath = ChangesUtil.getAfterPath(change);
@@ -207,7 +197,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
}
}
- private int compareRevisions(@NonNls final SVNRevision revision1, @NonNls final SVNRevision revision2) {
+ private static int compareRevisions(@NotNull SVNRevision revision1, @NotNull SVNRevision revision2) {
if (revision1.equals(revision2)) {
return 0;
}
@@ -227,11 +217,9 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
return revision1.getNumber() > revision2.getNumber() ? 1 : -1;
}
- private String revisionToString(final SVNRevision revision) {
- if (revision == null) {
- return "not exists";
- }
- return revision.toString();
+ @NotNull
+ private static String revisionToString(@Nullable SVNRevision revision) {
+ return revision == null ? "not exists" : revision.toString();
}
private final static String ourPropertiesDelimiter = "\n";
@@ -273,35 +261,35 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
private static String getPropertyList(@NotNull SvnVcs vcs, @NotNull SvnTarget target, @Nullable SVNRevision revision)
throws VcsException {
- final List<SVNPropertyData> lines = new ArrayList<SVNPropertyData>();
- final ISVNPropertyHandler propertyHandler = createHandler(revision, lines);
+ final List<PropertyData> lines = new ArrayList<PropertyData>();
+ final PropertyConsumer propertyHandler = createHandler(revision, lines);
vcs.getFactory(target).createPropertyClient().list(target, revision, Depth.EMPTY, propertyHandler);
return toSortedStringPresentation(lines);
}
- private static ISVNPropertyHandler createHandler(SVNRevision revision, final List<SVNPropertyData> lines) {
+ private static PropertyConsumer createHandler(SVNRevision revision, final List<PropertyData> lines) {
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
if (indicator != null) {
indicator.checkCanceled();
indicator.setText(SvnBundle.message("show.properties.diff.progress.text.revision.information", revision.toString()));
}
- return new ISVNPropertyHandler() {
- public void handleProperty(final File path, final SVNPropertyData property) throws SVNException {
+ return new PropertyConsumer() {
+ public void handleProperty(final File path, final PropertyData property) throws SVNException {
registerProperty(property);
}
- public void handleProperty(final SVNURL url, final SVNPropertyData property) throws SVNException {
+ public void handleProperty(final SVNURL url, final PropertyData property) throws SVNException {
registerProperty(property);
}
- public void handleProperty(final long revision, final SVNPropertyData property) throws SVNException {
+ public void handleProperty(final long revision, final PropertyData property) throws SVNException {
// revision properties here
}
- private void registerProperty(@NotNull SVNPropertyData property) {
+ private void registerProperty(@NotNull PropertyData property) {
if (indicator != null) {
indicator.checkCanceled();
indicator.setText2(SvnBundle.message("show.properties.diff.progress.text2.property.information", property.getName()));
@@ -311,26 +299,26 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
};
}
- private static String toSortedStringPresentation(List<SVNPropertyData> lines) {
+ private static String toSortedStringPresentation(List<PropertyData> lines) {
StringBuilder sb = new StringBuilder();
- Collections.sort(lines, new Comparator<SVNPropertyData>() {
- public int compare(final SVNPropertyData o1, final SVNPropertyData o2) {
+ Collections.sort(lines, new Comparator<PropertyData>() {
+ public int compare(final PropertyData o1, final PropertyData o2) {
return o1.getName().compareTo(o2.getName());
}
});
- for (SVNPropertyData line : lines) {
+ for (PropertyData line : lines) {
addPropertyPresentation(line, sb);
}
return sb.toString();
}
- private static void addPropertyPresentation(final SVNPropertyData property, final StringBuilder sb) {
+ private static void addPropertyPresentation(final PropertyData property, final StringBuilder sb) {
if (sb.length() != 0) {
sb.append(ourPropertiesDelimiter);
}
- sb.append(property.getName()).append("=").append((property.getValue() == null) ? "" : SVNPropertyValue.getPropertyAsString(property.getValue()));
+ sb.append(property.getName()).append("=").append(StringUtil.notNullize(PropertyValue.toString(property.getValue())));
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
index 31206eec045c..d6d9c3152dde 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java
@@ -24,7 +24,6 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
@@ -42,15 +41,16 @@ import org.jetbrains.idea.svn.api.ProgressEvent;
import org.jetbrains.idea.svn.api.ProgressTracker;
import org.jetbrains.idea.svn.commandLine.CommandUtil;
import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog;
+import org.jetbrains.idea.svn.properties.ExternalsDefinitionParser;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.jetbrains.idea.svn.update.UpdateClient;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNPropertyValue;
-import org.tmatesoft.svn.core.internal.wc.SVNExternal;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
+import java.util.Map;
/**
* Created with IntelliJ IDEA.
@@ -132,25 +132,24 @@ public class CreateExternalAction extends DumbAwareAction {
public static boolean addToExternalProperty(@NotNull SvnVcs vcs, @NotNull File ioFile, String target, String url)
throws SVNException, VcsException {
ClientFactory factory = vcs.getFactory(ioFile);
- SVNPropertyData propertyData = factory.createPropertyClient().getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_EXTERNALS,
+ PropertyValue propertyValue = factory.createPropertyClient().getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_EXTERNALS,
false, SVNRevision.UNDEFINED);
String newValue;
- if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) {
- final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString());
- for (SVNExternal external : externals) {
- if (Comparing.equal(external.getPath(), target)) {
- AbstractVcsHelper
- .getInstance(vcs.getProject()).showError(new VcsException("Selected destination conflicts with existing: " + external.toString()), "Create External");
- return true;
- }
+ if (propertyValue != null && !StringUtil.isEmptyOrSpaces(propertyValue.toString())) {
+ Map<String, String> externalsMap = ExternalsDefinitionParser.parseExternalsProperty(propertyValue.toString());
+ String externalsForTarget = externalsMap.get(target);
+
+ if (externalsForTarget != null) {
+ AbstractVcsHelper.getInstance(vcs.getProject()).showError(
+ new VcsException("Selected destination conflicts with existing: " + externalsForTarget), "Create External");
+ return true;
}
final String string = createExternalDefinitionString(url, target);
- newValue = propertyData.getValue().getString().trim() + "\n" + string;
+ newValue = propertyValue.toString().trim() + "\n" + string;
} else {
newValue = createExternalDefinitionString(url, target);
}
- factory.createPropertyClient().setProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), Depth.EMPTY,
- false);
+ factory.createPropertyClient().setProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, PropertyValue.create(newValue), Depth.EMPTY, false);
return false;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SetPropertyAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SetPropertyAction.java
index cdc738cf2d40..5e53cc956e92 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SetPropertyAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SetPropertyAction.java
@@ -30,7 +30,7 @@ import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.dialogs.SetPropertyDialog;
import org.jetbrains.idea.svn.properties.PropertyClient;
-import org.tmatesoft.svn.core.SVNPropertyValue;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import java.io.File;
@@ -79,7 +79,7 @@ public class SetPropertyAction extends BasicAction {
// TODO: most likely SVNDepth.getInfinityOrEmptyDepth should be used instead of SVNDepth.fromRecursive - to have either "infinity"
// TODO: or "empty" depth, and not "infinity" or "files" depth. But previous logic used SVNDepth.fromRecursive implicitly
- client.setProperty(ioFile, name, SVNPropertyValue.create(value), Depth.allOrFiles(recursive), false);
+ client.setProperty(ioFile, name, PropertyValue.create(value), Depth.allOrFiles(recursive), false);
}
for(int i = 0; i < file.length; i++) {
if (recursive && file[i].isDirectory()) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java
index c206cd3451d8..94fc2e11c96e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java
@@ -15,11 +15,10 @@
*/
package org.jetbrains.idea.svn.actions;
-import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -42,39 +41,36 @@ public class SvnExcludingIgnoredOperation {
public static class Filter {
private final Project myProject;
- private final FileIndexFacade myIndex;
+ private final ProjectLevelVcsManager myVcsManager;
private final ChangeListManager myClManager;
public Filter(final Project project) {
myProject = project;
if (!project.isDefault()) {
- myIndex = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
+ myVcsManager = ProjectLevelVcsManager.getInstance(project);
myClManager = ChangeListManager.getInstance(project);
}
else {
- myIndex = null;
+ myVcsManager = null;
myClManager = null;
}
}
public boolean accept(final VirtualFile file) {
if (!myProject.isDefault()) {
- if (isExcluded(file)) {
- return false;
- }
- if (myClManager.isIgnoredFile(file)) {
+ if (isIgnoredByVcs(file) || myClManager.isIgnoredFile(file)) {
return false;
}
}
return true;
}
- private boolean isExcluded(final VirtualFile file) {
+ private boolean isIgnoredByVcs(final VirtualFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return myIndex.isExcludedFile(file);
+ return myVcsManager.isIgnored(file);
}
});
}
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 912bd970f7b0..ddd9bd572f0e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
@@ -32,9 +32,9 @@ import org.jetbrains.idea.svn.SvnVcs;
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.SVNPropertyValue;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
@@ -162,8 +162,8 @@ public class SvnMergeProvider implements MergeProvider {
File ioFile = new File(file.getPath());
PropertyClient client = vcs.getFactory(ioFile).createPropertyClient();
- SVNPropertyData svnPropertyData = client.getProperty(SvnTarget.fromFile(ioFile), SVNProperty.MIME_TYPE, false, SVNRevision.WORKING);
- if (svnPropertyData != null && SVNProperty.isBinaryMimeType(SVNPropertyValue.getPropertyAsString(svnPropertyData.getValue()))) {
+ PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile), SVNProperty.MIME_TYPE, false, SVNRevision.WORKING);
+ if (value != null && SVNProperty.isBinaryMimeType(value.toString())) {
return true;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
index 33e06739ad0b..0b484e41d1c5 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.EventDispatcher;
@@ -36,6 +37,7 @@ import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -152,9 +154,20 @@ public class CommandExecutor {
protected void beforeCreateProcess() throws SvnBindException {
EncodingEnvironmentUtil.fixDefaultEncodingIfMac(myCommandLine, null);
+ setupLocale();
ensureMessageFile();
}
+ private void setupLocale() {
+ String locale = Registry.stringValue("svn.executable.locale");
+ Map<String, String> environment = myCommandLine.getEnvironment();
+
+ // TODO: check if we need to set LC_ALL to configured locale or just clear it
+ environment.put("LC_ALL", "");
+ environment.put("LC_MESSAGES", locale);
+ environment.put("LANG", locale);
+ }
+
private void ensureMessageFile() throws SvnBindException {
if (myMessage != null) {
myMessageFile = createTempFile("commit-message", ".txt");
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
index eee798737846..eb2e6cf976cb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
@@ -58,8 +58,7 @@ public class CommandUtil {
boolean hasPegRevision = pegRevision != null &&
!SVNRevision.UNDEFINED.equals(pegRevision) &&
!SVNRevision.WORKING.equals(pegRevision) &&
- pegRevision.isValid() &&
- pegRevision.getNumber() != 0;
+ pegRevision.isValid();
if (hasPegRevision || hasAtSymbol) {
// add '@' to correctly handle paths that contain '@' symbol
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/SvnConfigureProxiesDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/SvnConfigureProxiesDialog.java
index a70a4f28d0fd..40e3c80d1fc6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/SvnConfigureProxiesDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/SvnConfigureProxiesDialog.java
@@ -63,16 +63,10 @@ public class SvnConfigureProxiesDialog extends DialogWrapper implements Validati
public void onError(final String text, final JComponent component, final boolean forbidSave) {
myTabbedPane.setSelectedComponent(component);
- String prefixString = "";
- for (int i = 0; i < myTabbedPane.getComponentCount(); i++) {
- final Component currentComponent = myTabbedPane.getComponentAt(i);
- // compare referencies - same objects
- if (currentComponent == component) {
- prefixString = myTabbedPane.getTitleAt(i) + ": ";
- }
- }
+ String errorPrefix = myTabbedPane.getTitleAt(myTabbedPane.indexOfComponent(component)) + ": ";
+
setOKActionEnabled(! forbidSave);
- setInvalid(prefixString + text);
+ setInvalid(errorPrefix + text);
}
public void onSuccess() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java
index 6bd08c1089cb..50ddd9615d41 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java
@@ -22,10 +22,12 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.MultiLineLabelUI;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -100,16 +102,23 @@ public class BranchConfigurationDialog extends DialogWrapper {
myListPanel.add(
ToolbarDecorator.createDecorator(myLocationList)
.setAddAction(new AnActionButtonRunnable() {
+
+ @Nullable private SVNURL usedRootUrl;
+
@Override
public void run(AnActionButton button) {
- final String selectedUrl = SelectLocationDialog.selectLocation(project, rootUrl.toDecodedString());
- if (selectedUrl != null) {
- if (!configuration.getBranchUrls().contains(selectedUrl)) {
- configuration
- .addBranches(selectedUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
- mySvnBranchConfigManager.reloadBranches(myRoot, selectedUrl, null);
- listModel.fireItemAdded();
- myLocationList.setSelectedIndex(listModel.getSize() - 1);
+ Pair<String, SVNURL> result = SelectLocationDialog.selectLocation(project, ObjectUtils.notNull(usedRootUrl, rootUrl));
+ if (result != null) {
+ String selectedUrl = result.getFirst();
+ usedRootUrl = result.getSecond();
+ if (selectedUrl != null) {
+ if (!configuration.getBranchUrls().contains(selectedUrl)) {
+ configuration
+ .addBranches(selectedUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
+ mySvnBranchConfigManager.reloadBranches(myRoot, selectedUrl, null);
+ listModel.fireItemAdded();
+ myLocationList.setSelectedIndex(listModel.getSize() - 1);
+ }
}
}
}
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 860c524ed591..cd504be56077 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java
@@ -37,9 +37,12 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+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;
@@ -151,20 +154,20 @@ public class PropertiesComponent extends JPanel {
}
}
- private void collectProperties(@NotNull SvnVcs vcs, @NotNull File file, @NotNull final Map<String, String> props) {
+ private static void collectProperties(@NotNull SvnVcs vcs, @NotNull File file, @NotNull final Map<String, String> props) {
try {
- ISVNPropertyHandler handler = new ISVNPropertyHandler() {
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
- final SVNPropertyValue value = property.getValue();
+ PropertyConsumer handler = new PropertyConsumer() {
+ public void handleProperty(File path, PropertyData property) throws SVNException {
+ final PropertyValue value = property.getValue();
if (value != null) {
- props.put(property.getName(), SVNPropertyValue.getPropertyAsString(property.getValue()));
+ props.put(property.getName(), PropertyValue.toString(property.getValue()));
}
}
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ public void handleProperty(SVNURL url, PropertyData property) throws SVNException {
}
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ public void handleProperty(long revision, PropertyData property) throws SVNException {
}
};
vcs.getFactory(file).createPropertyClient().list(SvnTarget.fromFile(file, SVNRevision.UNDEFINED), SVNRevision.WORKING, Depth.EMPTY,
@@ -229,10 +232,12 @@ public class PropertiesComponent extends JPanel {
String url = "file://" + myFile.getPath().replace(File.separatorChar, '/');
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
+ VcsDirtyScopeManager dirtyScopeManager = VcsDirtyScopeManager.getInstance(myVcs.getProject());
+
if (recursive && file.isDirectory()) {
- VcsDirtyScopeManager.getInstance(myVcs.getProject()).dirDirtyRecursively(file, true);
+ dirtyScopeManager.dirDirtyRecursively(file);
} else {
- VcsDirtyScopeManager.getInstance(myVcs.getProject()).fileDirty(file);
+ dirtyScopeManager.fileDirty(file);
}
}
}
@@ -272,8 +277,7 @@ public class PropertiesComponent extends JPanel {
if (!StringUtil.isEmpty(property)) {
try {
myVcs.getFactory(myFile).createPropertyClient()
- .setProperty(myFile, property, value != null ? SVNPropertyValue.create(value) : null,
- Depth.allOrEmpty(recursive), force);
+ .setProperty(myFile, property, PropertyValue.create(value), Depth.allOrEmpty(recursive), force);
}
catch (VcsException error) {
VcsBalloonProblemNotifier
@@ -302,7 +306,7 @@ public class PropertiesComponent extends JPanel {
public void actionPerformed(AnActionEvent e) {
Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
- SVNPropertyData propValue = null;
+ PropertyValue propValue = null;
try {
propValue = myVcs.getFactory(myFile).createPropertyClient()
.getProperty(SvnTarget.fromFile(myFile), SVNProperty.KEYWORDS, false, SVNRevision.WORKING);
@@ -311,8 +315,7 @@ public class PropertiesComponent extends JPanel {
// show erorr message
}
- SetKeywordsDialog dialog = new SetKeywordsDialog(project,
- propValue != null ? SVNPropertyValue.getPropertyAsString(propValue.getValue()) : null);
+ SetKeywordsDialog dialog = new SetKeywordsDialog(project, PropertyValue.toString(propValue));
dialog.show();
if (dialog.isOK()) {
setProperty(SvnPropertyKeys.SVN_KEYWORDS, dialog.getKeywords(), false, false);
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 0fd1f06bf7cb..163be4922224 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java
@@ -76,10 +76,26 @@ public class RepositoryBrowserComponent extends JPanel implements Disposable, Da
}
public void setRepositoryURLs(SVNURL[] urls, final boolean showFiles) {
+ setRepositoryURLs(urls, showFiles, null, false);
+ }
+
+ public void setRepositoryURLs(SVNURL[] urls,
+ final boolean showFiles,
+ @Nullable NotNullFunction<RepositoryBrowserComponent, Expander> defaultExpanderFactory,
+ boolean expandFirst) {
RepositoryTreeModel model = new RepositoryTreeModel(myVCS, showFiles, this);
+
+ if (defaultExpanderFactory != null) {
+ model.setDefaultExpanderFactory(defaultExpanderFactory);
+ }
+
model.setRoots(urls);
Disposer.register(this, model);
myRepositoryTree.setModel(model);
+
+ if (expandFirst) {
+ myRepositoryTree.expandRow(0);
+ }
}
public void setRepositoryURL(SVNURL url, boolean showFiles, final NotNullFunction<RepositoryBrowserComponent, Expander> defaultExpanderFactory) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
index 191acf387b86..83d895b93ffc 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java
@@ -93,7 +93,7 @@ public class RepositoryBrowserDialog extends DialogWrapper {
private final boolean myShowFiles;
- @NonNls private static final String PLACE_TOOLBAR = "RepositoryBrowser.Toolbar";
+ @NonNls public static final String PLACE_TOOLBAR = "RepositoryBrowser.Toolbar";
@NonNls private static final String PLACE_MENU = "RepositoryBrowser.Menu";
private final String myRepositoriesLabelText;
protected JLabel myRepositoriesLabel;
@@ -138,7 +138,7 @@ public class RepositoryBrowserDialog extends DialogWrapper {
DefaultActionGroup group = new DefaultActionGroup();
final RepositoryBrowserComponent browser = getRepositoryBrowser();
group.add(new AddLocationAction(browser));
- group.add(new EditLocationAction());
+ group.add(new EditLocationAction(browser));
group.add(new DiscardLocationAction(browser));
group.add(new DetailsAction());
group.addSeparator();
@@ -216,7 +216,7 @@ public class RepositoryBrowserDialog extends DialogWrapper {
group.add(copyUrlAction);
group.addSeparator();
group.add(new RefreshAction(browser));
- group.add(new EditLocationAction());
+ group.add(new EditLocationAction(browser));
group.add(new DiscardLocationAction(browser));
ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(PLACE_MENU, group);
return menu.getComponent();
@@ -413,13 +413,17 @@ public class RepositoryBrowserDialog extends DialogWrapper {
}
}
- protected class EditLocationAction extends AnAction {
- public EditLocationAction() {
+ protected static class EditLocationAction extends AnAction {
+
+ @NotNull private final RepositoryBrowserComponent myBrowserComponent;
+
+ public EditLocationAction(@NotNull RepositoryBrowserComponent browserComponent) {
super(SvnBundle.message("repository.browser.edit.location.menu.item"));
+ myBrowserComponent = browserComponent;
}
public void update(AnActionEvent e) {
- RepositoryTreeNode node = getRepositoryBrowser().getSelectedNode();
+ RepositoryTreeNode node = myBrowserComponent.getSelectedNode();
if (e.getPlace().equals(PLACE_TOOLBAR)) {
e.getPresentation().setDescription(SvnBundle.message("repository.browser.edit.location.menu.item"));
e.getPresentation().setText(SvnBundle.message("repository.browser.edit.location.menu.item"));
@@ -429,13 +433,14 @@ public class RepositoryBrowserDialog extends DialogWrapper {
}
public void actionPerformed(AnActionEvent e) {
- RepositoryTreeNode node = getRepositoryBrowser().getSelectedNode();
+ RepositoryTreeNode node = myBrowserComponent.getSelectedNode();
if (node == null || (! (node.getParent() instanceof RepositoryTreeRootNode))) {
return;
}
final String oldUrl = node.getURL().toString();
final SvnApplicationSettings settings = SvnApplicationSettings.getInstance();
- final AddRepositoryLocationDialog dialog = new AddRepositoryLocationDialog(myProject, settings.getTypedUrlsListCopy()) {
+ final AddRepositoryLocationDialog dialog =
+ new AddRepositoryLocationDialog(myBrowserComponent.getProject(), settings.getTypedUrlsListCopy()) {
@Override
protected String initText() {
return oldUrl;
@@ -453,9 +458,9 @@ public class RepositoryBrowserDialog extends DialogWrapper {
settings.addTypedUrl(url);
settings.removeCheckoutURL(oldUrl);
settings.addCheckoutURL(url);
- final RepositoryBrowserComponent browser = getRepositoryBrowser();
- browser.removeURL(oldUrl);
- browser.addURL(url);
+
+ myBrowserComponent.removeURL(oldUrl);
+ myBrowserComponent.addURL(url);
}
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java
index a6ca6ad54f11..bcbbe79c1b45 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java
@@ -15,12 +15,15 @@
*/
package org.jetbrains.idea.svn.dialogs;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -52,21 +55,30 @@ public class SelectLocationDialog extends DialogWrapper {
private final String myDstLabel;
private JTextField myDstText;
private final boolean myIsShowFiles;
+ private final boolean myAllowActions;
@NonNls private static final String HELP_ID = "vcs.subversion.common";
// todo check that works when authenticated
@Nullable
public static String selectLocation(Project project, String url) {
- SelectLocationDialog dialog = openDialog(project, url, null, null, true, null);
+ SelectLocationDialog dialog = openDialog(project, url, null, null, true, false, null);
return dialog == null || !dialog.isOK() ? null : dialog.getSelectedURL();
}
@Nullable
+ public static Pair<String, SVNURL> selectLocation(Project project, @NotNull SVNURL url) {
+ SelectLocationDialog dialog = new SelectLocationDialog(project, url, null, null, true, true);
+ dialog.show();
+
+ return dialog.isOK() ? Pair.create(dialog.getSelectedURL(), dialog.getRootUrl()) : null;
+ }
+
+ @Nullable
public static String selectCopyDestination(Project project, String url, String dstLabel, String dstName, boolean showFiles) {
SelectLocationDialog dialog =
- openDialog(project, url, dstLabel, dstName, showFiles, SvnBundle.message("select.location.invalid.url.message", url));
+ openDialog(project, url, dstLabel, dstName, showFiles, false, SvnBundle.message("select.location.invalid.url.message", url));
return dialog == null || !dialog.isOK() ? null : SVNPathUtil.append(dialog.getSelectedURL(), dialog.getDestinationName());
}
@@ -77,6 +89,7 @@ public class SelectLocationDialog extends DialogWrapper {
String dstLabel,
String dstName,
boolean showFiles,
+ boolean allowActions,
String errorMessage) {
try {
SVNURL svnUrl = SvnUtil.createUrl(url);
@@ -86,8 +99,7 @@ public class SelectLocationDialog extends DialogWrapper {
SvnBundle.message("dialog.title.select.repository.location"));
return null;
}
-
- SelectLocationDialog dialog = new SelectLocationDialog(project, repositoryUrl, dstLabel, dstName, showFiles);
+ SelectLocationDialog dialog = new SelectLocationDialog(project, repositoryUrl, dstLabel, dstName, showFiles, allowActions);
dialog.show();
return dialog;
}
@@ -98,13 +110,14 @@ public class SelectLocationDialog extends DialogWrapper {
}
}
- private SelectLocationDialog(Project project, SVNURL url, String dstLabel, String dstName, boolean showFiles) {
+ private SelectLocationDialog(Project project, SVNURL url, String dstLabel, String dstName, boolean showFiles, boolean allowActions) {
super(project, true);
myProject = project;
myDstLabel = dstLabel;
myDstName = dstName;
myURL = url;
myIsShowFiles = showFiles;
+ myAllowActions = allowActions;
setTitle(SvnBundle.message("dialog.title.select.repository.location"));
getHelpAction().setEnabled(true);
init();
@@ -146,7 +159,13 @@ public class SelectLocationDialog extends DialogWrapper {
protected void init() {
super.init();
final String urlString = myURL.toString();
- myRepositoryBrowser.setRepositoryURL(myURL, myIsShowFiles, new UrlOpeningExpander.Factory(urlString, urlString));
+ if (myAllowActions) {
+ // initialize repo browser this way - to make actions work correctly
+ myRepositoryBrowser.setRepositoryURLs(new SVNURL[]{myURL}, myIsShowFiles, new UrlOpeningExpander.Factory(urlString, urlString), true);
+ }
+ else {
+ myRepositoryBrowser.setRepositoryURL(myURL, myIsShowFiles, new UrlOpeningExpander.Factory(urlString, urlString));
+ }
myRepositoryBrowser.addChangeListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
getOKAction().setEnabled(isOKActionEnabled());
@@ -162,7 +181,10 @@ public class SelectLocationDialog extends DialogWrapper {
protected JComponent createCenterPanel() {
JPanel panel = new JPanel();
- panel.setLayout(new GridBagLayout());
+ panel.setLayout(new BorderLayout());
+
+ JPanel browserPanel = new JPanel();
+ browserPanel.setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.insets = new Insets(2, 2, 2, 2);
@@ -177,7 +199,7 @@ public class SelectLocationDialog extends DialogWrapper {
myRepositoryBrowser = new RepositoryBrowserComponent(SvnVcs.getInstance(myProject));
- panel.add(myRepositoryBrowser, gc);
+ browserPanel.add(myRepositoryBrowser, gc);
if (myDstName != null) {
gc.gridy += 1;
gc.gridwidth = 1;
@@ -187,7 +209,7 @@ public class SelectLocationDialog extends DialogWrapper {
gc.weighty = 0;
JLabel dstLabel = new JLabel(myDstLabel);
- panel.add(dstLabel, gc);
+ browserPanel.add(dstLabel, gc);
gc.gridx += 1;
gc.weightx = 1;
@@ -196,7 +218,7 @@ public class SelectLocationDialog extends DialogWrapper {
myDstText = new JTextField();
myDstText.setText(myDstName);
myDstText.selectAll();
- panel.add(myDstText, gc);
+ browserPanel.add(myDstText, gc);
myDstText.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
@@ -217,12 +239,25 @@ public class SelectLocationDialog extends DialogWrapper {
gc.gridy += 1;
gc.gridwidth = 2;
- panel.add(new JSeparator(), gc);
+ browserPanel.add(new JSeparator(), gc);
+ }
+
+ if (myAllowActions) {
+ panel.add(createToolbar(), BorderLayout.NORTH);
}
+ panel.add(browserPanel, BorderLayout.CENTER);
return panel;
}
+ @NotNull
+ private JComponent createToolbar() {
+ DefaultActionGroup group = new DefaultActionGroup();
+ group.add(new RepositoryBrowserDialog.EditLocationAction(myRepositoryBrowser));
+
+ return ActionManager.getInstance().createActionToolbar(RepositoryBrowserDialog.PLACE_TOOLBAR, group, true).getComponent();
+ }
+
public JComponent getPreferredFocusedComponent() {
return (JComponent)myRepositoryBrowser.getPreferredFocusedComponent();
}
@@ -246,4 +281,16 @@ public class SelectLocationDialog extends DialogWrapper {
public String getSelectedURL() {
return myRepositoryBrowser.getSelectedURL();
}
+
+ @Nullable
+ public SVNURL getRootUrl() {
+ RepositoryTreeNode node = myRepositoryBrowser.getSelectedNode();
+
+ // find the most top parent of type RepositoryTreeNode
+ while (node != null && node.getParent() instanceof RepositoryTreeNode) {
+ node = (RepositoryTreeNode)node.getParent();
+ }
+
+ return node != null ? node.getURL() : null;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SetPropertyDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SetPropertyDialog.java
index 28375d28b7ba..f2a58a0bd2da 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SetPropertyDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SetPropertyDialog.java
@@ -24,15 +24,16 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.properties.PropertyClient;
-import org.tmatesoft.svn.core.SVNPropertyValue;
+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.SVNURL;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -154,10 +155,10 @@ public class SetPropertyDialog extends DialogWrapper {
return;
}
File file = myFiles[0];
- SVNPropertyData property = !StringUtil.isEmpty(name) ? getProperty(file, name) : null;
+ PropertyValue property = !StringUtil.isEmpty(name) ? getProperty(file, name) : null;
if (property != null) {
- myValueText.setText(SVNPropertyValue.getPropertyAsString(property.getValue()));
+ myValueText.setText(property.toString());
myValueText.selectAll();
}
else {
@@ -165,19 +166,20 @@ public class SetPropertyDialog extends DialogWrapper {
}
}
- private SVNPropertyData getProperty(@NotNull File file, @NotNull String name) {
- SVNPropertyData property;
+ @Nullable
+ private PropertyValue getProperty(@NotNull File file, @NotNull String name) {
+ PropertyValue result;
try {
PropertyClient client = myVCS.getFactory(file).createPropertyClient();
- property = client.getProperty(SvnTarget.fromFile(file, SVNRevision.WORKING), name, false, SVNRevision.WORKING);
+ result = client.getProperty(SvnTarget.fromFile(file, SVNRevision.WORKING), name, false, SVNRevision.WORKING);
}
catch (VcsException e) {
LOG.info(e);
- property = null;
+ result = null;
}
- return property;
+ return result;
}
protected JComponent createCenterPanel() {
@@ -205,18 +207,18 @@ public class SetPropertyDialog extends DialogWrapper {
if (files.length == 1) {
File file = files[0];
try {
- ISVNPropertyHandler handler = new ISVNPropertyHandler() {
- public void handleProperty(File path, SVNPropertyData property) {
+ PropertyConsumer handler = new PropertyConsumer() {
+ public void handleProperty(File path, PropertyData property) {
String name = property.getName();
if (name != null) {
names.add(name);
}
}
- public void handleProperty(SVNURL url, SVNPropertyData property) {
+ public void handleProperty(SVNURL url, PropertyData property) {
}
- public void handleProperty(long revision, SVNPropertyData property) {
+ public void handleProperty(long revision, PropertyData property) {
}
};
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CmdDiffClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CmdDiffClient.java
index 497134727ee4..be084b0986d0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CmdDiffClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/CmdDiffClient.java
@@ -52,13 +52,14 @@ import java.util.List;
*/
public class CmdDiffClient extends BaseSvnClient implements DiffClient {
+ @NotNull
@Override
public List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException {
- assertUrl(target2);
- if (target1.isFile()) {
+ assertUrl(target1);
+ if (target2.isFile()) {
// Such combination (file and url) with "--summarize" option is supported only in svn 1.8.
// For svn 1.7 "--summarize" is only supported when both targets are repository urls.
- assertDirectory(target1);
+ assertDirectory(target2);
WorkingCopyFormat format = WorkingCopyFormat.from(myFactory.createVersionClient().getVersion());
if (format.less(WorkingCopyFormat.ONE_DOT_EIGHT)) {
@@ -95,6 +96,7 @@ public class CmdDiffClient extends BaseSvnClient implements DiffClient {
}
}
+ @NotNull
private List<Change> parseOutput(@NotNull SvnTarget target1, @NotNull SvnTarget target2, @NotNull CommandExecutor executor)
throws SvnBindException {
try {
@@ -114,16 +116,30 @@ public class CmdDiffClient extends BaseSvnClient implements DiffClient {
}
}
- private ContentRevision createRemoteRevision(@NotNull FilePath remotePath, @NotNull FilePath localPath, @NotNull FileStatus status) {
+ @NotNull
+ private ContentRevision createRevision(@NotNull FilePath path,
+ @NotNull FilePath localPath,
+ @NotNull SVNRevision revision,
+ @NotNull FileStatus status) {
+ ContentRevision result;
+
+ if (path.isNonLocal()) {
// explicitly use local path for deleted items - so these items will be correctly displayed as deleted under local working copy node
// and not as deleted under remote branch node (in ChangesBrowser)
// NOTE, that content is still retrieved using remotePath.
- return SvnRepositoryContentRevision
- .create(myVcs, remotePath, status == FileStatus.DELETED ? localPath : null, SVNRevision.HEAD.getNumber());
+ result = SvnRepositoryContentRevision.create(myVcs, path, status == FileStatus.DELETED ? localPath : null, revision.getNumber());
+ }
+ else {
+ result = CurrentContentRevision.create(path);
}
- private static ContentRevision createLocalRevision(@NotNull FilePath path) {
- return CurrentContentRevision.create(path);
+ return result;
+ }
+
+ private static FilePath createFilePath(@NotNull SvnTarget target, boolean isDirectory) {
+ return target.isFile()
+ ? VcsUtil.getFilePath(target.getFile(), isDirectory)
+ : VcsUtil.getFilePathOnNonLocal(SvnUtil.toDecodedString(target), isDirectory);
}
@NotNull
@@ -134,9 +150,7 @@ public class CmdDiffClient extends BaseSvnClient implements DiffClient {
// TODO: 3) Properties change is currently not added as part of result change like in SvnChangeProviderContext.patchWithPropertyChange
SvnTarget subTarget1 = SvnUtil.append(target1, diffPath.path, true);
- String relativePath = target1.isFile()
- ? FileUtil.getRelativePath(target1.getFile(), subTarget1.getFile())
- : SvnUtil.getRelativeUrl(SvnUtil.toDecodedString(target1), SvnUtil.toDecodedString(subTarget1));
+ String relativePath = SvnUtil.getRelativeUrl(SvnUtil.toDecodedString(target1), SvnUtil.toDecodedString(subTarget1));
if (relativePath == null) {
throw new SvnBindException("Could not get relative path for " + target1 + " and " + subTarget1);
@@ -144,27 +158,19 @@ public class CmdDiffClient extends BaseSvnClient implements DiffClient {
SvnTarget subTarget2 = SvnUtil.append(target2, FileUtil.toSystemIndependentName(relativePath));
- FilePath target1Path = target1.isFile()
- ? VcsUtil.getFilePath(subTarget1.getFile(), diffPath.isDirectory())
- : VcsUtil.getFilePathOnNonLocal(SvnUtil.toDecodedString(subTarget1), diffPath.isDirectory());
- FilePath target2Path = VcsUtil.getFilePathOnNonLocal(SvnUtil.toDecodedString(subTarget2), diffPath.isDirectory());
+ FilePath target1Path = createFilePath(subTarget1, diffPath.isDirectory());
+ FilePath target2Path = createFilePath(subTarget2, diffPath.isDirectory());
FileStatus status = SvnStatusConvertor
.convertStatus(SvnStatusHandler.getStatus(diffPath.itemStatus), SvnStatusHandler.getStatus(diffPath.propertiesStatus));
- // for "file + url" pair - statuses determine changes needs to be done to "url" to get "file" state
- // for "url1 + url2" pair - statuses determine changes needs to be done to "url1" to get "url2" state
+ // statuses determine changes needs to be done to "target1" to get "target2" state
ContentRevision beforeRevision = status == FileStatus.ADDED
? null
- : target1.isFile()
- ? createRemoteRevision(target2Path, target1Path, status)
- : createRemoteRevision(target1Path, target2Path, status);
+ : createRevision(target1Path, target2Path, target1.getPegRevision(), status);
ContentRevision afterRevision = status == FileStatus.DELETED
? null
- : target1.isFile()
- ? createLocalRevision(target1Path)
- : createRemoteRevision(target2Path, target1Path, status);
-
+ : createRevision(target2Path, target1Path, target2.getPegRevision(), status);
return createChange(status, beforeRevision, afterRevision);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DiffClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DiffClient.java
index 35c35e9313f1..dfa43ddcb4bd 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DiffClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DiffClient.java
@@ -29,6 +29,11 @@ import java.util.List;
*/
public interface DiffClient extends SvnClient {
+ /**
+ * @param target1 Should always be url.
+ * @param target2 Could be either url or file. And should be directory if file.
+ */
+ @NotNull
List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException;
void unifiedDiff(@NotNull SvnTarget target1, @NotNull SvnTarget target2, @NotNull OutputStream output) throws VcsException;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DirectoryWithBranchComparer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DirectoryWithBranchComparer.java
index 0f0e6a714037..784548d9e661 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DirectoryWithBranchComparer.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/DirectoryWithBranchComparer.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnBundle;
+import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.jetbrains.idea.svn.api.ClientFactory;
import org.tmatesoft.svn.core.SVNException;
@@ -53,19 +54,24 @@ public class DirectoryWithBranchComparer extends ElementWithBranchComparer {
titleBuilder.append(SvnBundle.message("repository.browser.compare.title", myElementUrl,
FileUtil.toSystemDependentName(myVirtualFile.getPresentableUrl())));
- SvnTarget target1 = SvnTarget.fromFile(new File(myVirtualFile.getPath()));
- SvnTarget target2 = SvnTarget.fromURL(myElementUrl);
+ SvnTarget target1 = SvnTarget.fromURL(myElementUrl);
+ SvnTarget target2 = SvnTarget.fromFile(new File(myVirtualFile.getPath()));
changes.addAll(getClientFactory().createDiffClient().compare(target1, target2));
}
@NotNull
private ClientFactory getClientFactory() {
- WorkingCopyFormat format = myVcs.getWorkingCopyFormat(VfsUtilCore.virtualToIoFile(myVirtualFile));
+ return getClientFactory(myVcs, VfsUtilCore.virtualToIoFile(myVirtualFile));
+ }
+
+ @NotNull
+ public static ClientFactory getClientFactory(@NotNull SvnVcs vcs, @NotNull File file) {
+ WorkingCopyFormat format = vcs.getWorkingCopyFormat(file);
// svn 1.7 command line "--summarize" option for "diff" command does not support comparing working copy directories with repository
// directories - that is why command line is only used explicitly for svn 1.8
- return format.isOrGreater(WorkingCopyFormat.ONE_DOT_EIGHT) ? myVcs.getCommandLineFactory() : myVcs.getSvnKitFactory();
+ return format.isOrGreater(WorkingCopyFormat.ONE_DOT_EIGHT) ? vcs.getCommandLineFactory() : vcs.getSvnKitFactory();
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/SvnKitDiffClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/SvnKitDiffClient.java
index 0a1b14837b7e..ec4c51288cc2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/SvnKitDiffClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/diff/SvnKitDiffClient.java
@@ -54,6 +54,7 @@ import java.util.List;
*/
public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
+ @NotNull
@Override
public List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException {
DiffExecutor executor = new DiffExecutor(target1, target2);
@@ -99,12 +100,12 @@ public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
}
public void run() throws SVNException {
- assertUrl(myTarget2);
+ assertUrl(myTarget1);
- if (myTarget1.isFile()) {
- assertDirectory(myTarget1);
+ if (myTarget2.isFile()) {
+ assertDirectory(myTarget2);
- WorkingCopyFormat format = myVcs.getWorkingCopyFormat(myTarget1.getFile());
+ WorkingCopyFormat format = myVcs.getWorkingCopyFormat(myTarget2.getFile());
myChanges.addAll(WorkingCopyFormat.ONE_DOT_SIX.equals(format) ? run16Diff() : run17Diff());
}
else {
@@ -142,20 +143,20 @@ public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
}
private Collection<Change> run17Diff() throws SVNException {
- final Info info1 = myVcs.getInfo(myTarget1.getFile(), SVNRevision.HEAD);
+ final Info info1 = myVcs.getInfo(myTarget2.getFile(), SVNRevision.HEAD);
if (info1 == null) {
SVNErrorMessage err =
- SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", myTarget1);
+ SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", myTarget2);
SVNErrorManager.error(err, SVNLogType.WC);
}
else if (info1.getURL() == null) {
- SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", myTarget1);
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", myTarget2);
SVNErrorManager.error(err, SVNLogType.WC);
}
final SVNReporter17 reporter17 =
- new SVNReporter17(myTarget1.getFile(), new SVNWCContext(myVcs.getSvnKitManager().getSvnOptions(), new ISVNEventHandler() {
+ new SVNReporter17(myTarget2.getFile(), new SVNWCContext(myVcs.getSvnKitManager().getSvnOptions(), new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
}
@@ -169,9 +170,9 @@ public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
try {
repository = myVcs.getSvnKitManager().createRepository(info1.getURL());
long rev = repository.getLatestRevision();
- repository2 = myVcs.getSvnKitManager().createRepository(myTarget2.getURL());
- SvnDiffEditor diffEditor = new SvnDiffEditor(myTarget1.getFile(), repository2, rev, true);
- repository.diff(myTarget2.getURL(), rev, rev, null, true, SVNDepth.INFINITY, false, reporter17,
+ repository2 = myVcs.getSvnKitManager().createRepository(myTarget1.getURL());
+ SvnDiffEditor diffEditor = new SvnDiffEditor(myTarget2.getFile(), repository2, rev, true);
+ repository.diff(myTarget1.getURL(), rev, rev, null, true, SVNDepth.INFINITY, false, reporter17,
SVNCancellableEditor.newInstance(diffEditor, new SvnKitProgressCanceller(), null));
return diffEditor.getChangesMap().values();
@@ -193,7 +194,7 @@ public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
SVNRepository repository = null;
SVNRepository repository2 = null;
try {
- SVNAdminAreaInfo info = wcAccess.openAnchor(myTarget1.getFile(), false, SVNWCAccess.INFINITE_DEPTH);
+ SVNAdminAreaInfo info = wcAccess.openAnchor(myTarget2.getFile(), false, SVNWCAccess.INFINITE_DEPTH);
File anchorPath = info.getAnchor().getRoot();
String target = "".equals(info.getTargetName()) ? null : info.getTargetName();
@@ -215,10 +216,10 @@ public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
repository = myVcs.getSvnKitManager().createRepository(anchorURL.toString());
long rev = repository.getLatestRevision();
repository2 =
- myVcs.getSvnKitManager().createRepository((target == null) ? myTarget2.getURL() : myTarget2.getURL().removePathTail());
+ myVcs.getSvnKitManager().createRepository((target == null) ? myTarget1.getURL() : myTarget1.getURL().removePathTail());
SvnDiffEditor diffEditor =
- new SvnDiffEditor(target == null ? myTarget1.getFile() : myTarget1.getFile().getParentFile(), repository2, rev, true);
- repository.diff(myTarget2.getURL(), rev, rev, target, true, true, false, reporter,
+ new SvnDiffEditor(target == null ? myTarget2.getFile() : myTarget2.getFile().getParentFile(), repository2, rev, true);
+ repository.diff(myTarget1.getURL(), rev, rev, target, true, true, false, reporter,
SVNCancellableEditor.newInstance(diffEditor, new SvnKitProgressCanceller(), null));
return diffEditor.getChangesMap().values();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnDiffFromHistoryHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnDiffFromHistoryHandler.java
new file mode 100644
index 000000000000..be112127ecc9
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnDiffFromHistoryHandler.java
@@ -0,0 +1,80 @@
+/*
+ * 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.history;
+
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.history.BaseDiffFromHistoryHandler;
+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.ClientFactory;
+import org.jetbrains.idea.svn.diff.DirectoryWithBranchComparer;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnDiffFromHistoryHandler extends BaseDiffFromHistoryHandler<SvnFileRevision> {
+
+ @NotNull private final SvnVcs myVcs;
+
+ public SvnDiffFromHistoryHandler(@NotNull SvnVcs vcs) {
+ super(vcs.getProject());
+ myVcs = vcs;
+ }
+
+ @NotNull
+ @Override
+ protected List<Change> getChangesBetweenRevisions(@NotNull FilePath path, @NotNull SvnFileRevision rev1, @Nullable SvnFileRevision rev2)
+ throws VcsException {
+ File file = path.getIOFile();
+ SvnTarget target1 = SvnTarget.fromURL(SvnUtil.createUrl(rev1.getURL()), rev1.getRevision());
+ SvnTarget target2 = rev2 != null ? SvnTarget.fromURL(SvnUtil.createUrl(rev2.getURL()), rev2.getRevision()) : SvnTarget.fromFile(file);
+
+ return executeDiff(path, target1, target2);
+ }
+
+ @NotNull
+ @Override
+ protected List<Change> getAffectedChanges(@NotNull FilePath path, @NotNull SvnFileRevision rev) throws VcsException {
+ // Diff with zero revision is used here to get just affected changes under the path, and not all affected changes of the revision.
+ SvnTarget target1 = SvnTarget.fromURL(SvnUtil.createUrl(rev.getURL()), SVNRevision.create(0));
+ SvnTarget target2 = SvnTarget.fromURL(SvnUtil.createUrl(rev.getURL()), rev.getRevision());
+
+ return executeDiff(path, target1, target2);
+ }
+
+ @NotNull
+ @Override
+ protected String getPresentableName(@NotNull SvnFileRevision revision) {
+ return revision.getRevisionNumber().asString();
+ }
+
+ @NotNull
+ private List<Change> executeDiff(@NotNull FilePath path, @NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException {
+ File file = path.getIOFile();
+ ClientFactory factory = target2.isURL() ? myVcs.getFactory(file) : DirectoryWithBranchComparer.getClientFactory(myVcs, file);
+
+ return factory.createDiffClient().compare(target1, target2);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
index d2b820607ff4..8d1830763fc6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
@@ -40,8 +40,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -145,7 +145,7 @@ public class SvnEditCommitMessageAction extends AnAction {
}
SvnTarget target = SvnTarget.fromURL(root);
myVcs.getFactory(target).createPropertyClient()
- .setRevisionProperty(target, SvnPropertyKeys.LOG, SVNRevision.create(myNumber), SVNPropertyValue.create(myNewMessage), false);
+ .setRevisionProperty(target, SvnPropertyKeys.LOG, SVNRevision.create(myNumber), PropertyValue.create(myNewMessage), false);
}
catch (SVNException e) {
myException = new VcsException(e);
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 9e9dd7e1befc..b23b57772535 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -73,7 +73,7 @@ public class SvnHistoryProvider
@Override
public DiffFromHistoryHandler getHistoryDiffHandler() {
- return null;
+ return new SvnDiffFromHistoryHandler(myVcs);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
index f2f91bceec14..8ae2da7cf8b3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
@@ -77,11 +77,6 @@ public class SvnHistorySession extends VcsAbstractHistorySession {
return myCommittedPath;
}
- @Override
- public boolean isContentAvailable(final VcsFileRevision revision) {
- return !myCommittedPath.isDirectory();
- }
-
public boolean isHaveMergeSources() {
return myHaveMergeSources;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
index 8a9dbf760922..e0bdc15f78b1 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java
@@ -24,8 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
-import org.tmatesoft.svn.core.SVNPropertyValue;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -68,7 +67,7 @@ public class SvnPropertyService {
protected final boolean myCanUseCachedProperty;
protected abstract void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data,
- final SVNPropertyValue propertyValue) throws VcsException;
+ final PropertyValue propertyValue) throws VcsException;
protected abstract void onAfterProcessing(final VirtualFile[] file) throws VcsException;
@@ -92,14 +91,12 @@ public class SvnPropertyService {
}
final File dir = new File(entry.getKey().getPath());
try {
- final SVNPropertyValue value;
+ final PropertyValue value;
if (myCanUseCachedProperty) {
value = myVcs.getPropertyWithCaching(entry.getKey(), SvnPropertyKeys.SVN_IGNORE);
} else {
- final SVNPropertyData data =
- myVcs.getFactory(dir).createPropertyClient()
- .getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING);
- value = data == null ? null : data.getValue();
+ value = myVcs.getFactory(dir).createPropertyClient()
+ .getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING);
}
processFolder(entry.getKey(), dir, entry.getValue(), value);
}
@@ -127,7 +124,7 @@ public class SvnPropertyService {
return (! myFilesOk) && (! myExtensionOk);
}
- protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
+ protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final PropertyValue propertyValue)
throws VcsException {
if (propertyValue == null) {
myFilesOk = false;
@@ -135,7 +132,7 @@ public class SvnPropertyService {
return;
}
final Set<String> ignorePatterns = new HashSet<String>();
- final StringTokenizer st = new StringTokenizer(SVNPropertyValue.getPropertyAsString(propertyValue), "\r\n ");
+ final StringTokenizer st = new StringTokenizer(PropertyValue.toString(propertyValue), "\r\n ");
while (st.hasMoreElements()) {
final String ignorePattern = (String)st.nextElement();
ignorePatterns.add(ignorePattern);
@@ -180,14 +177,14 @@ public class SvnPropertyService {
return false;
}
- protected abstract String getNewPropertyValue(final Set<String> data, final SVNPropertyValue propertyValue);
+ protected abstract String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue);
- protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final SVNPropertyValue propertyValue)
+ protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final PropertyValue propertyValue)
throws VcsException {
String newValue = getNewPropertyValue(data, propertyValue);
newValue = (newValue.trim().isEmpty()) ? null : newValue;
myVcs.getFactory(folderDir).createPropertyClient()
- .setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), Depth.EMPTY, false);
+ .setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, PropertyValue.create(newValue), Depth.EMPTY, false);
if (myUseCommonExtension) {
dirtyScopeManager.dirDirtyRecursively(folder);
@@ -216,9 +213,9 @@ public class SvnPropertyService {
super(activeVcs, project, useCommonExtension);
}
- protected String getNewPropertyValue(final Set<String> data, final SVNPropertyValue propertyValue) {
+ protected String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue) {
if (propertyValue != null) {
- return getNewPropertyValueForRemove(data, SVNPropertyValue.getPropertyAsString(propertyValue));
+ return getNewPropertyValueForRemove(data, PropertyValue.toString(propertyValue));
}
return "";
}
@@ -241,7 +238,7 @@ public class SvnPropertyService {
super(activeVcs, project, useCommonExtension);
}
- protected String getNewPropertyValue(final Set<String> data, final SVNPropertyValue propertyValue) {
+ protected String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue) {
final String ignoreString;
if (data.size() == 1) {
ignoreString = data.iterator().next();
@@ -252,7 +249,7 @@ public class SvnPropertyService {
}
ignoreString = sb.toString();
}
- return (propertyValue == null) ? ignoreString : (SVNPropertyValue.getPropertyAsString(propertyValue) + '\n' + ignoreString);
+ return (propertyValue == null) ? ignoreString : (PropertyValue.toString(propertyValue) + '\n' + ignoreString);
}
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java
index b6228fca921d..1e031e20d408 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java
@@ -20,7 +20,10 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
-import com.intellij.openapi.vcs.changes.*;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangeList;
+import com.intellij.openapi.vcs.changes.ChangesUtil;
+import com.intellij.openapi.vcs.changes.EmptyChangelistBuilder;
import com.intellij.openapi.vcs.update.UpdatedFilesReverseSide;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
@@ -28,12 +31,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
-import java.util.*;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
public class GatheringChangelistBuilder extends EmptyChangelistBuilder {
@@ -92,13 +97,13 @@ public class GatheringChangelistBuilder extends EmptyChangelistBuilder {
SvnTarget target = SvnTarget.fromFile(file);
try {
- SVNPropertyData current =
+ PropertyValue current =
myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.WORKING);
- SVNPropertyData base =
+ PropertyValue base =
myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.BASE);
if (current != null) {
- return base == null || !Comparing.equal(current.getValue(), base.getValue());
+ return base == null || !Comparing.equal(current, base);
}
}
catch (VcsException e) {
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 62638291b485..701bb2575001 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
@@ -22,10 +22,10 @@ import com.intellij.util.containers.MultiMap;
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.internal.util.SVNMergeInfoUtil;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -205,7 +205,7 @@ public class BranchInfo {
return SvnMergeInfoCache.MergeCheckResult.getInstance(mergeInfo.contains(revisionAsked));
}
- final SVNPropertyData mergeinfoProperty;
+ final PropertyValue mergeinfoProperty;
SvnTarget target = SvnTarget.fromURL(branchUrl);
try {
@@ -235,7 +235,7 @@ public class BranchInfo {
return goUpInRepo(revisionAsked, targetRevision, newBranchUrl, newTrunkUrl);
}
// process
- return processMergeinfoProperty(keyString, revisionAsked, mergeinfoProperty.getValue(), trunkUrl, false);
+ return processMergeinfoProperty(keyString, revisionAsked, mergeinfoProperty, trunkUrl, false);
}
private Info getInfo(final File pathFile) {
@@ -277,7 +277,7 @@ public class BranchInfo {
return SvnMergeInfoCache.MergeCheckResult.getInstance(merged);
}
- final SVNPropertyData mergeinfoProperty;
+ final PropertyValue mergeinfoProperty;
try {
if (actualRevision == targetRevisionCorrected) {
// look in WC
@@ -302,11 +302,11 @@ public class BranchInfo {
return goUp(revisionAsked, targetRevisionCorrected, branchRootPath, path, trunkUrl);
}
// process
- return processMergeinfoProperty(keyString, revisionAsked, mergeinfoProperty.getValue(), trunkUrl, self);
+ return processMergeinfoProperty(keyString, revisionAsked, mergeinfoProperty, trunkUrl, self);
}
private SvnMergeInfoCache.MergeCheckResult processMergeinfoProperty(final String pathWithRevisionNumber, final long revisionAsked,
- final SVNPropertyValue value, final String trunkRelativeUrl,
+ final PropertyValue value, final String trunkRelativeUrl,
final boolean self) {
final String valueAsString = value.toString().trim();
@@ -318,7 +318,7 @@ public class BranchInfo {
final Map<String, SVNMergeRangeList> map;
try {
- map = SVNMergeInfoUtil.parseMergeInfo(new StringBuffer(replaceSeparators(value.getString())), null);
+ map = SVNMergeInfoUtil.parseMergeInfo(new StringBuffer(replaceSeparators(value.toString())), null);
}
catch (SVNException e) {
LOG.info(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 0ea95c99c4d4..225bc6ad0396 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/OneRecursiveShotMergeInfoWorker.java
@@ -23,11 +23,12 @@ import com.intellij.util.PairProcessor;
import org.jetbrains.annotations.NotNull;
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.internal.util.SVNMergeInfoUtil;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -63,19 +64,19 @@ public class OneRecursiveShotMergeInfoWorker implements MergeInfoWorker {
public void prepare() throws VcsException {
final Depth depth = Depth.allOrEmpty(myMergeContext.getVcs().getSvnConfiguration().isCheckNestedForQuickMerge());
- ISVNPropertyHandler handler = new ISVNPropertyHandler() {
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ PropertyConsumer handler = new PropertyConsumer() {
+ public void handleProperty(File path, PropertyData property) throws SVNException {
final String key = keyFromFile(path);
synchronized (myLock) {
myDataMap.put(key, SVNMergeInfoUtil
- .parseMergeInfo(new StringBuffer(replaceSeparators(SVNPropertyValue.getPropertyAsString(property.getValue()))), null));
+ .parseMergeInfo(new StringBuffer(replaceSeparators(PropertyValue.toString(property.getValue()))), null));
}
}
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ public void handleProperty(SVNURL url, PropertyData property) throws SVNException {
}
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ public void handleProperty(long revision, PropertyData property) throws SVNException {
}
};
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 e855abe1ec2e..e053776d14ce 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
@@ -10,9 +10,8 @@ import org.jetbrains.idea.svn.commandLine.CommandExecutor;
import org.jetbrains.idea.svn.commandLine.CommandUtil;
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
import org.jetbrains.idea.svn.info.Info;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
+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;
@@ -24,6 +23,7 @@ import javax.xml.bind.annotation.XmlValue;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* @author Konstantin Kolosovsky.
@@ -32,10 +32,10 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
@Nullable
@Override
- public SVNPropertyData getProperty(@NotNull SvnTarget target,
- @NotNull String property,
- boolean revisionProperty,
- @Nullable SVNRevision revision)
+ public PropertyValue getProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision revision)
throws VcsException {
List<String> parameters = new ArrayList<String>();
@@ -57,7 +57,9 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
parameters.add("--xml");
CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null);
- return parseSingleProperty(target, command.getOutput());
+ PropertyData data = parseSingleProperty(target, command.getOutput());
+
+ return data != null ? data.getValue() : null;
}
@Override
@@ -65,7 +67,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
@NotNull String property,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException {
+ @Nullable PropertyConsumer handler) throws VcsException {
List<String> parameters = new ArrayList<String>();
parameters.add(property);
@@ -79,7 +81,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
public void list(@NotNull SvnTarget target,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException {
+ @Nullable PropertyConsumer handler) throws VcsException {
List<String> parameters = new ArrayList<String>();
fillListParameters(target, revision, depth, parameters, true);
@@ -90,39 +92,39 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
@Override
public void setProperty(@NotNull File file,
@NotNull String property,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
@Nullable Depth depth,
boolean force) throws VcsException {
runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force);
}
@Override
- public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException {
- SVNProperties currentProperties = collectPropertiesToDelete(file);
+ public void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException {
+ PropertiesMap currentProperties = collectPropertiesToDelete(file);
currentProperties.putAll(properties);
- for (String propertyName : currentProperties.nameSet()) {
- setProperty(file, propertyName, currentProperties.getSVNPropertyValue(propertyName), Depth.EMPTY, true);
+ for (Map.Entry<String, PropertyValue> entry : currentProperties.entrySet()) {
+ setProperty(file, entry.getKey(), entry.getValue(), Depth.EMPTY, true);
}
}
@NotNull
- private SVNProperties collectPropertiesToDelete(@NotNull File file) throws VcsException {
- final SVNProperties result = new SVNProperties();
+ private PropertiesMap collectPropertiesToDelete(@NotNull File file) throws VcsException {
+ final PropertiesMap result = new PropertiesMap();
- list(SvnTarget.fromFile(file), null, Depth.EMPTY, new ISVNPropertyHandler() {
+ list(SvnTarget.fromFile(file), null, Depth.EMPTY, new PropertyConsumer() {
@Override
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ public void handleProperty(File path, PropertyData property) throws SVNException {
// null indicates property will be deleted
- result.put(property.getName(), (SVNPropertyValue)null);
+ result.put(property.getName(), null);
}
@Override
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ public void handleProperty(SVNURL url, PropertyData property) throws SVNException {
}
@Override
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ public void handleProperty(long revision, PropertyData property) throws SVNException {
}
});
@@ -133,7 +135,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
public void setRevisionProperty(@NotNull SvnTarget target,
@NotNull String property,
@NotNull SVNRevision revision,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
boolean force) throws VcsException {
runSetProperty(target, property, revision, null, value, force);
}
@@ -142,7 +144,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
@NotNull String property,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
boolean force) throws VcsException {
List<String> parameters = new ArrayList<String>();
boolean isDelete = value == null;
@@ -153,7 +155,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
CommandUtil.put(parameters, revision);
}
if (!isDelete) {
- parameters.add(SVNPropertyValue.getPropertyAsString(value));
+ parameters.add(PropertyValue.toString(value));
// --force could only be used in "propset" command, but not in "propdel" command
CommandUtil.put(parameters, force, "--force");
}
@@ -180,21 +182,22 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
CommandUtil.put(parameters, verbose, "--verbose");
}
- private SVNPropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException {
- final SVNPropertyData[] data = new SVNPropertyData[1];
- ISVNPropertyHandler handler = new ISVNPropertyHandler() {
+ @Nullable
+ private PropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException {
+ final PropertyData[] data = new PropertyData[1];
+ PropertyConsumer handler = new PropertyConsumer() {
@Override
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ public void handleProperty(File path, PropertyData property) throws SVNException {
data[0] = property;
}
@Override
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ public void handleProperty(SVNURL url, PropertyData property) throws SVNException {
data[0] = property;
}
@Override
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ public void handleProperty(long revision, PropertyData property) throws SVNException {
data[0] = property;
}
};
@@ -204,7 +207,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
return data[0];
}
- private static void parseOutput(SvnTarget target, String output, ISVNPropertyHandler handler) throws VcsException {
+ private static void parseOutput(SvnTarget target, String output, PropertyConsumer handler) throws VcsException {
try {
Properties properties = CommandUtil.parse(output, Properties.class);
@@ -231,7 +234,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
}
- private static void invokeHandler(@NotNull SvnTarget target, @Nullable SVNPropertyData data, @Nullable ISVNPropertyHandler handler)
+ private static void invokeHandler(@NotNull SvnTarget target, @Nullable PropertyData data, @Nullable PropertyConsumer handler)
throws SVNException {
if (handler != null && data != null) {
if (target.isFile()) {
@@ -242,7 +245,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
}
- private static void invokeHandler(long revision, @Nullable SVNPropertyData data, @Nullable ISVNPropertyHandler handler)
+ private static void invokeHandler(long revision, @Nullable PropertyData data, @Nullable PropertyConsumer handler)
throws SVNException {
if (handler != null && data != null) {
handler.handleProperty(revision, data);
@@ -250,13 +253,13 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
@Nullable
- private static SVNPropertyData create(@NotNull String property, @Nullable String value) {
- SVNPropertyData result = null;
+ private static PropertyData create(@NotNull String property, @Nullable String value) {
+ PropertyData result = null;
// such behavior is required to compatibility with SVNKit as some logic in merge depends on
// whether null property data or property data with empty string value is returned
if (value != null) {
- result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), LF_SEPARATOR_OPTIONS);
+ result = new PropertyData(property, PropertyValue.create(value.trim()));
}
return result;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java
new file mode 100644
index 000000000000..b3ec74e397cb
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java
@@ -0,0 +1,106 @@
+/*
+ * 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.properties;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class ExternalsDefinitionParser {
+
+ /**
+ * Parses "svn:externals" property in format starting from svn 1.5.
+ *
+ * @return map of externals definitions: key - relative directory, value - corresponding complete externals definition.
+ */
+ @NotNull
+ public static Map<String, String> parseExternalsProperty(@NotNull String externals) throws SvnBindException {
+ HashMap<String, String> map = ContainerUtil.newHashMap();
+
+ for (String external : StringUtil.splitByLines(externals, true)) {
+ map.put(parseRelativeDirectory(external), external);
+ }
+
+ return map;
+ }
+
+ /**
+ * Parses relative directory from externals definition (in format starting from svn 1.5). Restrictions for relative directory:
+ * - is at the end of externals definition separated from other parameters by ' ' char
+ * - could be quoted with '"' char
+ * - certain chars could be escaped with '\' char
+ */
+ @NotNull
+ public static String parseRelativeDirectory(@NotNull String s) throws SvnBindException {
+ s = s.trim();
+
+ int length = s.length();
+ String result;
+
+ if (isUnescapedQuote(s, length - 1)) {
+ int index = lastUnescapedIndexOf(s, length - 1, '"');
+ assertIndex(s, index, "Could not find start quote");
+ result = s.substring(index + 1, length - 1);
+ }
+ else {
+ int index = lastUnescapedIndexOf(s, length, ' ');
+ assertIndex(s, index, "Could not find separating space");
+ result = s.substring(index + 1);
+ }
+
+ return unescape(result);
+ }
+
+ private static void assertIndex(@NotNull String s, int index, @NotNull String message) throws SvnBindException {
+ if (index < 0) {
+ throw new SvnBindException(message + " - " + s);
+ }
+ }
+
+ @NotNull
+ private static String unescape(@NotNull String s) {
+ return s.replace("\\", "");
+ }
+
+ /**
+ * "from" index is excluded.
+ */
+ private static int lastUnescapedIndexOf(@NotNull String s, int from, char c) {
+ int result = from;
+
+ do {
+ result = s.lastIndexOf(c, result - 1);
+ }
+ while (result != -1 && !isUnescaped(s, result, c));
+
+ return result;
+ }
+
+ private static boolean isUnescapedQuote(@NotNull String s, int index) {
+ return isUnescaped(s, index, '"');
+ }
+
+ private static boolean isUnescaped(@NotNull String s, int index, char c) {
+ return StringUtil.isChar(s, index, c) && !StringUtil.isChar(s, index - 1, '\\');
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java
new file mode 100644
index 000000000000..c5857aa4b345
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java
@@ -0,0 +1,24 @@
+/*
+ * 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.properties;
+
+import com.intellij.util.containers.HashMap;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class PropertiesMap extends HashMap<String, PropertyValue> {
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
index 1b61d59c0e20..42acfc8109d7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
@@ -1,18 +1,10 @@
package org.jetbrains.idea.svn.properties;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.SvnClient;
-import org.tmatesoft.svn.core.SVNProperties;
-import org.tmatesoft.svn.core.SVNPropertyValue;
-import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
-import org.tmatesoft.svn.core.wc.ISVNOptions;
-import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
-import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -23,40 +15,33 @@ import java.io.File;
*/
public interface PropertyClient extends SvnClient {
- ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() {
- @Override
- public byte[] getNativeEOL() {
- return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString());
- }
- };
-
@Nullable
- SVNPropertyData getProperty(@NotNull final SvnTarget target,
- @NotNull final String property,
- boolean revisionProperty,
- @Nullable SVNRevision revision) throws VcsException;
+ PropertyValue getProperty(@NotNull final SvnTarget target,
+ @NotNull final String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision revision) throws VcsException;
void getProperty(@NotNull SvnTarget target, @NotNull String property,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException;
+ @Nullable PropertyConsumer handler) throws VcsException;
void list(@NotNull SvnTarget target,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException;
+ @Nullable PropertyConsumer handler) throws VcsException;
void setProperty(@NotNull File file,
@NotNull String property,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
@Nullable Depth depth,
boolean force) throws VcsException;
- void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException;
+ void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException;
void setRevisionProperty(@NotNull SvnTarget target,
@NotNull String property,
@NotNull SVNRevision revision,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
boolean force) throws VcsException;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java
new file mode 100644
index 000000000000..f45e09df39d5
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java
@@ -0,0 +1,33 @@
+/*
+ * 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.properties;
+
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface PropertyConsumer {
+
+ void handleProperty(File path, PropertyData property) throws SVNException;
+
+ void handleProperty(SVNURL url, PropertyData property) throws SVNException;
+
+ void handleProperty(long revision, PropertyData property) throws SVNException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java
new file mode 100644
index 000000000000..3953636d870c
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java
@@ -0,0 +1,53 @@
+/*
+ * 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.properties;
+
+import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class PropertyData {
+
+ private final PropertyValue myValue;
+
+ private final String myName;
+
+ public PropertyData(String name, PropertyValue value) {
+ myName = name;
+ myValue = value;
+ }
+
+ public String getName() {
+ return myName;
+ }
+
+ public PropertyValue getValue() {
+ return myValue;
+ }
+
+ @Nullable
+ public static PropertyData create(@Nullable SVNPropertyData data) {
+ PropertyData result = null;
+
+ if (data != null) {
+ result = new PropertyData(data.getName(), PropertyValue.create(data.getValue()));
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java
new file mode 100644
index 000000000000..62cb7cbd0340
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java
@@ -0,0 +1,53 @@
+/*
+ * 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.properties;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.SVNPropertyValue;
+
+/**
+ * TODO: Add correct support of binary properties - support in api, diff, etc.
+ *
+ * @author Konstantin Kolosovsky.
+ */
+public class PropertyValue {
+
+ @NotNull private final String myValue;
+
+ @Nullable
+ public static PropertyValue create(@Nullable SVNPropertyValue value) {
+ return create(SVNPropertyValue.getPropertyAsString(value));
+ }
+
+ private PropertyValue(@NotNull String propertyValue) {
+ myValue = propertyValue;
+ }
+
+ @Nullable
+ public static PropertyValue create(@Nullable String propertyValue) {
+ return propertyValue == null ? null : new PropertyValue(propertyValue);
+ }
+
+ @Nullable
+ public static String toString(@Nullable PropertyValue value) {
+ return value == null ? null : value.myValue;
+ }
+
+ public String toString() {
+ return myValue;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
index 4ad3f10afccc..23fedd3c7ac8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
@@ -1,42 +1,57 @@
package org.jetbrains.idea.svn.properties;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.api.BaseSvnClient;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
+import java.util.Map;
/**
* @author Konstantin Kolosovsky.
*/
public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClient {
+ public static final ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() {
+ @Override
+ public byte[] getNativeEOL() {
+ return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString());
+ }
+ };
+
@Nullable
@Override
- public SVNPropertyData getProperty(@NotNull SvnTarget target,
- @NotNull String property,
- boolean revisionProperty,
- @Nullable SVNRevision revision) throws VcsException {
+ public PropertyValue getProperty(@NotNull SvnTarget target,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision revision) throws VcsException {
+ PropertyData resultData;
+
try {
if (!revisionProperty) {
if (target.isFile()) {
- return createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision);
+ resultData = PropertyData.create(createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision));
} else {
- return createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision);
+ resultData = PropertyData.create(createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision));
}
} else {
- return getRevisionProperty(target, property, revision);
+ resultData = getRevisionProperty(target, property, revision);
}
}
catch (SVNException e) {
throw new VcsException(e);
}
+
+ return resultData != null ? resultData.getValue() : null;
}
@NotNull
@@ -52,7 +67,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
@NotNull String property,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException {
+ @Nullable PropertyConsumer handler) throws VcsException {
runGetProperty(target, property, revision, depth, handler);
}
@@ -60,18 +75,18 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
public void list(@NotNull SvnTarget target,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException {
+ @Nullable PropertyConsumer handler) throws VcsException {
runGetProperty(target, null, revision, depth, handler);
}
@Override
public void setProperty(@NotNull File file,
@NotNull String property,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
@Nullable Depth depth,
boolean force) throws VcsException {
try {
- createClient().doSetProperty(file, property, value, force, toDepth(depth), null, null);
+ createClient().doSetProperty(file, property, toPropertyValue(value), force, toDepth(depth), null, null);
}
catch (SVNException e) {
throw new SvnBindException(e);
@@ -79,12 +94,13 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
}
@Override
- public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException {
+ public void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException {
+ final SVNProperties propertiesToSet = toSvnProperties(properties);
try {
createClient().doSetProperty(file, new ISVNPropertyValueProvider() {
@Override
public SVNProperties providePropertyValues(File path, SVNProperties properties) throws SVNException {
- return properties;
+ return propertiesToSet;
}
}, true, SVNDepth.EMPTY, null, null);
}
@@ -97,14 +113,14 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
public void setRevisionProperty(@NotNull SvnTarget target,
@NotNull String property,
@NotNull SVNRevision revision,
- @Nullable SVNPropertyValue value,
+ @Nullable PropertyValue value,
boolean force) throws VcsException {
try {
if (target.isFile()) {
- createClient().doSetRevisionProperty(target.getFile(), revision, property, value, force, null);
+ createClient().doSetRevisionProperty(target.getFile(), revision, property, toPropertyValue(value), force, null);
}
else {
- createClient().doSetRevisionProperty(target.getURL(), revision, property, value, force, null);
+ createClient().doSetRevisionProperty(target.getURL(), revision, property, toPropertyValue(value), force, null);
}
}
catch (SVNException e) {
@@ -112,27 +128,39 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
}
}
+ @NotNull
+ private static SVNProperties toSvnProperties(@NotNull PropertiesMap properties) {
+ SVNProperties result = new SVNProperties();
+
+ for (Map.Entry<String, PropertyValue> entry : properties.entrySet()) {
+ result.put(entry.getKey(), toPropertyValue(entry.getValue()));
+ }
+
+ return result;
+ }
+
private void runGetProperty(@NotNull SvnTarget target,
@Nullable String property,
@Nullable SVNRevision revision,
@Nullable Depth depth,
- @Nullable ISVNPropertyHandler handler) throws VcsException {
+ @Nullable PropertyConsumer handler) throws VcsException {
SVNWCClient client = createClient();
try {
if (target.isURL()) {
- client.doGetProperty(target.getURL(), property, target.getPegRevision(), revision, toDepth(depth), handler);
+ client.doGetProperty(target.getURL(), property, target.getPegRevision(), revision, toDepth(depth), toHandler(handler));
} else {
- client.doGetProperty(target.getFile(), property, target.getPegRevision(), revision, toDepth(depth), handler, null);
+ client.doGetProperty(target.getFile(), property, target.getPegRevision(), revision, toDepth(depth), toHandler(handler), null);
}
} catch (SVNException e) {
throw new VcsException(e);
}
}
- private SVNPropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{
+ private PropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision)
+ throws SVNException {
final SVNWCClient client = createClient();
- final SVNPropertyData[] result = new SVNPropertyData[1];
+ final PropertyData[] result = new PropertyData[1];
ISVNPropertyHandler handler = new ISVNPropertyHandler() {
@Override
public void handleProperty(File path, SVNPropertyData property) throws SVNException {
@@ -151,7 +179,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
private void handle(@NotNull SVNPropertyData data) {
if (property.equals(data.getName())) {
- result[0] = data;
+ result[0] = PropertyData.create(data);
}
}
};
@@ -164,4 +192,41 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
return result[0];
}
+
+ @Nullable
+ private static ISVNPropertyHandler toHandler(@Nullable final PropertyConsumer consumer) {
+ ISVNPropertyHandler result = null;
+
+ if (consumer != null) {
+ result = new ISVNPropertyHandler() {
+ @Override
+ public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ consumer.handleProperty(path, PropertyData.create(property));
+ }
+
+ @Override
+ public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ consumer.handleProperty(url, PropertyData.create(property));
+ }
+
+ @Override
+ public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ consumer.handleProperty(revision, PropertyData.create(property));
+ }
+ };
+ }
+
+ return result;
+ }
+
+ @Nullable
+ private static SVNPropertyValue toPropertyValue(@Nullable PropertyValue value) {
+ SVNPropertyValue result = null;
+
+ if (value != null) {
+ result = SVNPropertyValue.create(value.toString());
+ }
+
+ return result;
+ }
}
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 237d05bd5f7a..7b09461b3766 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
@@ -34,6 +34,9 @@ import org.jetbrains.idea.svn.api.ProgressEvent;
import org.jetbrains.idea.svn.api.ProgressTracker;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
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.wc2.SvnTarget;
@@ -100,7 +103,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
};
final List<CopiedAsideInfo> fromToModified = new ArrayList<CopiedAsideInfo>();
- final Map<File, SVNProperties> properties = ContainerUtil.newHashMap();
+ final Map<File, PropertiesMap> properties = ContainerUtil.newHashMap();
moveRenamesToTmp(exceptions, fromToModified, properties, collector);
// adds (deletes)
// deletes (adds)
@@ -123,29 +126,29 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
private void moveRenamesToTmp(List<VcsException> exceptions,
List<CopiedAsideInfo> fromToModified,
- final Map<File, SVNProperties> properties,
+ final Map<File, PropertiesMap> properties,
final UnversionedAndNotTouchedFilesGroupCollector collector) {
final Map<File, ThroughRenameInfo> fromTo = collector.getFromTo();
try {
final File tmp = FileUtil.createTempDirectory("forRename", "");
- final ISVNPropertyHandler handler = new ISVNPropertyHandler() {
+ final PropertyConsumer handler = new PropertyConsumer() {
@Override
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ public void handleProperty(File path, PropertyData property) throws SVNException {
final ThroughRenameInfo info = collector.findToFile(new FilePathImpl(path, path.isDirectory()), null);
if (info != null) {
if (!properties.containsKey(info.getTo())) {
- properties.put(info.getTo(), new SVNProperties());
+ properties.put(info.getTo(), new PropertiesMap());
}
properties.get(info.getTo()).put(property.getName(), property.getValue());
}
}
@Override
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ public void handleProperty(SVNURL url, PropertyData property) throws SVNException {
}
@Override
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ public void handleProperty(long revision, PropertyData property) throws SVNException {
}
};
@@ -181,7 +184,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
private void moveGroup(final List<VcsException> exceptions,
List<CopiedAsideInfo> fromTo,
- Map<File, SVNProperties> properties) {
+ Map<File, PropertiesMap> properties) {
Collections.sort(fromTo, new Comparator<CopiedAsideInfo>() {
@Override
public int compare(CopiedAsideInfo o1, CopiedAsideInfo o2) {
@@ -240,8 +243,8 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
applyProperties(properties, exceptions);
}
- private void applyProperties(Map<File, SVNProperties> propertiesMap, final List<VcsException> exceptions) {
- for (Map.Entry<File, SVNProperties> entry : propertiesMap.entrySet()) {
+ private void applyProperties(Map<File, PropertiesMap> propertiesMap, final List<VcsException> exceptions) {
+ for (Map.Entry<File, PropertiesMap> entry : propertiesMap.entrySet()) {
File file = entry.getKey();
try {
mySvnVcs.getFactory(file).createPropertyClient().setProperties(file, entry.getValue());
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitAdminAreaFactorySelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitAdminAreaFactorySelector.java
new file mode 100644
index 000000000000..0d1a4c0106e0
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitAdminAreaFactorySelector.java
@@ -0,0 +1,137 @@
+/*
+ * 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.svnkit;
+
+import com.intellij.openapi.application.ApplicationManager;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnFormatSelector;
+import org.jetbrains.idea.svn.SvnWorkingCopyFormatHolder;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
+import org.tmatesoft.svn.core.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.internal.wc.admin.ISVNAdminAreaFactorySelector;
+import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminAreaFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitAdminAreaFactorySelector implements ISVNAdminAreaFactorySelector {
+
+ public Collection getEnabledFactories(File path, Collection factories, boolean writeAccess) throws SVNException {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return factories;
+ }
+
+ if (!writeAccess) {
+ return factories;
+ }
+
+ Collection result = null;
+ final WorkingCopyFormat presetFormat = SvnWorkingCopyFormatHolder.getPresetFormat();
+ if (presetFormat != null) {
+ result = format2Factories(presetFormat, factories);
+ }
+
+ if (result == null) {
+ final WorkingCopyFormat format = SvnFormatSelector.getWorkingCopyFormat(path);
+ result = format2Factories(format, factories);
+ }
+
+ if (result == null) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY));
+ }
+ return result;
+ }
+
+ @Nullable
+ static Collection format2Factories(final WorkingCopyFormat format, final Collection factories) {
+ if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
+ return factories;
+ }
+ else if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
+ return factoriesFor16(factories);
+ }
+ else if (WorkingCopyFormat.ONE_DOT_FIVE.equals(format)) {
+ return factoriesFor15(factories);
+ }
+ else if (WorkingCopyFormat.ONE_DOT_FOUR.equals(format)) {
+ return factoriesFor14(factories);
+ }
+ else if (WorkingCopyFormat.ONE_DOT_THREE.equals(format)) {
+ return factoriesFor13(factories);
+ }
+ return null;
+ }
+
+ private static Collection<SVNAdminAreaFactory> factoriesFor13(final Collection factories) {
+ for (Object item : factories) {
+ final SVNAdminAreaFactory factory = (SVNAdminAreaFactory)item;
+ final int supportedVersion = factory.getSupportedVersion();
+ if (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) {
+ return Collections.singletonList(factory);
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private static Collection<SVNAdminAreaFactory> factoriesFor14(final Collection factories) {
+ final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
+ for (Object item : factories) {
+ final SVNAdminAreaFactory factory = (SVNAdminAreaFactory)item;
+ final int supportedVersion = factory.getSupportedVersion();
+ if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion)) {
+ result.add(factory);
+ }
+ }
+ return result;
+ }
+
+ private static Collection<SVNAdminAreaFactory> factoriesFor15(final Collection factories) {
+ final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
+ for (Object item : factories) {
+ final SVNAdminAreaFactory factory = (SVNAdminAreaFactory)item;
+ final int supportedVersion = factory.getSupportedVersion();
+ if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_FIVE.getFormat() == supportedVersion)) {
+ result.add(factory);
+ }
+ }
+ return result;
+ }
+
+ private static Collection<SVNAdminAreaFactory> factoriesFor16(final Collection factories) {
+ final Collection<SVNAdminAreaFactory> result = new ArrayList<SVNAdminAreaFactory>(2);
+ for (Object item : factories) {
+ final SVNAdminAreaFactory factory = (SVNAdminAreaFactory)item;
+ final int supportedVersion = factory.getSupportedVersion();
+ if ((WorkingCopyFormat.ONE_DOT_FOUR.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_THREE.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_FIVE.getFormat() == supportedVersion) ||
+ (WorkingCopyFormat.ONE_DOT_SIX.getFormat() == supportedVersion)) {
+ result.add(factory);
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitManager.java
index a446b58bb1cb..757100026797 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitManager.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/svnkit/SvnKitManager.java
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnConfiguration;
-import org.jetbrains.idea.svn.SvnFormatSelector;
import org.jetbrains.idea.svn.SvnHttpAuthMethodsDefaultChecker;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.auth.SvnAuthenticationManager;
@@ -72,7 +71,7 @@ public class SvnKitManager {
SVNJNAUtil.setJNAEnabled(true);
SvnHttpAuthMethodsDefaultChecker.check();
- SVNAdminAreaFactory.setSelector(new SvnFormatSelector());
+ SVNAdminAreaFactory.setSelector(new SvnKitAdminAreaFactorySelector());
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();