mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-68072 "Subversion -> Compare with branch..." not working when selecting trunk
+ ask credentials if needed when "Refresh branches" + do not store concrete branches info in other.xml, store only mappings + store concrete branches in /system + order branches mapping for serialization
This commit is contained in:
@@ -122,6 +122,8 @@
|
||||
serviceImplementation="org.jetbrains.idea.svn.history.LoadedRevisionsCache"/>
|
||||
<projectService serviceInterface="org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache"
|
||||
serviceImplementation="org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache"/>
|
||||
<projectService serviceInterface="org.jetbrains.idea.svn.SvnLoadedBrachesStorage"
|
||||
serviceImplementation="org.jetbrains.idea.svn.SvnLoadedBrachesStorage"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.SvnBranchMapperManager"
|
||||
serviceImplementation="org.jetbrains.idea.svn.SvnBranchMapperManager"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"
|
||||
|
||||
@@ -60,10 +60,12 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnBranchConfigurationManager");
|
||||
private final Project myProject;
|
||||
private final ProjectLevelVcsManager myVcsManager;
|
||||
private final SvnLoadedBrachesStorage myStorage;
|
||||
|
||||
public SvnBranchConfigurationManager(final Project project, final ProjectLevelVcsManager vcsManager) {
|
||||
public SvnBranchConfigurationManager(final Project project, final ProjectLevelVcsManager vcsManager, final SvnLoadedBrachesStorage storage) {
|
||||
myProject = project;
|
||||
myVcsManager = vcsManager;
|
||||
myStorage = storage;
|
||||
myBunch = new NewRootBunch(project);
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
}
|
||||
|
||||
public static class ConfigurationBean {
|
||||
public Map<String, SvnBranchConfiguration> myConfigurationMap = new HashMap<String, SvnBranchConfiguration>();
|
||||
public Map<String, SvnBranchConfiguration> myConfigurationMap = new TreeMap<String, SvnBranchConfiguration>();
|
||||
/**
|
||||
* version of "support SVN in IDEA". for features tracking. should grow
|
||||
*/
|
||||
@@ -122,7 +124,6 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
for (String origKey : origMap.keySet()) {
|
||||
map.put(origKey, origMap.get(origKey).getValue());
|
||||
}
|
||||
configuration.setBranchMap(map);
|
||||
result.myConfigurationMap.put(key, helper.prepareForSerialization(configuration));
|
||||
}
|
||||
result.mySupportsUserInfoFilter = true;
|
||||
@@ -159,7 +160,7 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
// check if cancel had been put
|
||||
if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return;
|
||||
if (myAll || (! oldUrls.contains(newBranchUrl))) {
|
||||
new NewRootBunch.BranchesLoadRunnable(myProject, myBunch, newBranchUrl, InfoReliability.defaultValues, myRoot, null).run();
|
||||
new NewRootBunch.BranchesLoadRunnable(myProject, myBunch, newBranchUrl, InfoReliability.defaultValues, myRoot, null, true).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,13 +194,14 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
final SvnBranchConfigurationNew newConfig = new SvnBranchConfigurationNew();
|
||||
newConfig.setTrunkUrl(configToConvert.getTrunkUrl());
|
||||
newConfig.setUserinfoInUrl(configToConvert.isUserinfoInUrl());
|
||||
final Map<String, List<SvnBranchItem>> oldMap = configToConvert.getBranchMap();
|
||||
for (String branchUrl : configToConvert.getBranchUrls()) {
|
||||
List<SvnBranchItem> items = oldMap.get(branchUrl);
|
||||
items = ((items == null) || (items.isEmpty())) ? new ArrayList<SvnBranchItem>() : items;
|
||||
whatToInit.add(new Pair<VirtualFile, SvnBranchConfigurationNew>(root, newConfig));
|
||||
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(items,
|
||||
(items.isEmpty()) ? InfoReliability.defaultValues : InfoReliability.setByUser));
|
||||
List<SvnBranchItem> stored = getStored(branchUrl);
|
||||
if (stored != null && ! stored.isEmpty()) {
|
||||
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(stored, InfoReliability.setByUser));
|
||||
} else {
|
||||
whatToInit.add(new Pair<VirtualFile, SvnBranchConfigurationNew>(root, newConfig));
|
||||
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
|
||||
}
|
||||
}
|
||||
|
||||
myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), null);
|
||||
@@ -227,6 +229,14 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
myConfigurationBean = object;
|
||||
}
|
||||
|
||||
private List<SvnBranchItem> getStored(String branchUrl) {
|
||||
Collection<SvnBranchItem> collection = myStorage.get(branchUrl);
|
||||
if (collection == null) return null;
|
||||
final List<SvnBranchItem> items = new ArrayList<SvnBranchItem>(collection);
|
||||
Collections.sort(items);
|
||||
return items;
|
||||
}
|
||||
|
||||
private static class UrlSerializationHelper {
|
||||
private final SvnVcs myVcs;
|
||||
|
||||
@@ -248,24 +258,9 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
newBranchesList.add(serializeUrl(s, withUserInfo));
|
||||
}
|
||||
|
||||
final Map<String, List<SvnBranchItem>> map = configuration.getBranchMap();
|
||||
final Map<String, List<SvnBranchItem>> newMap = new HashMap<String, List<SvnBranchItem>>(map.size(), 1.0f);
|
||||
for (Map.Entry<String, List<SvnBranchItem>> entry : map.entrySet()) {
|
||||
final List<SvnBranchItem> items = entry.getValue();
|
||||
if (items != null) {
|
||||
final List<SvnBranchItem> newItems = new ArrayList<SvnBranchItem>();
|
||||
for (SvnBranchItem item : items) {
|
||||
newItems.add(new SvnBranchItem(serializeUrl(item.getUrl(), withUserInfo), new java.util.Date(item.getCreationDateMillis()),
|
||||
item.getRevision()));
|
||||
}
|
||||
newMap.put(serializeUrl(entry.getKey(), withUserInfo), newItems);
|
||||
}
|
||||
}
|
||||
|
||||
final SvnBranchConfiguration result = new SvnBranchConfiguration();
|
||||
result.setTrunkUrl(trunkUrl);
|
||||
result.setBranchUrls(newBranchesList);
|
||||
result.setBranchMap(newMap);
|
||||
result.setUserinfoInUrl(withUserInfo.isNull() ? false : withUserInfo.get());
|
||||
return result;
|
||||
}
|
||||
@@ -286,24 +281,9 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
newBranchesList.add(deserializeUrl(s, userInfo));
|
||||
}
|
||||
|
||||
final Map<String, List<SvnBranchItem>> map = configuration.getBranchMap();
|
||||
final Map<String, List<SvnBranchItem>> newMap = new HashMap<String, List<SvnBranchItem>>(map.size(), 1.0f);
|
||||
for (Map.Entry<String, List<SvnBranchItem>> entry : map.entrySet()) {
|
||||
final List<SvnBranchItem> items = entry.getValue();
|
||||
if (items != null) {
|
||||
final List<SvnBranchItem> newItems = new ArrayList<SvnBranchItem>();
|
||||
for (SvnBranchItem item : items) {
|
||||
newItems.add(new SvnBranchItem(deserializeUrl(item.getUrl(), userInfo), new java.util.Date(item.getCreationDateMillis()),
|
||||
item.getRevision()));
|
||||
}
|
||||
newMap.put(deserializeUrl(entry.getKey(), userInfo), newItems);
|
||||
}
|
||||
}
|
||||
|
||||
final SvnBranchConfiguration result = new SvnBranchConfiguration();
|
||||
result.setTrunkUrl(newTrunkUrl);
|
||||
result.setBranchUrls(newBranchesList);
|
||||
result.setBranchMap(newMap);
|
||||
result.setUserinfoInUrl(userInfo != null && userInfo.length() > 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Holds what working copies we have for URLs
|
||||
*/
|
||||
@State(
|
||||
name = "SvnBranchMapperManager",
|
||||
storages = {
|
||||
|
||||
@@ -433,7 +433,7 @@ compare.with.branch.diff.title=Compare with Branch
|
||||
compare.with.branch.error.title=Compare with Branch
|
||||
compare.with.branch.popup.title=Compare with Branch
|
||||
getting.branch.configuration.error=Error retrieving branch configuration: {0}
|
||||
compare.with.branch.location.error=Couldn''t find repository location for file ''{0}'' under branch ''{1}''
|
||||
compare.with.branch.location.error=Couldn''t find repository location for file ''{0}'' under branch ''{1}''\nPlease check your branch configuration.
|
||||
compare.with.branch.list.error=Error Loading Branches
|
||||
create.branch.invalid.revision.error=Invalid revision ''{0}''
|
||||
create.branch.no.working.copy.error=No working copy found at {0}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.application.PathManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.persistent.SmallMapSerializer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.branchConfig.InfoReliability;
|
||||
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/24/11
|
||||
* Time: 1:21 PM
|
||||
*/
|
||||
public class SvnLoadedBrachesStorage {
|
||||
private final Object myLock;
|
||||
private SmallMapSerializer<String, Map<String, Collection<SvnBranchItem>>> myState;
|
||||
private final File myFile;
|
||||
private final Project myProject;
|
||||
|
||||
public SvnLoadedBrachesStorage(final Project project) {
|
||||
myProject = project;
|
||||
final File vcsFile = new File(PathManager.getSystemPath(), "vcs");
|
||||
File file = new File(vcsFile, "svn_branches");
|
||||
file.mkdirs();
|
||||
myFile = new File(file, project.getLocationHash());
|
||||
myLock = new Object();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Collection<SvnBranchItem> get(final String url) {
|
||||
synchronized (myLock) {
|
||||
if (myState == null) return null;
|
||||
Map<String, Collection<SvnBranchItem>> map = myState.get("");
|
||||
return map == null ? null : map.get(SvnBranchConfigurationNew.ensureEndSlash(url));
|
||||
}
|
||||
}
|
||||
|
||||
public void put(final String url, final Collection<SvnBranchItem> items) {
|
||||
synchronized (myLock) {
|
||||
if (myState == null) return;
|
||||
Map<String, Collection<SvnBranchItem>> map = myState.get("");
|
||||
if (map == null) {
|
||||
map = new HashMap<String, Collection<SvnBranchItem>>();
|
||||
myState.put("", map);
|
||||
}
|
||||
map.put(url, items);
|
||||
}
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
synchronized (myLock) {
|
||||
myState = new SmallMapSerializer<String, Map<String, Collection<SvnBranchItem>>>(myFile, new EnumeratorStringDescriptor(), createExternalizer());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deactivate() {
|
||||
SvnBranchConfigurationManager manager = SvnBranchConfigurationManager.getInstance(myProject);
|
||||
Map<VirtualFile,SvnBranchConfigurationNew> mapCopy = manager.getSvnBranchConfigManager().getMapCopy();
|
||||
for (Map.Entry<VirtualFile, SvnBranchConfigurationNew> entry : mapCopy.entrySet()) {
|
||||
Map<String,InfoStorage<List<SvnBranchItem>>> branchMap = entry.getValue().getBranchMap();
|
||||
for (Map.Entry<String, InfoStorage<List<SvnBranchItem>>> storageEntry : branchMap.entrySet()) {
|
||||
put(storageEntry.getKey(), storageEntry.getValue().getValue());
|
||||
}
|
||||
}
|
||||
synchronized (myLock) {
|
||||
myState.force();
|
||||
myState = null;
|
||||
}
|
||||
}
|
||||
|
||||
private DataExternalizer<Map<String, Collection<SvnBranchItem>>> createExternalizer() {
|
||||
return new DataExternalizer<Map<String, Collection<SvnBranchItem>>>() {
|
||||
@Override
|
||||
public void save(DataOutput out, Map<String, Collection<SvnBranchItem>> value) throws IOException {
|
||||
out.writeInt(value.size());
|
||||
ArrayList<String> keys = new ArrayList<String>(value.keySet());
|
||||
Collections.sort(keys);
|
||||
for (String key : keys) {
|
||||
out.writeUTF(key);
|
||||
List<SvnBranchItem> list = new ArrayList<SvnBranchItem>(value.get(key));
|
||||
Collections.sort(list, SerializationComparator.getInstance());
|
||||
out.writeInt(list.size());
|
||||
for (SvnBranchItem item : list) {
|
||||
out.writeUTF(item.getUrl());
|
||||
out.writeLong(item.getCreationDateMillis());
|
||||
out.writeLong(item.getRevision());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<SvnBranchItem>> read(DataInput in) throws IOException {
|
||||
final HashMap<String, Collection<SvnBranchItem>> map = new HashMap<String, Collection<SvnBranchItem>>();
|
||||
int mapSize = in.readInt();
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
final String key = in.readUTF();
|
||||
final int size = in.readInt();
|
||||
final ArrayList<SvnBranchItem> list = new ArrayList<SvnBranchItem>(size);
|
||||
for (int j = 0; j < size; j++) {
|
||||
String url = in.readUTF();
|
||||
long creation = in.readLong();
|
||||
long revision = in.readLong();
|
||||
list.add(new SvnBranchItem(url, new Date(creation), revision));
|
||||
}
|
||||
map.put(key, list);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class SerializationComparator implements Comparator<SvnBranchItem> {
|
||||
private final static SerializationComparator ourInstance = new SerializationComparator();
|
||||
|
||||
public static SerializationComparator getInstance() {
|
||||
return ourInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(SvnBranchItem o1, SvnBranchItem o2) {
|
||||
return o1.getUrl().compareToIgnoreCase(o2.getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/24/11
|
||||
* Time: 1:07 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class SvnLoadedBranches {
|
||||
}
|
||||
@@ -151,6 +151,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
private final RootsToWorkingCopies myRootsToWorkingCopies;
|
||||
private final SvnAuthenticationNotifier myAuthNotifier;
|
||||
private static RareLogger.LogFilter[] ourLogFilters;
|
||||
private final SvnLoadedBrachesStorage myLoadedBranchesStorage;
|
||||
|
||||
static {
|
||||
SVNJNAUtil.setJNAEnabled(true);
|
||||
@@ -180,8 +181,10 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
return Boolean.valueOf(System.getProperty(systemParameterName));
|
||||
}
|
||||
|
||||
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration) {
|
||||
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final ChangeListManager changeListManager,
|
||||
final VcsDirtyScopeManager vcsDirtyScopeManager, final SvnLoadedBrachesStorage storage) {
|
||||
super(project, VCS_NAME);
|
||||
myLoadedBranchesStorage = storage;
|
||||
LOG.debug("ct");
|
||||
myRootsToWorkingCopies = new RootsToWorkingCopies(myProject);
|
||||
myConfiguration = svnConfiguration;
|
||||
@@ -417,6 +420,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
});
|
||||
|
||||
vcsManager.addVcsListener(myRootsToWorkingCopies);
|
||||
|
||||
myLoadedBranchesStorage.activate();
|
||||
}
|
||||
|
||||
private static void initLogFilters() {
|
||||
@@ -500,6 +505,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
mySvnBranchPointsCalculator.deactivate();
|
||||
mySvnBranchPointsCalculator = null;
|
||||
myWorkingCopiesContent.deactivate();
|
||||
myLoadedBranchesStorage.deactivate();
|
||||
}
|
||||
|
||||
public VcsShowConfirmationOption getAddConfirmation() {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.actions;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -27,11 +28,14 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.continuation.ModalityIgnorantBackgroundableTask;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.branchConfig.InfoReliability;
|
||||
import org.jetbrains.idea.svn.branchConfig.NewRootBunch;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog;
|
||||
@@ -181,52 +185,40 @@ public class SelectBranchPopup {
|
||||
});
|
||||
}
|
||||
else {
|
||||
showBranchPopup(selectedValue, true);
|
||||
showBranchPopup(selectedValue);
|
||||
}
|
||||
return FINAL_CHOICE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<SvnBranchItem> loadBranches(final String selectedBranchesHolder, final boolean cached) {
|
||||
if (cached) {
|
||||
return myConfiguration.getBranches(selectedBranchesHolder);
|
||||
}
|
||||
|
||||
final List<SvnBranchItem> result = new ArrayList<SvnBranchItem>();
|
||||
private void loadBranches(final String selectedBranchesHolder, final Runnable runnable) {
|
||||
final ProgressManager pm = ProgressManager.getInstance();
|
||||
|
||||
final boolean wasCanceled = ! pm.runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
final ProgressIndicator pi = pm.getProgressIndicator();
|
||||
final Semaphore s = new Semaphore();
|
||||
s.down();
|
||||
final Ref<Boolean> completedRef = new Ref<Boolean>();
|
||||
final SvnBranchConfigManager manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager();
|
||||
manager.reloadBranches(myVcsRoot, selectedBranchesHolder, new Consumer<List<SvnBranchItem>>() {
|
||||
public void consume(final List<SvnBranchItem> svnBranchItems) {
|
||||
result.addAll(svnBranchItems);
|
||||
completedRef.set(true);
|
||||
s.up();
|
||||
}
|
||||
});
|
||||
while (true) {
|
||||
s.waitFor(500);
|
||||
if (Boolean.TRUE.equals(completedRef.get())) break;
|
||||
pi.checkCanceled();
|
||||
}
|
||||
pm.run(new ModalityIgnorantBackgroundableTask(myProject, SvnBundle.message("compare.with.branch.progress.loading.branches")) {
|
||||
@Override
|
||||
protected void doInAwtIfFail(Exception e) {
|
||||
runnable.run();
|
||||
}
|
||||
}, SvnBundle.message("compare.with.branch.progress.loading.branches"), true, myProject);
|
||||
|
||||
@Override
|
||||
protected void doInAwtIfCancel() {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
if (wasCanceled) {
|
||||
return myConfiguration.getBranches(selectedBranchesHolder);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
protected void doInAwtIfSuccess() {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runImpl(@NotNull ProgressIndicator indicator) {
|
||||
final SvnBranchConfigManager manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager();
|
||||
new NewRootBunch.BranchesLoadRunnable(myProject, manager, selectedBranchesHolder, InfoReliability.setByUser, myVcsRoot, null, false).run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showBranchPopup(final String selectedValue, final boolean cached) {
|
||||
List<SvnBranchItem> branches = loadBranches(selectedValue, cached);
|
||||
private void showBranchPopup(final String selectedValue) {
|
||||
List<SvnBranchItem> branches = myConfiguration.getBranches(selectedValue);
|
||||
if (branches == null) {
|
||||
return;
|
||||
}
|
||||
@@ -247,7 +239,12 @@ public class SelectBranchPopup {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showBranchPopup(selectedValue, false);
|
||||
loadBranches(selectedValue, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showBranchPopup(selectedValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.branchConfig;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
|
||||
import org.tmatesoft.svn.core.ISVNDirEntryHandler;
|
||||
import org.tmatesoft.svn.core.SVNDirEntry;
|
||||
@@ -37,11 +38,12 @@ public class BranchesLoader {
|
||||
private BranchesLoader() {
|
||||
}
|
||||
|
||||
public static List<SvnBranchItem> loadBranches(final Project project, final String url) throws SVNException {
|
||||
public static List<SvnBranchItem> loadBranches(final Project project, final String url, boolean passive) throws SVNException {
|
||||
final List<SvnBranchItem> result = new LinkedList<SvnBranchItem>();
|
||||
|
||||
final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
|
||||
final ISVNAuthenticationManager passiveManager = configuration.getPassiveAuthenticationManager();
|
||||
final ISVNAuthenticationManager passiveManager = passive ? configuration.getPassiveAuthenticationManager() : configuration.getInteractiveManager(
|
||||
SvnVcs.getInstance(project));
|
||||
|
||||
final SVNLogClient logClient = new SVNLogClient(passiveManager, configuration.getOptions(project));
|
||||
final SVNURL branchesUrl = SVNURL.parseURIEncoded(url);
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.idea.svn.integrate.SvnBranchItem;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -95,7 +94,7 @@ public class NewRootBunch implements SvnBranchConfigManager {
|
||||
public void reloadBranches(@NotNull final VirtualFile root, @NotNull final String branchParentUrl,
|
||||
final Consumer<List<SvnBranchItem>> callback) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new BranchesLoadRunnable(myProject, this, branchParentUrl,
|
||||
InfoReliability.setByUser, root, callback));
|
||||
InfoReliability.setByUser, root, callback, true));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -125,7 +124,7 @@ public class NewRootBunch implements SvnBranchConfigManager {
|
||||
public void consume(List<SvnBranchItem> svnBranchItems) {
|
||||
runnable.run();
|
||||
}
|
||||
}).run();
|
||||
}, true).run();
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
@@ -142,21 +141,28 @@ public class NewRootBunch implements SvnBranchConfigManager {
|
||||
private final Consumer<List<SvnBranchItem>> myCallback;
|
||||
private final String myUrl;
|
||||
private final InfoReliability myInfoReliability;
|
||||
private boolean myPassive;
|
||||
|
||||
public BranchesLoadRunnable(final Project project, final SvnBranchConfigManager bunch, final String url, final InfoReliability infoReliability,
|
||||
final VirtualFile root, @Nullable final Consumer<List<SvnBranchItem>> callback) {
|
||||
public BranchesLoadRunnable(final Project project,
|
||||
final SvnBranchConfigManager bunch,
|
||||
final String url,
|
||||
final InfoReliability infoReliability,
|
||||
final VirtualFile root,
|
||||
@Nullable final Consumer<List<SvnBranchItem>> callback,
|
||||
boolean passive) {
|
||||
myProject = project;
|
||||
myBunch = bunch;
|
||||
myUrl = url;
|
||||
myInfoReliability = infoReliability;
|
||||
myRoot = root;
|
||||
myCallback = callback;
|
||||
myPassive = passive;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
boolean callbackCalled = false;
|
||||
try {
|
||||
final List<SvnBranchItem> items = BranchesLoader.loadBranches(myProject, myUrl);
|
||||
final List<SvnBranchItem> items = BranchesLoader.loadBranches(myProject, myUrl, myPassive);
|
||||
myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(items, myInfoReliability));
|
||||
if (myCallback != null) {
|
||||
myCallback.consume(items);
|
||||
@@ -171,7 +177,7 @@ public class NewRootBunch implements SvnBranchConfigManager {
|
||||
} finally {
|
||||
// callback must be called by contract
|
||||
if (myCallback != null && (! callbackCalled)) {
|
||||
myCallback.consume(Collections.<SvnBranchItem>emptyList());
|
||||
myCallback.consume(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,7 +199,8 @@ public class NewRootBunch implements SvnBranchConfigManager {
|
||||
if (result != null) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
for (String url : result.getBranchUrls()) {
|
||||
application.executeOnPooledThread(new BranchesLoadRunnable(myProject, myBunch, url, InfoReliability.defaultValues, myRoot, null));
|
||||
application.executeOnPooledThread(new BranchesLoadRunnable(myProject, myBunch, url, InfoReliability.defaultValues, myRoot, null,
|
||||
true));
|
||||
}
|
||||
myBunch.updateForRoot(myRoot, new InfoStorage<SvnBranchConfigurationNew>(result, InfoReliability.defaultValues), null);
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public interface SvnBranchConfigManager {
|
||||
SvnBranchConfigurationNew getConfig(@NotNull VirtualFile root);
|
||||
|
||||
void reloadBranches(@NotNull VirtualFile root, @NotNull String branchParentUrl,
|
||||
Consumer<List<SvnBranchItem>> callback);
|
||||
Consumer<List<SvnBranchItem>> callback);
|
||||
@Nullable
|
||||
@CalledInBackground
|
||||
SVNURL getWorkingBranchWithReload(final SVNURL svnurl, final VirtualFile root);
|
||||
|
||||
+41
-50
@@ -17,13 +17,16 @@ package org.jetbrains.idea.svn.branchConfig;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
@@ -62,11 +65,18 @@ public class SvnBranchConfigurationNew {
|
||||
|
||||
public List<String> getBranchUrls() {
|
||||
final ArrayList<String> result = new ArrayList<String>(myBranchMap.keySet());
|
||||
Collections.sort(result);
|
||||
return result;
|
||||
final List<String> cutList = ObjectsConvertor.convert(result, new Convertor<String, String>() {
|
||||
@Override
|
||||
public String convert(String s) {
|
||||
return cutEndSlash(s);
|
||||
}
|
||||
});
|
||||
Collections.sort(cutList);
|
||||
return cutList;
|
||||
}
|
||||
|
||||
public void addBranches(final String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
|
||||
public void addBranches(String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
|
||||
branchParentName = ensureEndSlash(branchParentName);
|
||||
InfoStorage<List<SvnBranchItem>> current = myBranchMap.get(branchParentName);
|
||||
if (current != null) {
|
||||
LOG.info("Branches list not added for : '" + branchParentName + "; this branch parent URL is already present.");
|
||||
@@ -75,7 +85,16 @@ public class SvnBranchConfigurationNew {
|
||||
myBranchMap.put(branchParentName, items);
|
||||
}
|
||||
|
||||
public void updateBranch(final String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
|
||||
public static String ensureEndSlash(String name) {
|
||||
return name.trim().endsWith("/") ? name : name + "/";
|
||||
}
|
||||
|
||||
private static String cutEndSlash(String name) {
|
||||
return name.endsWith("/") && name.length() > 0 ? name.substring(0, name.length() - 1) : name;
|
||||
}
|
||||
|
||||
public void updateBranch(String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
|
||||
branchParentName = ensureEndSlash(branchParentName);
|
||||
final InfoStorage<List<SvnBranchItem>> current = myBranchMap.get(branchParentName);
|
||||
if (current == null) {
|
||||
LOG.info("Branches list not updated for : '" + branchParentName + "; since config has changed.");
|
||||
@@ -89,21 +108,10 @@ public class SvnBranchConfigurationNew {
|
||||
}
|
||||
|
||||
public List<SvnBranchItem> getBranches(String url) {
|
||||
url = ensureEndSlash(url);
|
||||
return myBranchMap.get(url).getValue();
|
||||
}
|
||||
|
||||
/*public SvnBranchConfiguration createFromVcsRootBranches() {
|
||||
final SvnBranchConfiguration result = new SvnBranchConfiguration();
|
||||
result.setTrunkUrl(myTrunkUrl);
|
||||
final Map<String, List<SvnBranchItem>> branchMap = result.getBranchMap();
|
||||
for (String key : myBranchMap.keySet()) {
|
||||
result.setTrunkUrl(key);
|
||||
final List<SvnBranchItem> list = myBranchMap.get(key).getT();
|
||||
branchMap.put(key, list);
|
||||
}
|
||||
return result;
|
||||
}*/
|
||||
|
||||
public SvnBranchConfigurationNew copy() {
|
||||
SvnBranchConfigurationNew result = new SvnBranchConfigurationNew();
|
||||
result.myUserinfoInUrl = myUserinfoInUrl;
|
||||
@@ -119,16 +127,16 @@ public class SvnBranchConfigurationNew {
|
||||
|
||||
@Nullable
|
||||
public String getBaseUrl(String url) {
|
||||
if ((myTrunkUrl != null) && url.startsWith(myTrunkUrl)) {
|
||||
return myTrunkUrl;
|
||||
if (myTrunkUrl != null) {
|
||||
if (SVNPathUtil.isAncestor(myTrunkUrl, url)) {
|
||||
return cutEndSlash(myTrunkUrl);
|
||||
}
|
||||
}
|
||||
for(String branchUrl: myBranchMap.keySet()) {
|
||||
if (url.startsWith(branchUrl)) {
|
||||
int pos = url.indexOf('/', branchUrl.length()+1);
|
||||
if (pos >= 0) {
|
||||
return url.substring(0, pos);
|
||||
}
|
||||
return branchUrl;
|
||||
if (SVNPathUtil.isAncestor(branchUrl, url)) {
|
||||
String relativePath = SVNPathUtil.getRelativePath(branchUrl, url);
|
||||
int secondSlash = relativePath.indexOf("/");
|
||||
return cutEndSlash(branchUrl + (secondSlash == -1 ? relativePath : relativePath.substring(0, secondSlash)));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -140,27 +148,8 @@ public class SvnBranchConfigurationNew {
|
||||
if (baseUrl == null) {
|
||||
return null;
|
||||
}
|
||||
if (myBranchMap.isEmpty()) {
|
||||
return baseUrl;
|
||||
}
|
||||
int commonPrefixLength = getCommonPrefixLength(url, myTrunkUrl);
|
||||
for (String branchUrl : myBranchMap.keySet()) {
|
||||
commonPrefixLength = Math.min(commonPrefixLength, getCommonPrefixLength(url, branchUrl));
|
||||
if (commonPrefixLength <= 0) {
|
||||
return baseUrl;
|
||||
}
|
||||
}
|
||||
return baseUrl.substring(commonPrefixLength);
|
||||
}
|
||||
|
||||
private static int getCommonPrefixLength(final String s1, final String s2) {
|
||||
final int minLength = Math.min(s1.length(), s2.length());
|
||||
for(int i=0; i< minLength; i++) {
|
||||
if (s1.charAt(i) != s2.charAt(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return minLength;
|
||||
int lastSlash = baseUrl.lastIndexOf("/");
|
||||
return lastSlash == -1 ? baseUrl : baseUrl.substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -171,12 +160,11 @@ public class SvnBranchConfigurationNew {
|
||||
|
||||
@Nullable
|
||||
public SVNURL getWorkingBranch(final SVNURL someUrl) throws SVNException {
|
||||
final BranchSearcher branchSearcher = new BranchSearcher(someUrl);
|
||||
iterateUrls(branchSearcher);
|
||||
|
||||
return branchSearcher.getResult();
|
||||
String baseUrl = getBaseUrl(someUrl.toString());
|
||||
return baseUrl == null ? null : SVNURL.parseURIEncoded(baseUrl);
|
||||
}
|
||||
|
||||
// todo not checked
|
||||
// todo +-
|
||||
@Nullable
|
||||
public String getGroupToLoadToReachUrl(final SVNURL url) throws SVNException {
|
||||
@@ -209,6 +197,7 @@ public class SvnBranchConfigurationNew {
|
||||
}
|
||||
}
|
||||
|
||||
// to retrieve mappings between existing in the project working copies and their URLs
|
||||
@Nullable
|
||||
public Map<String,String> getUrl2FileMappings(final Project project, final VirtualFile root) {
|
||||
try {
|
||||
@@ -220,7 +209,8 @@ public class SvnBranchConfigurationNew {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeBranch(final String url) {
|
||||
public void removeBranch(String url) {
|
||||
url = ensureEndSlash(url);
|
||||
myBranchMap.remove(url);
|
||||
}
|
||||
|
||||
@@ -261,6 +251,7 @@ public class SvnBranchConfigurationNew {
|
||||
boolean accept(final String url) throws SVNException;
|
||||
}
|
||||
|
||||
// todo not checked
|
||||
private static class BranchSearcher implements UrlListener {
|
||||
private final SVNURL mySomeUrl;
|
||||
private SVNURL myResult;
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnBranchConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnBranchMapperManager;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
|
||||
Reference in New Issue
Block a user