Merge branch 'svn_18_3'

This commit is contained in:
Konstantin Kolosovsky
2014-08-13 13:25:43 +04:00
58 changed files with 665 additions and 660 deletions
@@ -229,7 +229,8 @@ public abstract class ProjectLevelVcsManager {
public abstract boolean isBackgroundVcsOperationRunning();
public abstract List<VirtualFile> getRootsUnderVcsWithoutFiltering(final AbstractVcs vcs);
public abstract VirtualFile[] getRootsUnderVcs(AbstractVcs vcs);
public abstract VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs);
/**
* Also includes into list all modules under roots
@@ -49,7 +49,7 @@ public abstract class AbstractRefreshablePanel<T> implements RefreshablePanel<Ch
private final DetailsPanel myDetailsPanel;
private final GenericDetailsLoader<Ticket, T> myDetailsLoader;
private final BackgroundTaskQueue myQueue;
private boolean myDisposed;
private volatile boolean myDisposed;
protected AbstractRefreshablePanel(final Project project, final String loadingTitle, final BackgroundTaskQueue queue) {
myQueue = queue;
@@ -150,7 +150,7 @@ public class ChangesBrowserNode<T> extends DefaultMutableTreeNode {
public <T> List<T> getAllObjectsUnder(final Class<T> clazz) {
List<T> changes = new ArrayList<T>();
final Enumeration enumeration = depthFirstEnumeration();
final Enumeration enumeration = preorderEnumeration();
while (enumeration.hasMoreElements()) {
ChangesBrowserNode child = (ChangesBrowserNode)enumeration.nextElement();
final Object value = child.getUserObject();
@@ -661,7 +661,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
@Override
@NotNull
public VirtualFile[] getRootsUnderVcs(AbstractVcs vcs) {
public VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs) {
return myMappingsToRoots.getRootsUnderVcs(vcs);
}
@@ -42,7 +42,7 @@ public class MappingsToRoots {
}
@NotNull
public VirtualFile[] getRootsUnderVcs(final AbstractVcs vcs) {
public VirtualFile[] getRootsUnderVcs(@NotNull AbstractVcs vcs) {
List<VirtualFile> result = myMappings.getMappingsAsFilesUnderVcs(vcs);
final AbstractVcs.RootsConvertor convertor = vcs.getCustomConvertor();
@@ -273,7 +273,7 @@ public class NewMappings {
return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath());
}
public List<VirtualFile> getMappingsAsFilesUnderVcs(final AbstractVcs vcs) {
public List<VirtualFile> getMappingsAsFilesUnderVcs(@NotNull AbstractVcs vcs) {
final List<VirtualFile> result = new ArrayList<VirtualFile>();
final String vcsName = vcs.getName();
+7 -7
View File
@@ -76,7 +76,7 @@
<reference id="Vcs.ShowTabbedFileHistory"/>
<reference id="Vcs.ShowHistoryForBlock"/>
<reference id="Annotate"/>
<action id="Subversion.Copy" class="org.jetbrains.idea.svn.actions.CreateBranchOrTagAction"/>
<action id="Subversion.Copy" class="org.jetbrains.idea.svn.branchConfig.CreateBranchOrTagAction"/>
<separator/>
<action id="Subversion.Lock" class="org.jetbrains.idea.svn.actions.LockAction"/>
<action id="Subversion.Unlock" class="org.jetbrains.idea.svn.actions.UnlockAction"/>
@@ -122,16 +122,16 @@
<applicationService serviceInterface="org.jetbrains.idea.svn.SvnApplicationSettings"
serviceImplementation="org.jetbrains.idea.svn.SvnApplicationSettings"/>
<projectService serviceImplementation="org.jetbrains.idea.svn.SvnConfiguration"/>
<projectService serviceInterface="org.jetbrains.idea.svn.SvnBranchConfigurationManager"
serviceImplementation="org.jetbrains.idea.svn.SvnBranchConfigurationManager"/>
<projectService serviceInterface="org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager"
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager"/>
<projectService serviceInterface="org.jetbrains.idea.svn.history.LoadedRevisionsCache"
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"/>
<projectService serviceInterface="org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage"
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage"/>
<applicationService serviceInterface="org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager"
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager"/>
<applicationService serviceInterface="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"
serviceImplementation="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"/>
<applicationService serviceInterface="org.jetbrains.idea.svn.dialogs.browserCache.Loader"
@@ -105,7 +105,7 @@ public class RootsToWorkingCopies implements VcsListener {
@CalledInBackground
@Nullable
public WorkingCopy getWcRoot(final VirtualFile root) {
public WorkingCopy getWcRoot(@NotNull VirtualFile root) {
assert (! ApplicationManager.getApplication().isDispatchThread()) || ApplicationManager.getApplication().isUnitTestMode();
synchronized (myLock) {
@@ -117,7 +117,7 @@ public class RootsToWorkingCopies implements VcsListener {
}
@Nullable
private WorkingCopy calculateRoot(final VirtualFile root) {
private WorkingCopy calculateRoot(@NotNull VirtualFile root) {
File workingCopyRoot = SvnUtil.getWorkingCopyRootNew(new File(root.getPath()));
WorkingCopy workingCopy = null;
@@ -526,6 +526,7 @@ action.Subversion.integrate.changes.alien.commit.changelist.title=Integrated
action.Subversion.integrate.changes.dialog.add.wc.text=Add
action.Subversion.integrate.changes.dialog.remove.wc.text=Remove
action.Subversion.integrate.changes.message.files.up.to.date.text=All files are up to date
action.Subversion.integrate.changes.collecting.changes.to.commit.task.title=Collecting changes to commit
action.Subversion.integrate.changes.error.unable.to.collect.changes.text=Error while collecting changes to commit: {0}
error.cannot.load.revisions=Can not load revision list
action.Subversion.integrate.changes.message.canceled.text=Integration was canceled
@@ -27,6 +27,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.lock.Lock;
import org.jetbrains.idea.svn.status.Status;
@@ -244,7 +245,13 @@ class SvnChangeProviderContext implements StatusReceiver {
myChangelistBuilder.processLocallyDeletedFile(createLocallyDeletedChange(filePath, status));
}
else if (status.is(StatusType.STATUS_IGNORED)) {
if (!myVcs.isWcRoot(filePath)) {
if (filePath.getVirtualFile() == null) {
filePath.hardRefresh();
}
if (filePath.getVirtualFile() == null) {
LOG.error("No virtual file for ignored file: " + filePath.getPresentableUrl() + ", isNonLocal: " + filePath.isNonLocal());
}
else if (!myVcs.isWcRoot(filePath)) {
myChangelistBuilder.processIgnoredFile(filePath.getVirtualFile());
}
}
@@ -30,6 +30,7 @@ import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.auth.SvnAuthenticationManager;
import org.jetbrains.idea.svn.auth.SvnAuthenticationProvider;
import org.jetbrains.idea.svn.auth.SvnInteractiveAuthenticationProvider;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.config.SvnServerFileKeys;
import org.jetbrains.idea.svn.diff.DiffOptions;
import org.jetbrains.idea.svn.update.MergeRootInfo;
@@ -221,11 +221,16 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
}
public void realRefresh(final Runnable afterRefreshCallback) {
final SvnVcs vcs = SvnVcs.getInstance(myProject);
final VirtualFile[] roots = myHelper.executeDefended(myProject);
final SvnRootsDetector rootsDetector = new SvnRootsDetector(vcs, this, myNestedCopiesHolder);
// do not send additional request for nested copies when in init state
rootsDetector.detectCopyRoots(roots, init(), afterRefreshCallback);
if (myProject.isDisposed()) {
afterRefreshCallback.run();
}
else {
final SvnVcs vcs = SvnVcs.getInstance(myProject);
final VirtualFile[] roots = myHelper.executeDefended(myProject);
final SvnRootsDetector rootsDetector = new SvnRootsDetector(vcs, this, myNestedCopiesHolder);
// do not send additional request for nested copies when in init state
rootsDetector.detectCopyRoots(roots, init(), afterRefreshCallback);
}
}
public void applyDetectionResult(@NotNull SvnRootsDetector.Result result) {
@@ -19,22 +19,25 @@ import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.changes.VcsDirtyScope;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SvnScopeZipper implements Runnable {
private final VcsDirtyScope myIn;
private final List<FilePath> myRecursiveDirs;
// instead of set and heavy equals of file path
private final Map<String, MyDirNonRecursive> myNonRecursiveDirs;
// those alone in their immediate parent
private final List<FilePath> mySingleFiles;
public SvnScopeZipper(final VcsDirtyScope in) {
@NotNull private final VcsDirtyScope myIn;
@NotNull private final List<FilePath> myRecursiveDirs;
// instead of set and heavy equals of file path
@NotNull private final Map<String, MyDirNonRecursive> myNonRecursiveDirs;
public SvnScopeZipper(@NotNull VcsDirtyScope in) {
myIn = in;
myRecursiveDirs = new ArrayList<FilePath>(in.getRecursivelyDirtyDirectories());
myNonRecursiveDirs = new HashMap<String, MyDirNonRecursive>();
mySingleFiles = new ArrayList<FilePath>();
myRecursiveDirs = ContainerUtil.newArrayList(in.getRecursivelyDirtyDirectories());
myNonRecursiveDirs = ContainerUtil.newHashMap();
}
public void run() {
@@ -46,85 +49,72 @@ public class SvnScopeZipper implements Runnable {
final VirtualFile vFile = file.getVirtualFile();
// todo take care about this 'not valid' - right now keeping things as they used to be
final MyDirNonRecursive me = createOrGet(file);
me.setInterestedInParent(true);
if (vFile != null && vFile.isValid()) {
for (VirtualFile child : vFile.getChildren()) {
me.add(new FilePathImpl(child));
}
}
}
final FilePath parent = file.getParentPath();
if (parent != null) {
final MyDirNonRecursive item = createOrGet(parent);
item.add(file);
else {
final FilePath parent = file.getParentPath();
if (parent != null) {
final MyDirNonRecursive item = createOrGet(parent);
item.add(file);
}
}
}
// move alone files into a separate list
/*for (Iterator<Map.Entry<String, MyDirNonRecursive>> iterator = myNonRecursiveDirs.entrySet().iterator(); iterator.hasNext();) {
final Map.Entry<String, MyDirNonRecursive> entry = iterator.next();
final MyDirNonRecursive item = entry.getValue();
if ((! item.isInterestedInParent()) && (item.getChildrenList().size() == 1)) {
iterator.remove();
mySingleFiles.add(item.getChildrenList().iterator().next());
}
}*/
}
private MyDirNonRecursive createOrGet(final FilePath parent) {
final String key = getKey(parent);
final MyDirNonRecursive result = myNonRecursiveDirs.get(key);
if (result != null) return result;
final MyDirNonRecursive newItem = new MyDirNonRecursive(parent);
myNonRecursiveDirs.put(key, newItem);
return newItem;
@NotNull
private MyDirNonRecursive createOrGet(@NotNull FilePath parent) {
String key = getKey(parent);
MyDirNonRecursive result = myNonRecursiveDirs.get(key);
if (result == null) {
result = new MyDirNonRecursive(parent);
myNonRecursiveDirs.put(key, result);
}
return result;
}
@NotNull
public List<FilePath> getRecursiveDirs() {
return myRecursiveDirs;
}
@NotNull
public Map<String, MyDirNonRecursive> getNonRecursiveDirs() {
return myNonRecursiveDirs;
}
public List<FilePath> getSingleFiles() {
return mySingleFiles;
public static String getKey(@NotNull FilePath path) {
return path.getPresentableUrl();
}
static class MyDirNonRecursive {
private boolean myInterestedInParent;
private final FilePath myDir;
@NotNull private final FilePath myDir;
// instead of set and heavy equals of file path
private final Map<String, FilePath> myChildren;
@NotNull private final Map<String, FilePath> myChildren;
private MyDirNonRecursive(final FilePath dir) {
private MyDirNonRecursive(@NotNull FilePath dir) {
myDir = dir;
myChildren = new HashMap<String, FilePath>();
myChildren = ContainerUtil.newHashMap();
}
public boolean isInterestedInParent() {
return myInterestedInParent;
}
public void setInterestedInParent(boolean interestedInParent) {
myInterestedInParent = interestedInParent;
}
public void add(final FilePath path) {
public void add(@NotNull FilePath path) {
myChildren.put(getKey(path), path);
}
@NotNull
public Collection<FilePath> getChildrenList() {
return myChildren.values();
}
@NotNull
public FilePath getDir() {
return myDir;
}
}
public static String getKey(final FilePath path) {
return path.getPresentableUrl();
}
}
@@ -49,6 +49,7 @@ import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.EventAction;
import org.jetbrains.idea.svn.api.ProgressEvent;
import org.jetbrains.idea.svn.api.ProgressTracker;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer;
@@ -58,11 +59,15 @@ import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.status.Status;
import org.tmatesoft.sqljet.core.SqlJetException;
import org.tmatesoft.sqljet.core.table.SqlJetDb;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -343,7 +348,7 @@ public class SvnUtil {
for (T committable : committables) {
final RootUrlInfo path = vcs.getSvnFileUrlMapping().getWcRootForFilePath(convertor.convert(committable));
if (path == null) {
result.putValue(new Pair<SVNURL, WorkingCopyFormat>(null, null), committable);
result.putValue(Pair.create((SVNURL)null, WorkingCopyFormat.UNKNOWN), committable);
} else {
result.putValue(Pair.create(path.getRepositoryUrlUrl(), path.getFormat()), committable);
}
@@ -68,6 +68,7 @@ import org.jetbrains.idea.svn.api.CmdClientFactory;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.SvnKitClientFactory;
import org.jetbrains.idea.svn.auth.SvnAuthenticationNotifier;
import org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
@@ -81,7 +82,6 @@ import org.jetbrains.idea.svn.history.SvnHistoryProvider;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.info.InfoConsumer;
import org.jetbrains.idea.svn.properties.PropertyClient;
import org.jetbrains.idea.svn.properties.PropertyData;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment;
import org.jetbrains.idea.svn.status.Status;
@@ -89,7 +89,10 @@ import org.jetbrains.idea.svn.status.StatusType;
import org.jetbrains.idea.svn.svnkit.SvnKitManager;
import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.wc.SVNAdminUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -145,7 +148,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
private final RootsToWorkingCopies myRootsToWorkingCopies;
private final SvnAuthenticationNotifier myAuthNotifier;
private final SvnLoadedBrachesStorage myLoadedBranchesStorage;
private final SvnLoadedBranchesStorage myLoadedBranchesStorage;
private final SvnExecutableChecker myChecker;
@@ -157,7 +160,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
private final boolean myLogExceptions;
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) {
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBranchesStorage storage) {
super(project, VCS_NAME);
myLoadedBranchesStorage = storage;
@@ -723,9 +726,10 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
return WorkingCopyFormat.UNKNOWN.equals(format) ? SvnFormatSelector.findRootAndGetFormat(ioFile) : format;
}
public boolean isWcRoot(FilePath filePath) {
public boolean isWcRoot(@NotNull FilePath filePath) {
boolean isWcRoot = false;
WorkingCopy wcRoot = myRootsToWorkingCopies.getWcRoot(filePath.getVirtualFile());
VirtualFile file = filePath.getVirtualFile();
WorkingCopy wcRoot = file != null ? myRootsToWorkingCopies.getWcRoot(file) : null;
if (wcRoot != null) {
isWcRoot = wcRoot.getFile().getAbsolutePath().equals(filePath.getIOFile().getAbsolutePath());
}
@@ -917,7 +921,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
@Override
public boolean isVcsBackgroundOperationsAllowed(VirtualFile root) {
public boolean isVcsBackgroundOperationsAllowed(@NotNull VirtualFile root) {
// TODO: Currently myAuthNotifier.isAuthenticatedFor directly uses SVNKit to check credentials - so assume for now that background
// TODO: operations are always allowed for command line. As sometimes this leads to errors - for instance, incoming changes are not
// TODO: displayed in "Incoming" tab - incoming changes are collected using command line but not displayed because
@@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.integrate.MergerFactory;
import org.jetbrains.idea.svn.integrate.SelectedCommittedStuffChecker;
import org.jetbrains.idea.svn.integrate.SvnIntegrateChangesActionPerformer;
@@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsRunnable;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnRevisionNumber;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
@@ -33,7 +34,6 @@ import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.properties.PropertyClient;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -162,8 +162,8 @@ public class SvnMergeProvider implements MergeProvider {
File ioFile = new File(file.getPath());
PropertyClient client = vcs.getFactory(ioFile).createPropertyClient();
PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile), SVNProperty.MIME_TYPE, false, SVNRevision.WORKING);
if (value != null && SVNProperty.isBinaryMimeType(value.toString())) {
PropertyValue value = client.getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_MIME_TYPE, false, SVNRevision.WORKING);
if (value != null && isBinaryMimeType(value.toString())) {
return true;
}
}
@@ -173,4 +173,8 @@ public class SvnMergeProvider implements MergeProvider {
return false;
}
private static boolean isBinaryMimeType(@NotNull String mimeType) {
return !mimeType.startsWith("text/");
}
}
@@ -223,7 +223,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
/**
* Bases on presence of notifications!
*/
public ThreeState isAuthenticatedFor(final VirtualFile vf) {
public ThreeState isAuthenticatedFor(@NotNull VirtualFile vf) {
final WorkingCopy wcCopy = myRootsToWorkingCopies.getWcRoot(vf);
if (wcCopy == null) return ThreeState.UNSURE;
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog">
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.branchConfig.BranchConfigurationDialog">
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.idea.svn.dialogs;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
import com.intellij.openapi.project.Project;
@@ -32,12 +32,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.branchConfig.InfoReliability;
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
@@ -59,7 +55,7 @@ public class BranchConfigurationDialog extends DialogWrapper {
private JList myLocationList;
private JPanel myListPanel;
private JLabel myErrorPrompt;
private final SvnBranchConfigManager mySvnBranchConfigManager;
private final NewRootBunch mySvnBranchConfigManager;
private final VirtualFile myRoot;
public BranchConfigurationDialog(@NotNull final Project project,
@@ -115,7 +111,7 @@ public class BranchConfigurationDialog extends DialogWrapper {
if (!configuration.getBranchUrls().contains(selectedUrl)) {
configuration
.addBranches(selectedUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
mySvnBranchConfigManager.reloadBranches(myRoot, selectedUrl, null);
mySvnBranchConfigManager.reloadBranchesAsync(myRoot, selectedUrl, InfoReliability.setByUser);
listModel.fireItemAdded();
myLocationList.setSelectedIndex(listModel.getSize() - 1);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +16,16 @@
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnConfiguration;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
@@ -33,27 +35,60 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class BranchesLoader {
/**
* @author Konstantin Kolosovsky.
*/
public class BranchesLoader implements Runnable {
@NotNull private final Project myProject;
@NotNull private final NewRootBunch myBunch;
@NotNull private final VirtualFile myRoot;
@NotNull private final String myUrl;
@NotNull private final InfoReliability myInfoReliability;
private final boolean myPassive;
private BranchesLoader() {
public BranchesLoader(@NotNull Project project,
@NotNull NewRootBunch bunch,
@NotNull String url,
@NotNull InfoReliability infoReliability,
@NotNull VirtualFile root,
boolean passive) {
myProject = project;
myBunch = bunch;
myUrl = url;
myInfoReliability = infoReliability;
myRoot = root;
myPassive = passive;
}
public static List<SvnBranchItem> loadBranches(final Project project, final String url, boolean passive) throws SVNException,
VcsException {
final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
final SvnVcs vcs = SvnVcs.getInstance(project);
SVNURL branchesUrl = SVNURL.parseURIEncoded(url);
public void run() {
try {
List<SvnBranchItem> branches = loadBranches();
myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(branches, myInfoReliability));
}
catch (VcsException e) {
showError(e);
}
catch (SVNException e) {
showError(e);
}
}
@NotNull
public List<SvnBranchItem> loadBranches() throws SVNException, VcsException {
final SvnConfiguration configuration = SvnConfiguration.getInstance(myProject);
final SvnVcs vcs = SvnVcs.getInstance(myProject);
SVNURL branchesUrl = SVNURL.parseURIEncoded(myUrl);
List<SvnBranchItem> result = new LinkedList<SvnBranchItem>();
SvnTarget target = SvnTarget.fromURL(branchesUrl);
if (!passive) {
if (!myPassive) {
// TODO: Implement ability to specify interactive/non-interactive auth mode for clients
DirectoryEntryConsumer handler = createConsumer(branchesUrl, result);
vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, handler);
}
else {
ISVNDirEntryHandler handler = createHandler(branchesUrl, result);
SVNLogClient client = vcs.getSvnKitManager().createLogClient(configuration.getPassiveAuthenticationManager(project));
SVNLogClient client = vcs.getSvnKitManager().createLogClient(configuration.getPassiveAuthenticationManager(myProject));
client
.doList(target.getURL(), target.getPegRevision(), SVNRevision.HEAD, false, SVNDepth.IMMEDIATES, SVNDirEntry.DIRENT_ALL, handler);
}
@@ -62,6 +97,13 @@ public class BranchesLoader {
return result;
}
private void showError(Exception e) {
// already logged inside
if (InfoReliability.setByUser.equals(myInfoReliability)) {
VcsBalloonProblemNotifier.showOverChangesView(myProject, "Branches load error: " + e.getMessage(), MessageType.ERROR);
}
}
@NotNull
private static ISVNDirEntryHandler createHandler(@NotNull final SVNURL branchesUrl, @NotNull final List<SvnBranchItem> result) {
return new ISVNDirEntryHandler() {
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.actions;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -28,7 +27,6 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import icons.SvnIcons;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog;
import org.jetbrains.idea.svn.history.SvnChangeList;
public class ConfigureBranchesAction extends AnAction implements DumbAware {
@@ -15,7 +15,7 @@
*/
package org.jetbrains.idea.svn.actions;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.Application;
@@ -35,10 +35,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.actions.BasicAction;
import org.jetbrains.idea.svn.checkin.CommitEventHandler;
import org.jetbrains.idea.svn.checkin.IdeaCommitHandler;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.dialogs.CreateBranchOrTagDialog;
import org.jetbrains.idea.svn.update.AutoSvnUpdater;
import org.jetbrains.idea.svn.update.SingleRootSwitcher;
import org.tmatesoft.svn.core.SVNErrorCode;
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.dialogs.CreateBranchOrTagDialog">
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.svn.branchConfig.CreateBranchOrTagDialog">
<grid id="9287c" binding="myTopPanel" layout-manager="GridBagLayout">
<constraints>
<xy x="10" y="10" width="561" height="502"/>
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.dialogs;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.diagnostic.Logger;
@@ -33,10 +33,9 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.RootUrlInfo;
import org.jetbrains.idea.svn.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.update.SvnRevisionPanel;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
@@ -0,0 +1,155 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konstantin Kolosovsky.
*/
public class DefaultBranchConfigInitializer implements Runnable {
private static final Logger LOG = Logger.getInstance(DefaultBranchConfigInitializer.class);
@NonNls private static final String DEFAULT_TRUNK_NAME = "trunk";
@NonNls private static final String DEFAULT_BRANCHES_NAME = "branches";
@NonNls private static final String DEFAULT_TAGS_NAME = "tags";
@NotNull private final Project myProject;
@NotNull private final NewRootBunch myBunch;
@NotNull private final VirtualFile myRoot;
public DefaultBranchConfigInitializer(@NotNull Project project, @NotNull NewRootBunch bunch, @NotNull VirtualFile root) {
myProject = project;
myRoot = root;
myBunch = bunch;
}
public void run() {
SvnBranchConfigurationNew configuration = getDefaultConfiguration();
if (configuration != null) {
for (String url : configuration.getBranchUrls()) {
myBunch.reloadBranchesAsync(myRoot, url, InfoReliability.defaultValues);
}
myBunch.updateForRoot(myRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.defaultValues), false);
}
}
@Nullable
public SvnBranchConfigurationNew getDefaultConfiguration() {
SvnBranchConfigurationNew result = null;
SvnVcs vcs = SvnVcs.getInstance(myProject);
SVNURL rootUrl = SvnUtil.getUrl(vcs, VfsUtilCore.virtualToIoFile(myRoot));
if (rootUrl != null) {
try {
result = getDefaultConfiguration(vcs, rootUrl);
}
catch (SVNException e) {
LOG.info(e);
}
catch (VcsException e) {
LOG.info(e);
}
}
else {
LOG.info("Directory is not a working copy: " + myRoot.getPresentableUrl());
}
return result;
}
@NotNull
private static SvnBranchConfigurationNew getDefaultConfiguration(@NotNull SvnVcs vcs, @NotNull SVNURL url)
throws SVNException, VcsException {
SvnBranchConfigurationNew result = new SvnBranchConfigurationNew();
result.setTrunkUrl(url.toString());
SVNURL branchLocationsParent = getBranchLocationsParent(url);
if (branchLocationsParent != null) {
SvnTarget target = SvnTarget.fromURL(branchLocationsParent);
vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, createHandler(result, target.getURL()));
}
return result;
}
@Nullable
private static SVNURL getBranchLocationsParent(@NotNull SVNURL url) throws SVNException {
while (!hasEmptyName(url) && !hasDefaultName(url)) {
url = url.removePathTail();
}
return hasDefaultName(url) ? url.removePathTail() : null;
}
private static boolean hasEmptyName(@NotNull SVNURL url) {
return StringUtil.isEmpty(SVNPathUtil.tail(url.getPath()));
}
private static boolean hasDefaultName(@NotNull SVNURL url) {
String name = SVNPathUtil.tail(url.getPath());
return name.equalsIgnoreCase(DEFAULT_TRUNK_NAME) ||
name.equalsIgnoreCase(DEFAULT_BRANCHES_NAME) ||
name.equalsIgnoreCase(DEFAULT_TAGS_NAME);
}
@NotNull
private static DirectoryEntryConsumer createHandler(@NotNull final SvnBranchConfigurationNew result, @NotNull final SVNURL rootPath) {
return new DirectoryEntryConsumer() {
@Override
public void consume(final DirectoryEntry entry) throws SVNException {
if (entry.isDirectory()) {
SVNURL childUrl = rootPath.appendPath(entry.getName(), false);
if (StringUtil.endsWithIgnoreCase(entry.getName(), DEFAULT_TRUNK_NAME)) {
result.setTrunkUrl(childUrl.toString());
}
else {
result.addBranches(childUrl.toString(),
new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(0), InfoReliability.defaultValues));
}
}
}
};
}
}
@@ -1,113 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class DefaultConfigLoader {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.DefaultConfigLoader");
@NonNls private static final String DEFAULT_TRUNK_NAME = "trunk";
@NonNls private static final String DEFAULT_BRANCHES_NAME = "branches";
@NonNls private static final String DEFAULT_TAGS_NAME = "tags";
private DefaultConfigLoader() {
}
@Nullable
public static SvnBranchConfigurationNew loadDefaultConfiguration(final Project project, final VirtualFile vcsRoot) {
try {
final SvnVcs vcs = SvnVcs.getInstance(project);
File rootFile = new File(vcsRoot.getPath());
final Info info = vcs.getInfo(rootFile);
if (info == null || info.getURL() == null) {
LOG.info("Directory is not a working copy: " + vcsRoot.getPresentableUrl());
return null;
}
SVNURL baseUrl = info.getURL();
final SvnBranchConfigurationNew result = new SvnBranchConfigurationNew();
result.setTrunkUrl(baseUrl.toString());
while(true) {
final String s = SVNPathUtil.tail(baseUrl.getPath());
if (s.equalsIgnoreCase(DEFAULT_TRUNK_NAME) || s.equalsIgnoreCase(DEFAULT_BRANCHES_NAME) || s.equalsIgnoreCase(DEFAULT_TAGS_NAME)) {
SVNURL rootPath = baseUrl.removePathTail();
SvnTarget target = SvnTarget.fromURL(rootPath);
vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, createHandler(result, rootPath));
break;
}
if (SVNPathUtil.removeTail(baseUrl.getPath()).length() == 0) {
break;
}
baseUrl = baseUrl.removePathTail();
}
return result;
}
catch (SVNException e) {
LOG.info(e);
return null;
}
catch (VcsException e) {
LOG.info(e);
return null;
}
}
@NotNull
private static DirectoryEntryConsumer createHandler(final SvnBranchConfigurationNew result, final SVNURL rootPath) {
return new DirectoryEntryConsumer() {
@Override
public void consume(final DirectoryEntry entry) throws SVNException {
if (entry.isDirectory()) {
SVNURL childUrl = rootPath.appendPath(entry.getName(), false);
if (StringUtil.endsWithIgnoreCase(entry.getName(), DEFAULT_TRUNK_NAME)) {
result.setTrunkUrl(childUrl.toString());
}
else {
result.addBranches(childUrl.toString(),
new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(0), InfoReliability.defaultValues));
}
}
}
};
}
}
@@ -15,9 +15,6 @@
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.Nullable;
public class InfoStorage<T> {
public T myT;
public InfoReliability myInfoReliability;
@@ -27,14 +24,15 @@ public class InfoStorage<T> {
myInfoReliability = infoReliability;
}
public void accept(final InfoStorage<T> infoStorage, @Nullable final PairConsumer<T, T> callbackOnUpdate) {
if (infoStorage.myInfoReliability.shouldOverride(myInfoReliability)) {
if (callbackOnUpdate != null) {
callbackOnUpdate.consume(myT, infoStorage.myT);
}
public boolean accept(final InfoStorage<T> infoStorage) {
boolean override = infoStorage.myInfoReliability.shouldOverride(myInfoReliability);
if (override) {
myT = infoStorage.myT;
myInfoReliability = infoStorage.myInfoReliability;
}
return override;
}
public T getValue() {
@@ -15,31 +15,23 @@
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManagerQueue;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.CalledInBackground;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
// synch is here
public class NewRootBunch implements SvnBranchConfigManager {
public class NewRootBunch {
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.NewRootBunch");
private final Object myLock = new Object();
private final Project myProject;
@@ -52,17 +44,31 @@ public class NewRootBunch implements SvnBranchConfigManager {
myMap = new HashMap<VirtualFile, InfoStorage<SvnBranchConfigurationNew>>();
}
public void updateForRoot(@NotNull final VirtualFile root, @NotNull final InfoStorage<SvnBranchConfigurationNew> config,
@Nullable final PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> callbackOnUpdate) {
public void updateForRoot(@NotNull final VirtualFile root,
@NotNull final InfoStorage<SvnBranchConfigurationNew> config,
boolean reload) {
synchronized (myLock) {
final SvnBranchConfigurationNew previous;
boolean override;
final InfoStorage<SvnBranchConfigurationNew> existing = myMap.get(root);
if (existing == null) {
previous = null;
override = true;
myMap.put(root, config);
if (callbackOnUpdate != null) {
callbackOnUpdate.consume(null, config.getValue());
}
} else {
existing.accept(config, callbackOnUpdate);
}
else {
previous = existing.getValue();
override = existing.accept(config);
}
if (reload && override) {
myBranchesLoader.run(new Runnable() {
@Override
public void run() {
reloadBranches(root, previous, config.getValue());
}
});
}
}
}
@@ -88,17 +94,44 @@ public class NewRootBunch implements SvnBranchConfigManager {
result = new SvnBranchConfigurationNew();
myMap.put(root, new InfoStorage<SvnBranchConfigurationNew>(result, InfoReliability.empty));
myBranchesLoader.run(new DefaultBranchConfigInitializer(myProject, this, root));
} else {
}
else {
result = value.getValue();
}
return result;
}
}
public void reloadBranches(@NotNull final VirtualFile root, @NotNull final String branchParentUrl,
final Consumer<List<SvnBranchItem>> callback) {
ApplicationManager.getApplication().executeOnPooledThread(new BranchesLoadRunnable(myProject, this, branchParentUrl,
InfoReliability.setByUser, root, callback, true));
public void reloadBranchesAsync(@NotNull final VirtualFile root,
@NotNull final String branchLocation,
@NotNull final InfoReliability reliability) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
reloadBranches(root, branchLocation, reliability, true);
}
});
}
public void reloadBranches(@NotNull VirtualFile root, @Nullable SvnBranchConfigurationNew prev, @NotNull SvnBranchConfigurationNew next) {
final Set<String> oldUrls = (prev == null) ? Collections.<String>emptySet() : new HashSet<String>(prev.getBranchUrls());
final SvnVcs vcs = SvnVcs.getInstance(myProject);
if (!vcs.isVcsBackgroundOperationsAllowed(root)) return;
for (String newBranchUrl : next.getBranchUrls()) {
// check if cancel had been put
if (!vcs.isVcsBackgroundOperationsAllowed(root)) return;
if (!oldUrls.contains(newBranchUrl)) {
reloadBranches(root, newBranchUrl, InfoReliability.defaultValues, true);
}
}
}
public void reloadBranches(@NotNull VirtualFile root,
@NotNull String branchLocation,
@NotNull InfoReliability reliability,
boolean passive) {
new BranchesLoader(myProject, this, branchLocation, reliability, root, passive).run();
}
@Nullable
@@ -108,28 +141,11 @@ public class NewRootBunch implements SvnBranchConfigManager {
try {
final SvnBranchConfigurationNew configuration = myMap.get(root).getValue();
final String group = configuration.getGroupToLoadToReachUrl(svnurl);
final Runnable runnable = new Runnable() {
public void run() {
final SvnBranchConfigurationNew reloadedConfiguration = myMap.get(root).getValue();
try {
result.set(reloadedConfiguration.getWorkingBranch(svnurl));
}
catch (SVNException e) {
//
}
}
};
if (group == null) {
runnable.run();
} else {
new BranchesLoadRunnable(myProject, this, group, InfoReliability.setByUser, root,
new Consumer<List<SvnBranchItem>>() {
public void consume(List<SvnBranchItem> svnBranchItems) {
runnable.run();
}
}, true).run();
if (group != null) {
reloadBranches(root, group, InfoReliability.setByUser, true);
}
result.set(myMap.get(root).getValue().getWorkingBranch(svnurl));
}
catch (SVNException e) {
//
@@ -137,88 +153,6 @@ public class NewRootBunch implements SvnBranchConfigManager {
return result.get();
}
public static class BranchesLoadRunnable implements Runnable {
private final Project myProject;
private final SvnBranchConfigManager myBunch;
private final VirtualFile myRoot;
@Nullable
private final Consumer<List<SvnBranchItem>> myCallback;
private final String myUrl;
private final InfoReliability myInfoReliability;
private boolean myPassive;
public BranchesLoadRunnable(final Project project,
final SvnBranchConfigManager bunch,
final String url,
final InfoReliability infoReliability,
final VirtualFile root,
@Nullable final Consumer<List<SvnBranchItem>> callback,
boolean passive) {
myProject = project;
myBunch = bunch;
myUrl = url;
myInfoReliability = infoReliability;
myRoot = root;
myCallback = callback;
myPassive = passive;
}
public void run() {
boolean callbackCalled = false;
try {
final List<SvnBranchItem> items = BranchesLoader.loadBranches(myProject, myUrl, myPassive);
myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(items, myInfoReliability));
if (myCallback != null) {
myCallback.consume(items);
callbackCalled = true;
}
}
catch (VcsException e) {
showError(e);
}
catch (SVNException e) {
showError(e);
}
finally {
// callback must be called by contract
if (myCallback != null && (! callbackCalled)) {
myCallback.consume(null);
}
}
}
private void showError(Exception e) {
// already logged inside
if (InfoReliability.setByUser.equals(myInfoReliability)) {
VcsBalloonProblemNotifier.showOverChangesView(myProject, "Branches load error: " + e.getMessage(), MessageType.ERROR);
}
}
}
private static class DefaultBranchConfigInitializer implements Runnable {
private final Project myProject;
private final SvnBranchConfigManager myBunch;
private final VirtualFile myRoot;
private DefaultBranchConfigInitializer(final Project project, final SvnBranchConfigManager bunch, final VirtualFile root) {
myProject = project;
myRoot = root;
myBunch = bunch;
}
public void run() {
final SvnBranchConfigurationNew result = DefaultConfigLoader.loadDefaultConfiguration(myProject, myRoot);
if (result != null) {
final Application application = ApplicationManager.getApplication();
for (String url : result.getBranchUrls()) {
application.executeOnPooledThread(new BranchesLoadRunnable(myProject, myBunch, url, InfoReliability.defaultValues, myRoot, null,
true));
}
myBunch.updateForRoot(myRoot, new InfoStorage<SvnBranchConfigurationNew>(result, InfoReliability.defaultValues), null);
}
}
}
public Map<VirtualFile, SvnBranchConfigurationNew> getMapCopy() {
synchronized (myLock) {
final Map<VirtualFile, SvnBranchConfigurationNew> result = new HashMap<VirtualFile, SvnBranchConfigurationNew>();
@@ -228,4 +162,4 @@ public class NewRootBunch implements SvnBranchConfigManager {
return result;
}
}
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.actions;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -30,13 +30,10 @@ import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.branchConfig.InfoReliability;
import org.jetbrains.idea.svn.branchConfig.NewRootBunch;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.BranchConfigurationDialog;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.jetbrains.idea.svn.RootUrlInfo;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnFileUrlMapping;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
@@ -221,8 +218,9 @@ public class SelectBranchPopup {
@Override
protected void runImpl(@NotNull ProgressIndicator indicator) {
final SvnBranchConfigManager manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager();
new NewRootBunch.BranchesLoadRunnable(myProject, manager, selectedBranchesHolder, InfoReliability.setByUser, myVcsRoot, null, false).run();
final NewRootBunch manager = SvnBranchConfigurationManager.getInstance(myProject).getSvnBranchConfigManager();
manager.reloadBranches(myVcsRoot, selectedBranchesHolder, InfoReliability.setByUser, false);
}
});
}
@@ -1,47 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.vcs.CalledInBackground;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.SVNURL;
import java.util.List;
import java.util.Map;
public interface SvnBranchConfigManager {
void updateForRoot(@NotNull VirtualFile root, @NotNull InfoStorage<SvnBranchConfigurationNew> config,
@Nullable final PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> callbackOnUpdate);
void updateBranches(@NotNull VirtualFile root, @NotNull String branchesParent,
@NotNull InfoStorage<List<SvnBranchItem>> items);
@NotNull
SvnBranchConfigurationNew getConfig(@NotNull VirtualFile root);
void reloadBranches(@NotNull VirtualFile root, @NotNull String branchParentUrl,
Consumer<List<SvnBranchItem>> callback);
@Nullable
@CalledInBackground
SVNURL getWorkingBranchWithReload(final SVNURL svnurl, final VirtualFile root);
Map<VirtualFile, SvnBranchConfigurationNew> getMapCopy();
}
@@ -14,24 +14,36 @@
* limitations under the License.
*/
package org.jetbrains.idea.svn;
package org.jetbrains.idea.svn.branchConfig;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Default constructor and setters are necessary for serialization purposes.
*
* @author yole
*/
@SuppressWarnings("UnusedDeclaration")
public class SvnBranchConfiguration {
private String myTrunkUrl;
private List<String> myBranchUrls;
@NotNull private List<String> myBranchUrls;
private boolean myUserinfoInUrl;
public SvnBranchConfiguration() {
myBranchUrls = new ArrayList<String>();
}
public SvnBranchConfiguration(String trunkUrl, @NotNull List<String> branchUrls, boolean userinfoInUrl) {
myTrunkUrl = trunkUrl;
myBranchUrls = branchUrls;
Collections.sort(myBranchUrls);
myUserinfoInUrl = userinfoInUrl;
}
public boolean isUserinfoInUrl() {
return myUserinfoInUrl;
}
@@ -39,8 +51,8 @@ public class SvnBranchConfiguration {
public void setUserinfoInUrl(final boolean userinfoInUrl) {
myUserinfoInUrl = userinfoInUrl;
}
public void setBranchUrls(final List<String> branchUrls) {
public void setBranchUrls(@NotNull List<String> branchUrls) {
myBranchUrls = branchUrls;
Collections.sort(myBranchUrls);
}
@@ -53,6 +65,7 @@ public class SvnBranchConfiguration {
return myTrunkUrl;
}
@NotNull
public List<String> getBranchUrls() {
return myBranchUrls;
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.idea.svn;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
@@ -27,7 +27,6 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManagerQueue;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.committed.VcsConfigurationChangeListener;
@@ -35,14 +34,10 @@ import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vcs.impl.VcsInitObject;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PairConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.branchConfig.*;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.jetbrains.idea.svn.SvnVcs;
import java.io.File;
import java.util.*;
@@ -58,15 +53,16 @@ import java.util.*;
)}
)
public class SvnBranchConfigurationManager implements PersistentStateComponent<SvnBranchConfigurationManager.ConfigurationBean> {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnBranchConfigurationManager");
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager");
private final Project myProject;
private final ProjectLevelVcsManager myVcsManager;
private final SvnLoadedBrachesStorage myStorage;
private final SvnLoadedBranchesStorage myStorage;
private final ProgressManagerQueue myBranchesLoader;
private boolean myIsInitialized;
public SvnBranchConfigurationManager(final Project project,
final ProjectLevelVcsManager vcsManager,
final SvnLoadedBrachesStorage storage) {
final SvnLoadedBranchesStorage storage) {
myProject = project;
myVcsManager = vcsManager;
myStorage = storage;
@@ -91,7 +87,13 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
}
public static SvnBranchConfigurationManager getInstance(final Project project) {
return PeriodicalTasksCloser.getInstance().safeGetService(project, SvnBranchConfigurationManager.class);
SvnBranchConfigurationManager result = PeriodicalTasksCloser.getInstance().safeGetService(project, SvnBranchConfigurationManager.class);
if (result != null) {
result.initialize();
}
return result;
}
public static class ConfigurationBean {
@@ -108,19 +110,18 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
}
private ConfigurationBean myConfigurationBean = new ConfigurationBean();
private final SvnBranchConfigManager myBunch;
private final NewRootBunch myBunch;
public SvnBranchConfigurationNew get(@NotNull final VirtualFile vcsRoot) throws VcsException {
return myBunch.getConfig(vcsRoot);
}
public SvnBranchConfigManager getSvnBranchConfigManager() {
public NewRootBunch getSvnBranchConfigManager() {
return myBunch;
}
public void setConfiguration(final VirtualFile vcsRoot, final SvnBranchConfigurationNew configuration) {
myBunch.updateForRoot(vcsRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.setByUser),
new BranchesPreloader(myProject, myBunch, vcsRoot, myBranchesLoader));
myBunch.updateForRoot(vcsRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.setByUser), true);
SvnBranchMapperManager.getInstance().notifyBranchesChanged(myProject, vcsRoot, configuration);
@@ -136,71 +137,33 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
for (VirtualFile root : myBunch.getMapCopy().keySet()) {
final String key = root.getPath();
final SvnBranchConfigurationNew configOrig = myBunch.getConfig(root);
final SvnBranchConfiguration configuration = new SvnBranchConfiguration();
configuration.setTrunkUrl(configOrig.getTrunkUrl());
configuration.setUserinfoInUrl(configOrig.isUserinfoInUrl());
configuration.setBranchUrls(configOrig.getBranchUrls());
final HashMap<String, List<SvnBranchItem>> map = new HashMap<String, List<SvnBranchItem>>();
final Map<String, InfoStorage<List<SvnBranchItem>>> origMap = configOrig.getBranchMap();
for (String origKey : origMap.keySet()) {
map.put(origKey, origMap.get(origKey).getValue());
}
final SvnBranchConfiguration configuration =
new SvnBranchConfiguration(configOrig.getTrunkUrl(), configOrig.getBranchUrls(), configOrig.isUserinfoInUrl());
result.myConfigurationMap.put(key, helper.prepareForSerialization(configuration));
}
result.mySupportsUserInfoFilter = true;
return result;
}
private static class BranchesPreloader implements PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> {
private final Project myProject;
private final VirtualFile myRoot;
private final ProgressManagerQueue myQueue;
private final SvnBranchConfigManager myBunch;
private boolean myAll;
public void loadState(ConfigurationBean object) {
myConfigurationBean = object;
}
public BranchesPreloader(Project project, @NotNull final SvnBranchConfigManager bunch, VirtualFile root,
final ProgressManagerQueue queue) {
myBunch = bunch;
myProject = project;
myRoot = root;
myQueue = queue;
}
private synchronized void initialize() {
if (!myIsInitialized) {
myIsInitialized = true;
public void consume(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) {
myQueue.run(new Runnable() {
public void run() {
loadImpl(prev, next);
}
});
}
protected void loadImpl(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) {
final Set<String> oldUrls = (prev == null) ? Collections.<String>emptySet() : new HashSet<String>(prev.getBranchUrls());
final SvnVcs vcs = SvnVcs.getInstance(myProject);
if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return;
for (String newBranchUrl : next.getBranchUrls()) {
// check if cancel had been put
if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return;
if (myAll || (! oldUrls.contains(newBranchUrl))) {
new NewRootBunch.BranchesLoadRunnable(myProject, myBunch, newBranchUrl, InfoReliability.defaultValues, myRoot, null, true).run();
}
}
}
public void setAll(boolean all) {
myAll = all;
preloadBranches(resolveAllBranchPoints());
}
}
public void loadState(final ConfigurationBean object) {
final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject));
final Map<String, SvnBranchConfiguration> map = object.myConfigurationMap;
final Map<String, SvnBranchConfiguration> newMap = new HashMap<String, SvnBranchConfiguration>(map.size(), 1);
@NotNull
private Set<Pair<VirtualFile, SvnBranchConfigurationNew>> resolveAllBranchPoints() {
final LocalFileSystem lfs = LocalFileSystem.getInstance();
final Set<Pair<VirtualFile, SvnBranchConfigurationNew>> whatToInit = new HashSet<Pair<VirtualFile, SvnBranchConfigurationNew>>();
for (Map.Entry<String, SvnBranchConfiguration> entry : map.entrySet()) {
final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject));
final Set<Pair<VirtualFile, SvnBranchConfigurationNew>> branchPointsToLoad = ContainerUtil.newHashSet();
for (Map.Entry<String, SvnBranchConfiguration> entry : myConfigurationBean.myConfigurationMap.entrySet()) {
final SvnBranchConfiguration configuration = entry.getValue();
final VirtualFile root = lfs.refreshAndFindFileByIoFile(new File(entry.getKey()));
if (root == null) {
@@ -222,22 +185,24 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
if (stored != null && ! stored.isEmpty()) {
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(stored, InfoReliability.setByUser));
} else {
whatToInit.add(Pair.create(root, newConfig));
branchPointsToLoad.add(Pair.create(root, newConfig));
newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
}
}
myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), null);
myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), false);
}
return branchPointsToLoad;
}
private void preloadBranches(@NotNull final Collection<Pair<VirtualFile, SvnBranchConfigurationNew>> branchPoints) {
((ProjectLevelVcsManagerImpl) myVcsManager).addInitializationRequest(VcsInitObject.BRANCHES, new Runnable() {
public void run() {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
try {
for (Pair<VirtualFile, SvnBranchConfigurationNew> pair : whatToInit) {
final BranchesPreloader branchesPreloader = new BranchesPreloader(myProject, myBunch, pair.getFirst(), myBranchesLoader);
branchesPreloader.setAll(true);
branchesPreloader.loadImpl(null, pair.getSecond());
for (Pair<VirtualFile, SvnBranchConfigurationNew> pair : branchPoints) {
myBunch.reloadBranches(pair.getFirst(), null, pair.getSecond());
}
}
catch (ProcessCanceledException e) {
@@ -247,9 +212,6 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
});
}
});
object.myConfigurationMap.clear();
object.myConfigurationMap.putAll(newMap);
myConfigurationBean = object;
}
private List<SvnBranchItem> getStored(String branchUrl) {
@@ -259,93 +221,4 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
Collections.sort(items);
return items;
}
private static class UrlSerializationHelper {
private final SvnVcs myVcs;
private UrlSerializationHelper(final SvnVcs vcs) {
myVcs = vcs;
}
public SvnBranchConfiguration prepareForSerialization(final SvnBranchConfiguration configuration) {
final Ref<Boolean> withUserInfo = new Ref<Boolean>();
final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo);
if (Boolean.FALSE.equals(withUserInfo.get())) {
return configuration;
}
final List<String> branches = configuration.getBranchUrls();
final List<String> newBranchesList = new ArrayList<String>(branches.size());
for (String s : branches) {
newBranchesList.add(serializeUrl(s, withUserInfo));
}
final SvnBranchConfiguration result = new SvnBranchConfiguration();
result.setTrunkUrl(trunkUrl);
result.setBranchUrls(newBranchesList);
result.setUserinfoInUrl(withUserInfo.isNull() ? false : withUserInfo.get());
return result;
}
public SvnBranchConfiguration afterDeserialization(final String path, final SvnBranchConfiguration configuration) {
if (! configuration.isUserinfoInUrl()) {
return configuration;
}
final String userInfo = getUserInfo(path);
if (userInfo == null) {
return configuration;
}
final String newTrunkUrl = deserializeUrl(configuration.getTrunkUrl(), userInfo);
final List<String> branches = configuration.getBranchUrls();
final List<String> newBranchesList = new ArrayList<String>(branches.size());
for (String s : branches) {
newBranchesList.add(deserializeUrl(s, userInfo));
}
final SvnBranchConfiguration result = new SvnBranchConfiguration();
result.setTrunkUrl(newTrunkUrl);
result.setBranchUrls(newBranchesList);
result.setUserinfoInUrl(userInfo != null && userInfo.length() > 0);
return result;
}
private static String serializeUrl(final String url, final Ref<Boolean> withUserInfo) {
if (Boolean.FALSE.equals(withUserInfo.get())) {
return url;
}
try {
final SVNURL svnurl = SVNURL.parseURIEncoded(url);
if (withUserInfo.isNull()) {
final String userInfo = svnurl.getUserInfo();
withUserInfo.set((userInfo != null) && (userInfo.length() > 0));
}
if (withUserInfo.get()) {
return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), true)
.toString();
}
}
catch (SVNException e) {
//
}
return url;
}
@Nullable
private String getUserInfo(final String path) {
final SVNURL svnurl = myVcs.getSvnFileUrlMapping().getUrlForFile(new File(path));
return svnurl != null ? svnurl.getUserInfo() : null;
}
private static String deserializeUrl(final String url, final String userInfo) {
try {
final SVNURL svnurl = SVNURL.parseURIEncoded(url);
return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(),
true).toString();
} catch (SVNException e) {
return url;
}
}
}
}
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
@@ -98,7 +97,7 @@ public class SvnBranchConfigurationNew {
LOG.info("Branches list not updated for : '" + branchParentName + "; since config has changed.");
return;
}
current.accept(items, null);
current.accept(items);
}
public Map<String, InfoStorage<List<SvnBranchItem>>> getBranchMap() {
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.integrate;
package org.jetbrains.idea.svn.branchConfig;
import java.util.Date;
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.messages.Topic;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import java.io.File;
import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Holds what working copies we have for URLs
@@ -56,7 +56,6 @@ public class SvnBranchMapperManager implements PersistentStateComponent<SvnBranc
public void put(final String url, final String value) {
myStateHolder.put(url, value);
notifyWcRootsChanged(url, Collections.unmodifiableCollection(myStateHolder.get(url)));
}
public void remove(final String url, final File value) {
@@ -64,11 +63,6 @@ public class SvnBranchMapperManager implements PersistentStateComponent<SvnBranc
if (set != null) {
set.remove(value.getAbsolutePath());
}
notifyWcRootsChanged(url, Collections.unmodifiableCollection(set));
}
private static void notifyWcRootsChanged(final String url, final Collection<String> roots) {
ApplicationManager.getApplication().getMessageBus().syncPublisher(WC_ROOTS_CHANGED).rootsChanged(url, roots);
}
public void notifyBranchesChanged(final Project project, final VirtualFile vcsRoot, final SvnBranchConfigurationNew configuration) {
@@ -104,11 +98,4 @@ public class SvnBranchMapperManager implements PersistentStateComponent<SvnBranc
return myMapping.get(key);
}
}
public static interface WcRootsChangeConsumer {
void rootsChanged(final String url, final Collection<String> roots);
}
public static final Topic<WcRootsChangeConsumer> WC_ROOTS_CHANGED =
new Topic<WcRootsChangeConsumer>("SVN_WC_ROOTS_CHANGED", WcRootsChangeConsumer.class);
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn;
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.project.Project;
@@ -23,9 +23,6 @@ import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import java.io.DataInput;
import java.io.DataOutput;
@@ -39,13 +36,13 @@ import java.util.*;
* Date: 8/24/11
* Time: 1:21 PM
*/
public class SvnLoadedBrachesStorage {
public class SvnLoadedBranchesStorage {
private final Object myLock;
private SmallMapSerializer<String, Map<String, Collection<SvnBranchItem>>> myState;
private final File myFile;
private final Project myProject;
public SvnLoadedBrachesStorage(final Project project) {
public SvnLoadedBranchesStorage(final Project project) {
myProject = project;
final File vcsFile = new File(PathManager.getSystemPath(), "vcs");
File file = new File(vcsFile, "svn_branches");
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.branchConfig;
import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konstantin Kolosovsky.
*/
public class UrlSerializationHelper {
private final SvnVcs myVcs;
public UrlSerializationHelper(final SvnVcs vcs) {
myVcs = vcs;
}
public SvnBranchConfiguration prepareForSerialization(final SvnBranchConfiguration configuration) {
final Ref<Boolean> withUserInfo = new Ref<Boolean>();
final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo);
if (Boolean.FALSE.equals(withUserInfo.get())) {
return configuration;
}
final List<String> branches = configuration.getBranchUrls();
final List<String> newBranchesList = new ArrayList<String>(branches.size());
for (String s : branches) {
newBranchesList.add(serializeUrl(s, withUserInfo));
}
return new SvnBranchConfiguration(trunkUrl, newBranchesList, withUserInfo.isNull() ? false : withUserInfo.get());
}
public SvnBranchConfiguration afterDeserialization(final String path, final SvnBranchConfiguration configuration) {
if (! configuration.isUserinfoInUrl()) {
return configuration;
}
final String userInfo = getUserInfo(path);
if (userInfo == null) {
return configuration;
}
final String newTrunkUrl = deserializeUrl(configuration.getTrunkUrl(), userInfo);
final List<String> branches = configuration.getBranchUrls();
final List<String> newBranchesList = new ArrayList<String>(branches.size());
for (String s : branches) {
newBranchesList.add(deserializeUrl(s, userInfo));
}
return new SvnBranchConfiguration(newTrunkUrl, newBranchesList, userInfo.length() > 0);
}
private static String serializeUrl(final String url, final Ref<Boolean> withUserInfo) {
if (Boolean.FALSE.equals(withUserInfo.get())) {
return url;
}
try {
final SVNURL svnurl = SVNURL.parseURIEncoded(url);
if (withUserInfo.isNull()) {
final String userInfo = svnurl.getUserInfo();
withUserInfo.set((userInfo != null) && (userInfo.length() > 0));
}
if (withUserInfo.get()) {
return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), true)
.toString();
}
}
catch (SVNException e) {
//
}
return url;
}
@Nullable
private String getUserInfo(final String path) {
final SVNURL svnurl = myVcs.getSvnFileUrlMapping().getUrlForFile(new File(path));
return svnurl != null ? svnurl.getUserInfo() : null;
}
private static String deserializeUrl(final String url, final String userInfo) {
try {
final SVNURL svnurl = SVNURL.parseURIEncoded(url);
return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(),
true).toString();
} catch (SVNException e) {
return url;
}
}
}
@@ -124,7 +124,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
String comment,
List<VcsException> exception,
final Set<String> feedback,
final WorkingCopyFormat format)
@NotNull WorkingCopyFormat format)
throws VcsException {
if (committables.isEmpty()) {
return;
@@ -45,7 +45,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.actions.CleanupWorker;
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.BranchConfigurationDialog;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.api.ClientFactory;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
@@ -41,7 +41,6 @@ import org.jetbrains.idea.svn.properties.PropertyConsumer;
import org.jetbrains.idea.svn.properties.PropertyData;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -309,7 +308,7 @@ public class PropertiesComponent extends JPanel {
PropertyValue propValue = null;
try {
propValue = myVcs.getFactory(myFile).createPropertyClient()
.getProperty(SvnTarget.fromFile(myFile), SVNProperty.KEYWORDS, false, SVNRevision.WORKING);
.getProperty(SvnTarget.fromFile(myFile), SvnPropertyKeys.SVN_KEYWORDS, false, SVNRevision.WORKING);
}
catch (VcsException e1) {
// show erorr message
@@ -26,7 +26,7 @@ import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
/**
@@ -48,7 +48,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.actions.ConfigureBranchesAction;
import org.jetbrains.idea.svn.branchConfig.ConfigureBranchesAction;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.status.Status;
@@ -24,10 +24,10 @@ import com.intellij.util.NullableFunction;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBranchMapperManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches;
import org.jetbrains.idea.svn.integrate.IntegratedSelectedOptionsDialog;
@@ -23,10 +23,11 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.WCInfo;
import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.jetbrains.idea.svn.branchConfig.SvnBranchItem;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import java.io.File;
@@ -35,6 +35,8 @@ import java.util.Date;
*/
public class Info extends BaseNodeDescription {
public static final String SCHEDULE_ADD = "add";
private final File myFile;
private final String myPath;
private final SVNURL myURL;
@@ -32,6 +32,7 @@ import com.intellij.util.PlatformIcons;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager;
import org.jetbrains.idea.svn.info.Info;
import org.tmatesoft.svn.core.SVNURL;
@@ -18,7 +18,7 @@ package org.jetbrains.idea.svn.integrate;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.dialogs.MergeContext;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnConfiguration;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
@@ -19,7 +19,9 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
@@ -28,6 +30,7 @@ import com.intellij.openapi.vcs.changes.InvokeAfterUpdateMode;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog;
import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.update.*;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
@@ -330,18 +333,37 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable {
});
}
final SvnChangeProvider provider = new SvnChangeProvider(myVcs);
final GatheringChangelistBuilder clb = new GatheringChangelistBuilder(myVcs, myAccomulatedFiles);
try {
provider.getChanges(dirtyScope, clb, ProgressManager.getInstance().getProgressIndicator(), null);
} catch (VcsException e) {
Messages.showErrorDialog(SvnBundle.message("action.Subversion.integrate.changes.error.unable.to.collect.changes.text",
e.getMessage()), myTitle);
return;
}
new Task.Backgroundable(myVcs.getProject(),
SvnBundle.message("action.Subversion.integrate.changes.collecting.changes.to.commit.task.title")) {
if (! clb.getChanges().isEmpty()) {
CommitChangeListDialog.commitAlienChanges(myProject, clb.getChanges(), myVcs, myMerger.getComment(), myMerger.getComment());
}
private final GatheringChangelistBuilder changesBuilder = new GatheringChangelistBuilder(myVcs, myAccomulatedFiles);
private final Ref<String> caughtError = new Ref<String>();
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
if (!myVcs.getProject().isDisposed()) {
final SvnChangeProvider provider = new SvnChangeProvider(myVcs);
try {
provider.getChanges(dirtyScope, changesBuilder, indicator, null);
}
catch (VcsException e) {
caughtError.set(SvnBundle.message("action.Subversion.integrate.changes.error.unable.to.collect.changes.text", e.getMessage()));
}
}
}
@Override
public void onSuccess() {
if (!caughtError.isNull()) {
VcsBalloonProblemNotifier.showOverVersionControlView(myVcs.getProject(), caughtError.get(), MessageType.ERROR);
}
else if (!changesBuilder.getChanges().isEmpty()) {
CommitChangeListDialog
.commitAlienChanges(myProject, changesBuilder.getChanges(), myVcs, myMerger.getComment(), myMerger.getComment());
}
}
}.queue();
}
}
@@ -19,11 +19,15 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.history.SvnChangeList;
import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNMergeRange;
import org.tmatesoft.svn.core.SVNMergeRangeList;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNMergeInfoUtil;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
@@ -209,7 +213,8 @@ public class BranchInfo {
SvnTarget target = SvnTarget.fromURL(branchUrl);
try {
mergeinfoProperty = myVcs.getFactory(target).createPropertyClient().getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.create(targetRevision));
mergeinfoProperty = myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false,
SVNRevision.create(targetRevision));
}
catch (VcsException e) {
LOG.info(e);
@@ -283,13 +288,13 @@ public class BranchInfo {
// look in WC
SvnTarget target = SvnTarget.fromFile(pathFile, SVNRevision.WORKING);
mergeinfoProperty =
myVcs.getFactory(target).createPropertyClient().getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.WORKING);
myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.WORKING);
} else {
// in repo
myMixedRevisionsFound = true;
SvnTarget target = SvnTarget.fromURL(svnInfo.getURL());
mergeinfoProperty = myVcs.getFactory(target).createPropertyClient()
.getProperty(target, SVNProperty.MERGE_INFO, false, SVNRevision.create(targetRevisionCorrected));
.getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.create(targetRevisionCorrected));
}
}
catch (VcsException e) {
@@ -21,12 +21,16 @@ import com.intellij.openapi.vcs.AreaMap;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.PairProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.dialogs.MergeContext;
import org.jetbrains.idea.svn.properties.PropertyConsumer;
import org.jetbrains.idea.svn.properties.PropertyData;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNMergeRange;
import org.tmatesoft.svn.core.SVNMergeRangeList;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNMergeInfoUtil;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
@@ -83,7 +87,7 @@ public class OneRecursiveShotMergeInfoWorker implements MergeInfoWorker {
File path = new File(myMergeContext.getWcInfo().getPath());
myMergeContext.getVcs().getFactory(path).createPropertyClient()
.getProperty(SvnTarget.fromFile(path), SVNProperty.MERGE_INFO, SVNRevision.WORKING, depth, handler);
.getProperty(SvnTarget.fromFile(path), SvnPropertyKeys.MERGE_INFO, SVNRevision.WORKING, depth, handler);
}
public SvnMergeInfoCache.MergeCheckResult isMerged(final String relativeToRepoURLPath, final long revisionNumber) {
@@ -1,5 +1,7 @@
package org.jetbrains.idea.svn.properties;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vcs.VcsException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,6 +32,8 @@ import java.util.Map;
*/
public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
private static final Logger LOG = Logger.getInstance(CmdPropertyClient.class);
@Nullable
@Override
public PropertyValue getProperty(@NotNull SvnTarget target,
@@ -57,7 +61,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
parameters.add("--xml");
CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null);
PropertyData data = parseSingleProperty(target, command.getOutput());
PropertyData data = parseSingleProperty(target, command);
return data != null ? data.getValue() : null;
}
@@ -74,7 +78,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
fillListParameters(target, revision, depth, parameters, false);
CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null);
parseOutput(target, command.getOutput(), handler);
parseOutput(target, command, handler);
}
@Override
@@ -86,7 +90,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
fillListParameters(target, revision, depth, parameters, true);
CommandExecutor command = execute(myVcs, target, SvnCommandName.proplist, parameters, null);
parseOutput(target, command.getOutput(), handler);
parseOutput(target, command, handler);
}
@Override
@@ -183,7 +187,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
@Nullable
private PropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException {
private PropertyData parseSingleProperty(SvnTarget target, @NotNull CommandExecutor command) throws VcsException {
final PropertyData[] data = new PropertyData[1];
PropertyConsumer handler = new PropertyConsumer() {
@Override
@@ -202,14 +206,14 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
};
parseOutput(target, output, handler);
parseOutput(target, command, handler);
return data[0];
}
private static void parseOutput(SvnTarget target, String output, PropertyConsumer handler) throws VcsException {
private static void parseOutput(SvnTarget target, @NotNull CommandExecutor command, PropertyConsumer handler) throws VcsException {
try {
Properties properties = CommandUtil.parse(output, Properties.class);
Properties properties = CommandUtil.parse(command.getOutput(), Properties.class);
if (properties != null) {
for (Target childInfo : properties.targets) {
@@ -227,6 +231,8 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
}
}
catch (JAXBException e) {
LOG.error("Could not parse properties. Command: " + command.getCommandText() + ", Warning: " + command.getErrorOutput(),
new Attachment("output.xml", command.getOutput()));
throw new VcsException(e);
}
catch (SVNException e) {
@@ -37,8 +37,10 @@ import org.jetbrains.idea.svn.info.Info;
import org.jetbrains.idea.svn.properties.PropertiesMap;
import org.jetbrains.idea.svn.properties.PropertyConsumer;
import org.jetbrains.idea.svn.properties.PropertyData;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
@@ -312,7 +314,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
if (info.isFile()) {
doRevert(file, false);
} else {
if (SVNProperty.SCHEDULE_ADD.equals(info.getSchedule())) {
if (Info.SCHEDULE_ADD.equals(info.getSchedule())) {
doRevert(file, true);
} else {
boolean is17OrGreater = is17OrGreaterCopy(file, info);
@@ -103,6 +103,7 @@ public class CmdStatusClient extends BaseSvnClient implements StatusClient {
// so it does not contain any <entry> element and current parsing logic returns null
PortableStatus status = new PortableStatus();
status.setFile(path);
status.setPath(path.getAbsolutePath());
status.setContentsStatus(StatusType.STATUS_NORMAL);
status.setInfoGetter(new Getter<Info>() {
@@ -145,6 +145,7 @@ public abstract class AbstractSvnUpdateIntegrateEnvironment implements UpdateEnv
}
public void onRefreshFilesCompleted() {
// TODO: why do we need to mark all roots as dirty here???
dirtyRoots();
for (Runnable groupWorker : myGroupWorkers) {
@@ -22,7 +22,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.vcs.FilePath;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
import org.jetbrains.idea.svn.history.SvnChangeList;
@@ -36,9 +36,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.SvnTestCase;
import org.jetbrains.idea.svn.branchConfig.InfoReliability;
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.*;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.jetbrains.idea.svn.branchConfig.SvnBranchItem;
import org.jetbrains.idea.svn.mergeinfo.MergeChecker;
import org.junit.Before;
import org.junit.Test;