Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2010-01-29 15:06:07 +03:00
26 changed files with 415 additions and 61 deletions
@@ -145,7 +145,7 @@ public class PsiFileFactoryImpl extends PsiFileFactory {
FileTypeManager fileTypeManager = FileTypeManager.getInstance();
FileType type = fileTypeManager.getFileTypeByFileName(name);
if (type.isBinary()) {
throw new RuntimeException("Cannot create binary files from text");
throw new RuntimeException("Cannot create binary files from text: name " + name + ", file type " + type);
}
return createFileFromText(name, type, text);
@@ -641,6 +641,10 @@ public class FileUtil {
return aFileName.replace('\\', '/');
}
public static String nameToCompare(@NonNls @NotNull String name) {
return (SystemInfo.isFileSystemCaseSensitive ? name : name.toLowerCase()).replace('\\', '/');
}
public static String unquote(String urlString) {
urlString = urlString.replace('/', File.separatorChar);
return URLUtil.unescapePercentSequences(urlString);
@@ -20,4 +20,5 @@ import org.jetbrains.annotations.NotNull;
public interface SequentialUpdatesContext {
@NotNull
String getMessageWhenInterruptedBeforeStart();
boolean shouldFail();
}
@@ -45,7 +45,7 @@ public class VcsGuess {
return null;
}
if (myExcludedFileIndex.isInContent(file) || isFileInBaseDir(file) ||
myVcsManager.hasExplicitMapping(file)) {
myVcsManager.hasExplicitMapping(file) || file.equals(myProject.getBaseDir())) {
if (myExcludedFileIndex.isExcludedFile(file)) {
return null;
}
@@ -472,7 +472,7 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction {
}
boolean continueChain = false;
for (SequentialUpdatesContext context : myContextInfo.values()) {
continueChain |= context != null;
continueChain |= (context != null) && (context.shouldFail());
}
final boolean continueChainFinal = continueChain;
@@ -563,7 +563,7 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction {
private void gatherContextInterruptedMessages() {
for (Map.Entry<AbstractVcs, SequentialUpdatesContext> entry : myContextInfo.entrySet()) {
final SequentialUpdatesContext context = entry.getValue();
if (context == null) continue;
if ((context == null) || (! context.shouldFail())) continue;
final VcsException exception = new VcsException(context.getMessageWhenInterruptedBeforeStart());
gatherExceptions(entry.getKey(), Collections.singletonList(exception));
}
@@ -200,7 +200,7 @@ public class XLineBreakpointManager {
if (line >= 0 && line < document.getLineCount() && file != null) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
if (!myProject.isDisposed() && file.isValid()) {
if (!myProject.isDisposed() && myProject.isInitialized() && file.isValid()) {
XDebuggerUtil.getInstance().toggleLineBreakpoint(myProject, file, line);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -317,21 +317,16 @@ public class CollectionUtils{
}
// constant empty arrays are ignored.
return !isConstantEmptyArray(field);
}
public static String getInterfaceForClass(String name){
final int paramStart = name.indexOf((int) '<');
String baseName;
final String arg;
if(paramStart >= 0){
baseName = name.substring(0, paramStart);
baseName = baseName.trim();
arg = name.substring(paramStart);
} else{
public static String getInterfaceForClass(String name) {
final int parameterStart = name.indexOf((int) '<');
final String baseName;
if (parameterStart >= 0) {
baseName = name.substring(0, parameterStart).trim();
} else {
baseName = name;
arg = "";
}
return s_interfaceForCollection.get(baseName) + arg;
return s_interfaceForCollection.get(baseName);
}
}
@@ -81,6 +81,10 @@ public class CvsUpdateEnvironment implements UpdateEnvironment {
return "Merge (" + mergeString + ") wasn't started, only update (-r " + myUpdateTagName + ") was performed";
}
public boolean shouldFail() {
return true;
}
public UpdateSettingsOnCvsConfiguration getConfiguration() {
return myConfiguration;
}
@@ -16,7 +16,17 @@
package org.jetbrains.idea.svn;
public enum NestedCopyType {
external,
switched,
inner
external("External"),
switched("Switched"),
inner("Nested");
private final String myName;
NestedCopyType(String name) {
myName = name;
}
public String getName() {
return myName;
}
}
@@ -30,6 +30,7 @@ public class RootUrlInfo implements RootUrlPair {
private final VirtualFile myVfile;
// vcs root
private final VirtualFile myRoot;
private NestedCopyType myType;
public RootUrlInfo(final SVNURL repositoryUrl, final SVNURL absoluteUrlAsUrl, final WorkingCopyFormat format, final VirtualFile vfile,
final VirtualFile root) {
@@ -41,6 +42,7 @@ public class RootUrlInfo implements RootUrlPair {
final String asString = repositoryUrl.toString();
myRepositoryUrl = asString.endsWith("/") ? asString.substring(0, asString.length() - 1) : asString;
myAbsoluteUrlAsUrl = absoluteUrlAsUrl;
//myType = NestedCopyType.inner; // default
}
public String getRepositoryUrl() {
@@ -79,4 +81,12 @@ public class RootUrlInfo implements RootUrlPair {
public String getUrl() {
return myAbsoluteUrlAsUrl.toString();
}
public NestedCopyType getType() {
return myType;
}
public void setType(NestedCopyType type) {
myType = type;
}
}
@@ -67,6 +67,13 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
private void onStateChangedToSuccess(final AuthenticationRequest obj) {
myVcs.invokeRefreshSvnRoots(false);
/*ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
myVcs.invokeRefreshSvnRoots(false);
}
});*/
/*final List<SVNURL> outdatedRequests = new LinkedList<SVNURL>();
final Collection<SVNURL> keys = getAllCurrentKeys();
for (SVNURL key : keys) {
@@ -326,11 +326,24 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone
clManager.invokeAfterUpdate(new Runnable() {
public void run() {
final List<RootUrlInfo> nestedRoots = new ArrayList<RootUrlInfo>();
for (NestedCopiesBuilder.MyPointInfo info : myGate.get().getSet()) {
if (NestedCopyType.external.equals(info.getType())) {
final NestedCopiesData data = myGate.get();
for (NestedCopiesBuilder.MyPointInfo info : data.getSet()) {
if (NestedCopyType.external.equals(info.getType()) || NestedCopyType.switched.equals(info.getType())) {
final File infoFile = new File(info.getFile().getPath());
boolean copyFound = false;
for (RootUrlInfo topRoot : myTopRoots) {
if (topRoot.getIoFile().equals(infoFile)) {
topRoot.setType(info.getType());
copyFound = true;
break;
}
}
if (copyFound) {
continue;
}
try {
final SVNStatus svnStatus = SvnUtil.getStatus(myVcs, new File(info.getFile().getPath()));
final SVNStatus svnStatus = SvnUtil.getStatus(myVcs, infoFile);
if (svnStatus.getURL() == null) continue;
info.setUrl(svnStatus.getURL());
info.setFormat(WorkingCopyFormat.getInstance(svnStatus.getWorkingCopyFormat()));
@@ -343,12 +356,16 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone
if (VfsUtil.isAncestor(topRoot.getVirtualFile(), info.getFile(), true)) {
final SVNURL repoRoot = myRepositoryRoots.ask(info.getUrl());
if (repoRoot != null) {
nestedRoots.add(new RootUrlInfo(repoRoot, info.getUrl(), info.getFormat(), info.getFile(), topRoot.getRoot()));
final RootUrlInfo rootInfo = new RootUrlInfo(repoRoot, info.getUrl(), info.getFormat(), info.getFile(), topRoot.getRoot());
rootInfo.setType(info.getType());
nestedRoots.add(rootInfo);
}
break;
}
}
}
// check those top roots which ARE externals, but that was not detected due to they itself were the status request target
//new SvnNestedTypeRechecker(myVcs.getProject(), myTopRoots).run();
myTopRoots.addAll(nestedRoots);
myApplier.apply(myVcs, myAtomicSectionsAware, myTopRoots, myLonelyRoots);
@@ -0,0 +1,183 @@
/*
* Copyright 2000-2010 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;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.AbstractFilterChildren;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.MultiMap;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.*;
import java.io.File;
import java.util.*;
// referencies of RootUrlInfo will be kept; so type flag will be raised right in original object
public class SvnNestedTypeRechecker {
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnNestedTypeRechecker");
private final MultiMap<VirtualFile, RootUrlInfo> myRoots;
private Map<String, RootUrlInfo> mySourceItems;
private Map<String, Map<String, File>> myTreeTravellingMap;
private final Project myProject;
public SvnNestedTypeRechecker(final Project project, final List<RootUrlInfo> roots) {
myProject = project;
final NestedGatherer nestedGatherer = new NestedGatherer();
nestedGatherer.doFilter(new ArrayList<RootUrlInfo>(roots));
myRoots = nestedGatherer.getNested();
mySourceItems = new HashMap<String, RootUrlInfo>();
for (VirtualFile root : myRoots.keySet()) {
final Collection<RootUrlInfo> items = myRoots.get(root);
for (RootUrlInfo item : items) {
mySourceItems.put(FileUtil.nameToCompare(item.getVirtualFile().getPath()), item);
}
}
}
private void initTravellingMap() {
myTreeTravellingMap = new HashMap<String, Map<String, File>>();
final MultiMap<VirtualFile, File> tmpMap = new MultiMap<VirtualFile, File>();
for (VirtualFile parent : myRoots.keySet()) {
final Collection<RootUrlInfo> children = myRoots.get(parent);
for (RootUrlInfo child : children) {
VirtualFile current = child.getVirtualFile();
while (! current.equals(parent)) {
tmpMap.putValue(current.getParent(), new File(current.getPath()));
current = current.getParent();
if (current.getParent() == null) break; //+-
}
}
}
for (VirtualFile dir : tmpMap.keySet()) {
final Map<String, File> currMap = new HashMap<String, File>();
final Collection<File> coll = tmpMap.get(dir);
for (File file : coll) {
currMap.put(file.getAbsolutePath(), file);
}
myTreeTravellingMap.put(FileUtil.nameToCompare(dir.getPath()), currMap);
}
}
public void run() {
if (! myRoots.isEmpty()) {
initTravellingMap();
final ISVNStatusFileProvider fileProvider = new ISVNStatusFileProvider() {
public Map getChildrenFiles(File parent) {
final Map<String, File> children = myTreeTravellingMap.get(FileUtil.nameToCompare(parent.getAbsolutePath()));
return children == null ? Collections.emptyMap() : children;
}
};
final SvnVcs vcs = SvnVcs.getInstance(myProject);
final SVNStatusClient client = vcs.createStatusClient();
client.setFilesProvider(fileProvider);
for (VirtualFile parent : myRoots.keySet()) {
try {
client.doStatus(new File(parent.getPath()), SVNRevision.WORKING, SVNDepth.INFINITY, false, true, true, false, new ISVNStatusHandler() {
public void handleStatus(final SVNStatus status) throws SVNException {
final boolean switched = status.isSwitched();
final boolean externals = SVNStatusType.STATUS_EXTERNAL.equals(status.getContentsStatus());
if (switched || externals) {
final RootUrlInfo urlInfo = mySourceItems.get(FileUtil.nameToCompare(status.getFile().getAbsolutePath()));
if (urlInfo != null) {
if (switched) {
urlInfo.setType(NestedCopyType.switched);
} else {
urlInfo.setType(NestedCopyType.external);
}
}
}
}
}, null);
}
catch (SVNException e) {
LOG.debug(e);
}
}
}
}
/*private static SVNStatus getExternalItemStatus(final SvnVcs vcs, final File file) {
final SVNStatusClient statusClient = vcs.createStatusClient();
try {
if (file.isDirectory()) {
return statusClient.doStatus(file, false);
} else {
final File parent = file.getParentFile();
if (parent != null) {
statusClient.setFilesProvider(new ISVNStatusFileProvider() {
public Map getChildrenFiles(File parent) {
return Collections.singletonMap(file.getAbsolutePath(), file);
}
});
final Ref<SVNStatus> refStatus = new Ref<SVNStatus>();
statusClient.doStatus(parent, SVNRevision.WORKING, SVNDepth.FILES, false, true, false, false, new ISVNStatusHandler() {
public void handleStatus(final SVNStatus status) throws SVNException {
if (file.equals(status.getFile())) {
refStatus.set(status);
}
}
}, null);
return refStatus.get();
}
}
}
catch (SVNException e) {
//
}
return null;
}*/
private static class NestedGatherer extends AbstractFilterChildren<RootUrlInfo> {
private final MultiMap<VirtualFile, RootUrlInfo> myNested;
private NestedGatherer() {
myNested = new MultiMap<VirtualFile, RootUrlInfo>();
}
@Override
protected void sortAscending(List<RootUrlInfo> rootUrlInfos) {
Collections.sort(rootUrlInfos, new Comparator<RootUrlInfo>() {
public int compare(final RootUrlInfo r1, final RootUrlInfo r2) {
return new Integer(r1.getVirtualFile().getPath().length()).compareTo(r2.getVirtualFile().getPath().length());
}
});
}
@Override
protected boolean isAncestor(RootUrlInfo parent, RootUrlInfo child) {
final boolean result = VfsUtil.isAncestor(parent.getVirtualFile(), child.getVirtualFile(), true);
if (result) {
myNested.putValue(parent.getVirtualFile(), child);
}
return result;
}
public MultiMap<VirtualFile, RootUrlInfo> getNested() {
return myNested;
}
}
}
@@ -222,11 +222,15 @@ public class SvnVcs extends AbstractVcs {
if (asynchronous) {
myCopiesRefreshManager.getCopiesRefresh().asynchRequest();
} else {
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
myCopiesRefreshManager.getCopiesRefresh().synchRequest();
}
}, SvnBundle.message("refreshing.working.copies.roots.progress.text"), true, myProject);
if (ApplicationManager.getApplication().isDispatchThread()) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
myCopiesRefreshManager.getCopiesRefresh().synchRequest();
}
}, SvnBundle.message("refreshing.working.copies.roots.progress.text"), true, myProject);
} else {
myCopiesRefreshManager.getCopiesRefresh().synchRequest();
}
}
}
}
@@ -816,7 +820,7 @@ public class SvnVcs extends AbstractVcs {
for (RootUrlInfo info : infoList) {
final File file = info.getIoFile();
infos.add(new WCInfo(file.getAbsolutePath(), info.getAbsoluteUrlAsUrl(),
SvnFormatSelector.getWorkingCopyFormat(file), info.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file)));
SvnFormatSelector.getWorkingCopyFormat(file), info.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file), info.getType()));
}
return infos;
}
@@ -15,6 +15,8 @@
*/
package org.jetbrains.idea.svn.dialogs;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
@@ -23,17 +25,12 @@ import com.intellij.openapi.ui.MultiLineLabelUI;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsDirectoryMapping;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.ui.table.TableView;
import com.intellij.util.messages.Topic;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.messages.Topic;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.jetbrains.idea.svn.*;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -187,7 +184,7 @@ public class SvnMapDialog extends DialogWrapper {
}
private void createUIComponents() {
myTableModel = new ListTableModel<WCInfo>(new ColumnInfo[]{WC_ROOT_PATH, WC_URL, WC_COPY_ROOT, WC_FORMAT}, Collections.<WCInfo>emptyList(), 0);
myTableModel = new ListTableModel<WCInfo>(new ColumnInfo[]{WC_ROOT_PATH, WC_URL, WC_COPY_ROOT, WC_FORMAT, WC_TYPE}, Collections.<WCInfo>emptyList(), 0);
myTableView = new TableView<WCInfo>(myTableModel);
}
@@ -207,15 +204,16 @@ public class SvnMapDialog extends DialogWrapper {
}
};
private static final ColumnInfo<WCInfo, String> WC_FORMAT = new ColumnInfo<WCInfo, String>(SvnBundle.message("dialog.show.svn.map.table.header.column.format.title")) {
@Override
public String getName() {
return super.getName();
}
public String valueOf(final WCInfo info) {
final WorkingCopyFormat format = info.getFormat();
return SvnUtil.formatRepresentation(format);
}
};
private static final ColumnInfo<WCInfo, String> WC_TYPE = new ColumnInfo<WCInfo, String>("Type") {
public String valueOf(final WCInfo info) {
final NestedCopyType type = info.getType();
return type == null ? "" : type.getName();
}
};
}
@@ -15,9 +15,10 @@
*/
package org.jetbrains.idea.svn.dialogs;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.idea.svn.NestedCopyType;
import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.tmatesoft.svn.core.SVNURL;
import com.intellij.openapi.vfs.VirtualFile;
public class WCInfo implements WCPaths {
private final String myPath;
@@ -25,13 +26,16 @@ public class WCInfo implements WCPaths {
private final WorkingCopyFormat myFormat;
private final String myRepositoryRoot;
private final boolean myIsWcRoot;
private final NestedCopyType myType;
public WCInfo(final String path, final SVNURL url, final WorkingCopyFormat format, final String repositoryRoot, final boolean isWcRoot) {
public WCInfo(final String path, final SVNURL url, final WorkingCopyFormat format, final String repositoryRoot, final boolean isWcRoot,
final NestedCopyType type) {
myPath = path;
myUrl = url;
myFormat = format;
myRepositoryRoot = repositoryRoot;
myIsWcRoot = isWcRoot;
myType = type;
}
public String getPath() {
@@ -82,4 +86,8 @@ public class WCInfo implements WCPaths {
public int hashCode() {
return (myPath != null ? myPath.hashCode() : 0);
}
public NestedCopyType getType() {
return myType;
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.dialogs;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.idea.svn.NestedCopyType;
import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
@@ -30,8 +31,9 @@ public class WCInfoWithBranches extends WCInfo {
public WCInfoWithBranches(final String path, final SVNURL url, final WorkingCopyFormat format, final String repositoryRoot, final boolean isWcRoot,
final List<Branch> branches,
final VirtualFile root,
final String trunkToot) {
super(path, url, format, repositoryRoot, isWcRoot);
final String trunkToot,
final NestedCopyType type) {
super(path, url, format, repositoryRoot, isWcRoot, type);
myBranches = branches;
myRoot = root;
myTrunkRoot = trunkToot;
@@ -23,7 +23,6 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.WCInfo;
import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches;
@@ -31,7 +30,10 @@ import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class WcInfoLoader {
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.WcInfoLoader");
@@ -77,7 +79,8 @@ public class WcInfoLoader {
return null;
}
final WCInfo wcInfo = new WCInfo(rootInfo.getIoFile().getAbsolutePath(), rootInfo.getAbsoluteUrlAsUrl(),
SvnFormatSelector.getWorkingCopyFormat(file), rootInfo.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file));
SvnFormatSelector.getWorkingCopyFormat(file), rootInfo.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file),
rootInfo.getType());
return createInfo(wcInfo, vcs, urlMapping);
}
@@ -122,7 +125,7 @@ public class WcInfoLoader {
final String branchRoot = createBranchesList(url, configuration, items);
return new WCInfoWithBranches(info.getPath(), info.getUrl(), info.getFormat(),
info.getRepositoryRoot(), info.isIsWcRoot(), items, root,
branchRoot);
branchRoot, info.getType());
}
private static String createBranchesList(final String url, final SvnBranchConfigurationNew configuration,
@@ -26,7 +26,7 @@ import org.tmatesoft.svn.core.wc.SVNStatusType;
public class IntegrateEventHandler extends UpdateEventHandler {
public IntegrateEventHandler(final SvnVcs vcs, final ProgressIndicator progressIndicator) {
super(vcs, progressIndicator);
super(vcs, progressIndicator, null);
}
protected boolean handleInDescendants(final SVNEvent event) {
@@ -21,6 +21,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
@@ -69,19 +70,31 @@ public abstract class AbstractSvnUpdateIntegrateEnvironment implements UpdateEnv
final ProgressIndicator progressIndicator, @NotNull final Ref<SequentialUpdatesContext> context)
throws ProcessCanceledException {
if (context.isNull()) {
context.set(new SvnUpdateContext(myVcs));
}
final ArrayList<VcsException> exceptions = new ArrayList<VcsException>();
UpdateEventHandler eventHandler = new UpdateEventHandler(myVcs, progressIndicator);
UpdateEventHandler eventHandler = new UpdateEventHandler(myVcs, progressIndicator, (SvnUpdateContext) context.get());
eventHandler.setUpdatedFiles(updatedFiles);
boolean totalUpdate = true;
AbstractUpdateIntegrateCrawler crawler = createCrawler(eventHandler, totalUpdate, exceptions, updatedFiles);
Collection<File> updatedRoots = new HashSet<File>();
Arrays.sort(contentRoots, new Comparator<FilePath>() {
public int compare(FilePath o1, FilePath o2) {
return SystemInfo.isFileSystemCaseSensitive ? o1.getPath().replace("/", "\\").compareTo(o2.getPath().replace("/", "\\")) :
o1.getPath().replace("/", "\\").compareToIgnoreCase(o2.getPath().replace("/", "\\"));
}
});
for (FilePath contentRoot : contentRoots) {
if (progressIndicator != null && progressIndicator.isCanceled()) {
throw new ProcessCanceledException();
}
Collection<File> roots = SvnUtil.crawlWCRoots(contentRoot.getIOFile(), crawler, progressIndicator);
final File ioRoot = contentRoot.getIOFile();
if (! ((SvnUpdateContext)context.get()).shouldRunFor(ioRoot)) continue;
Collection<File> roots = SvnUtil.crawlWCRoots(ioRoot, crawler, progressIndicator);
updatedRoots.addAll(roots);
}
if (updatedRoots.isEmpty()) {
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2010 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.update;
import com.intellij.openapi.vcs.update.SequentialUpdatesContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.NestedCopyType;
import org.jetbrains.idea.svn.RootUrlInfo;
import org.jetbrains.idea.svn.SvnVcs;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
public class SvnUpdateContext implements SequentialUpdatesContext {
private final Set<File> myUpdatedExternals;
private final SvnVcs myVcs;
public SvnUpdateContext(final SvnVcs vcs) {
myVcs = vcs;
myUpdatedExternals = new HashSet<File>();
}
@NotNull
public String getMessageWhenInterruptedBeforeStart() {
// never
return null;
}
public boolean shouldFail() {
return false;
}
public void registerExternalRootBeingUpdated(final File root) {
myUpdatedExternals.add(root);
}
public boolean shouldRunFor(final File ioRoot) {
if (myUpdatedExternals.contains(ioRoot)) return false;
final RootUrlInfo info = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(ioRoot);
if (info != null) {
return ! NestedCopyType.switched.equals(info.getType());
}
return true;
}
}
@@ -3,12 +3,12 @@
<grid id="f589c" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="29" y="50" width="455" height="147"/>
<xy x="29" y="50" width="455" height="152"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="3b3aa" layout-manager="GridLayoutManager" row-count="4" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="3b3aa" layout-manager="GridLayoutManager" row-count="5" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -74,6 +74,14 @@
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="update.switch.to.branch.text"/>
</properties>
</component>
<component id="3e3c3" class="javax.swing.JLabel" binding="myCopyType">
<constraints>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
</children>
</grid>
<vspacer id="120cd">
@@ -33,6 +33,7 @@ import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -49,6 +50,7 @@ public class SvnUpdateRootOptionsPanel implements SvnPanel{
private TextFieldWithBrowseButton myBranchField;
private JLabel myBranchLabel;
private JLabel myUrlLabel;
private JLabel myCopyType;
private String mySourceUrl;
private SVNURL myBranchUrl;
@@ -118,6 +120,25 @@ public class SvnUpdateRootOptionsPanel implements SvnPanel{
myRevisionText.setEnabled(myRevisionBox.isSelected());
myURLText.setEnabled(myUpdateToSpecificUrl.isSelected());
myBranchField.setEnabled(myUpdateToSpecificUrl.isSelected() && (myBranchUrl != null) && (mySourceUrl != null));
final boolean revisionCanBeSpecifiedForRoot = isRevisionCanBeSpecifiedForRoot();
myRevisionBox.setEnabled(revisionCanBeSpecifiedForRoot);
myRevisionText.setEnabled(revisionCanBeSpecifiedForRoot);
myCopyType.setVisible(! revisionCanBeSpecifiedForRoot);
myCopyType.setFont(myCopyType.getFont().deriveFont(Font.ITALIC));
myUpdateToSpecificUrl.setEnabled(revisionCanBeSpecifiedForRoot);
}
private boolean isRevisionCanBeSpecifiedForRoot() {
final RootUrlInfo info = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(myRoot.getIOFile());
if (info != null) {
final boolean result = (!NestedCopyType.external.equals(info.getType())) && (!NestedCopyType.switched.equals(info.getType()));
if (! result) {
myCopyType.setText(info.getType().getName() + " copy");
}
return result;
}
return true;
}
private void chooseBranch() {
@@ -16,11 +16,12 @@
package org.jetbrains.idea.svn.update;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.update.FileGroup;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnFileUrlMapping;
import org.jetbrains.idea.svn.SvnVcs;
@@ -44,13 +45,16 @@ public class UpdateEventHandler implements ISVNEventHandler {
private UpdatedFiles myUpdatedFiles;
private int myExternalsCount;
private final SvnVcs myVCS;
@Nullable private final SvnUpdateContext mySequentialUpdatesContext;
protected String myText;
protected String myText2;
public UpdateEventHandler(SvnVcs vcs, ProgressIndicator progressIndicator) {
public UpdateEventHandler(SvnVcs vcs, ProgressIndicator progressIndicator,
@Nullable final SvnUpdateContext sequentialUpdatesContext) {
myProgressIndicator = progressIndicator;
myVCS = vcs;
mySequentialUpdatesContext = sequentialUpdatesContext;
myExternalsCount = 1;
}
@@ -134,6 +138,9 @@ public class UpdateEventHandler implements ISVNEventHandler {
}
}
else if (event.getAction() == SVNEventAction.UPDATE_EXTERNAL) {
if (mySequentialUpdatesContext != null) {
mySequentialUpdatesContext.registerExternalRootBeingUpdated(event.getFile());
}
myExternalsCount++;
if (myUpdatedFiles.getGroupById(AbstractSvnUpdateIntegrateEnvironment.EXTERNAL_ID) == null) {
myUpdatedFiles.registerGroup(new FileGroup(SvnBundle.message("status.group.name.externals"),