mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VCS: roots autodetection mentioned in IDEADEV-42024 (Subversion: Update is not working properly) and IDEA-25305 (After adding a new maven module, my Version COntrol configuration is cleared.)
This commit is contained in:
@@ -24,6 +24,8 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.ModuleAdapter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootEvent;
|
||||
import com.intellij.openapi.roots.ModuleRootListener;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -34,13 +36,11 @@ import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.VcsDirectoryMapping;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -49,6 +49,7 @@ public class ModuleVcsDetector implements ProjectComponent {
|
||||
private final Project myProject;
|
||||
private final MessageBus myMessageBus;
|
||||
private final ProjectLevelVcsManagerImpl myVcsManager;
|
||||
private MessageBusConnection myConnection;
|
||||
|
||||
public ModuleVcsDetector(final Project project, final MessageBus messageBus, final ProjectLevelVcsManager vcsManager) {
|
||||
myProject = project;
|
||||
@@ -63,7 +64,7 @@ public class ModuleVcsDetector implements ProjectComponent {
|
||||
manager.registerStartupActivity(new Runnable() {
|
||||
public void run() {
|
||||
if (myVcsManager.needAutodetectMappings()) {
|
||||
autoDetectVcsMappings();
|
||||
autoDetectVcsMappings(true);
|
||||
}
|
||||
myVcsManager.updateActiveVcss();
|
||||
}
|
||||
@@ -71,20 +72,36 @@ public class ModuleVcsDetector implements ProjectComponent {
|
||||
manager.registerPostStartupActivity(new Runnable() {
|
||||
public void run() {
|
||||
if (myMessageBus != null) {
|
||||
myMessageBus.connect().subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
|
||||
public void moduleAdded(final Project project, final Module module) {
|
||||
autoDetectModuleVcsMapping(module);
|
||||
}
|
||||
|
||||
public void beforeModuleRemoved(final Project project, final Module module) {
|
||||
checkRemoveVcsRoot(module);
|
||||
}
|
||||
});
|
||||
myConnection = myMessageBus.connect();
|
||||
final MyModulesListener listener = new MyModulesListener();
|
||||
myConnection.subscribe(ProjectTopics.MODULES, listener);
|
||||
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, listener);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class MyModulesListener extends ModuleAdapter implements ModuleRootListener {
|
||||
public void beforeRootsChange(ModuleRootEvent event) {
|
||||
}
|
||||
|
||||
public void rootsChanged(ModuleRootEvent event) {
|
||||
// the check calculates to true only before user has done any change to mappings, i.e. in case modules are detected/added automatically
|
||||
// on start etc (look inside)
|
||||
if (myVcsManager.needAutodetectMappings()) {
|
||||
autoDetectVcsMappings(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void moduleAdded(final Project project, final Module module) {
|
||||
autoDetectModuleVcsMapping(module);
|
||||
}
|
||||
|
||||
public void beforeModuleRemoved(final Project project, final Module module) {
|
||||
checkRemoveVcsRoot(module);
|
||||
}
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
}
|
||||
|
||||
@@ -98,12 +115,16 @@ public class ModuleVcsDetector implements ProjectComponent {
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
if (myConnection != null) {
|
||||
myConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void autoDetectVcsMappings() {
|
||||
private void autoDetectVcsMappings(final boolean tryMapPieces) {
|
||||
Set<AbstractVcs> usedVcses = new HashSet<AbstractVcs>();
|
||||
Map<VirtualFile, AbstractVcs> vcsMap = new HashMap<VirtualFile, AbstractVcs>();
|
||||
for(Module module: ModuleManager.getInstance(myProject).getModules()) {
|
||||
final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
|
||||
for(Module module: moduleManager.getModules()) {
|
||||
final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
|
||||
for(VirtualFile file: files) {
|
||||
AbstractVcs contentRootVcs = myVcsManager.findVersioningVcs(file);
|
||||
@@ -115,11 +136,31 @@ public class ModuleVcsDetector implements ProjectComponent {
|
||||
}
|
||||
if (usedVcses.size() == 1) {
|
||||
final AbstractVcs[] abstractVcses = usedVcses.toArray(new AbstractVcs[1]);
|
||||
final Module[] modules = moduleManager.getModules();
|
||||
final Set<String> contentRoots = new HashSet<String>();
|
||||
for (Module module : modules) {
|
||||
final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots();
|
||||
for (VirtualFile root : roots) {
|
||||
contentRoots.add(root.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
if (abstractVcses [0] != null) {
|
||||
final List<VcsDirectoryMapping> vcsDirectoryMappings = new ArrayList<VcsDirectoryMapping>(myVcsManager.getDirectoryMappings());
|
||||
for (Iterator<VcsDirectoryMapping> iterator = vcsDirectoryMappings.iterator(); iterator.hasNext();) {
|
||||
final VcsDirectoryMapping mapping = iterator.next();
|
||||
if (! contentRoots.contains(mapping.getDirectory())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
myVcsManager.setAutoDirectoryMapping("", abstractVcses [0].getName());
|
||||
for (VcsDirectoryMapping mapping : vcsDirectoryMappings) {
|
||||
myVcsManager.removeDirectoryMapping(mapping);
|
||||
}
|
||||
myVcsManager.cleanupMappings();
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (tryMapPieces) {
|
||||
for(Map.Entry<VirtualFile, AbstractVcs> entry: vcsMap.entrySet()) {
|
||||
myVcsManager.setAutoDirectoryMapping(entry.getKey().getPath(), entry.getValue() == null ? "" : entry.getValue().getName());
|
||||
}
|
||||
|
||||
@@ -100,6 +100,16 @@ public class NewMappings {
|
||||
public void setMapping(final String path, final String activeVcsName) {
|
||||
LOG.debug("setMapping path = '" + path + "' vcs = " + activeVcsName);
|
||||
final VcsDirectoryMapping newMapping = new VcsDirectoryMapping(path, activeVcsName);
|
||||
// do not add duplicates
|
||||
synchronized (myLock) {
|
||||
if (myVcsToPaths.containsKey(activeVcsName)) {
|
||||
final List<VcsDirectoryMapping> vcsDirectoryMappings = myVcsToPaths.get(activeVcsName);
|
||||
if ((vcsDirectoryMappings != null) && (vcsDirectoryMappings.contains(newMapping))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
final LocalFileSystem.WatchRequest request = addWatchRequest(newMapping);
|
||||
|
||||
final Ref<Boolean> switched = new Ref<Boolean>(Boolean.FALSE);
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.jetbrains.idea.svn.dialogs.WCInfo;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
|
||||
import org.tmatesoft.svn.core.io.SVNCapability;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
@@ -582,4 +584,24 @@ public class SvnUtil {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SVNURL getUrl(final File file) {
|
||||
SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
|
||||
try {
|
||||
wcAccess.probeOpen(file, false, 0);
|
||||
SVNEntry entry = wcAccess.getVersionedEntry(file, false);
|
||||
return entry.getSVNURL();
|
||||
} catch (SVNException e) {
|
||||
//
|
||||
} finally {
|
||||
try {
|
||||
wcAccess.close();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,22 +877,34 @@ public class SvnVcs extends AbstractVcs {
|
||||
|
||||
final List<MyPair<S>> infos = new ArrayList<MyPair<S>>(in.size());
|
||||
final SvnFileUrlMappingImpl mapping = (SvnFileUrlMappingImpl) getSvnFileUrlMapping();
|
||||
final List<S> notMatched = new LinkedList<S>();
|
||||
for (S s : in) {
|
||||
final VirtualFile vf = convertor.convert(s);
|
||||
|
||||
final File ioFile = new File(vf.getPath());
|
||||
final SVNURL url = mapping.getUrlForFile(ioFile);
|
||||
if (url == null) continue;
|
||||
SVNURL url = mapping.getUrlForFile(ioFile);
|
||||
if (url == null) {
|
||||
url = SvnUtil.getUrl(ioFile);
|
||||
if (url == null) {
|
||||
notMatched.add(s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
infos.add(new MyPair<S>(vf, url.toString(), s));
|
||||
}
|
||||
final List<MyPair<S>> filtered = new ArrayList<MyPair<S>>(infos.size());
|
||||
ForNestedRootChecker.filterOutSuperfluousChildren(this, infos, filtered);
|
||||
|
||||
return ObjectsConvertor.convert(filtered, new Convertor<MyPair<S>, S>() {
|
||||
final List<S> converted = ObjectsConvertor.convert(filtered, new Convertor<MyPair<S>, S>() {
|
||||
public S convert(final MyPair<S> o) {
|
||||
return o.getSrc();
|
||||
}
|
||||
});
|
||||
if (! notMatched.isEmpty()) {
|
||||
// potential bug is here: order is not kept. but seems it only occurs for cases where result is sorted after filtering so ok
|
||||
converted.addAll(notMatched);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
private static class MyPair<T> implements RootUrlPair {
|
||||
|
||||
Reference in New Issue
Block a user