mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'svn_18_3'
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
@@ -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
-1
@@ -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>
|
||||
+4
-8
@@ -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() {
|
||||
|
||||
+1
-3
@@ -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 {
|
||||
+2
-2
@@ -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
-1
@@ -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"/>
|
||||
+2
-3
@@ -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;
|
||||
+155
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-10
@@ -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();
|
||||
}
|
||||
+17
-4
@@ -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;
|
||||
}
|
||||
+40
-167
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+5
-18
@@ -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);
|
||||
}
|
||||
+3
-6
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+34
-12
@@ -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) {
|
||||
|
||||
+6
-2
@@ -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>() {
|
||||
|
||||
+1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user