mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'svn_18_2'
This commit is contained in:
@@ -35,6 +35,8 @@ public class AttributeBinding implements Binding {
|
||||
@Override
|
||||
public Object serialize(@NotNull Object o, Object context, SerializationFilter filter) {
|
||||
final Object v = myAccessor.read(o);
|
||||
if (v == null) return context;
|
||||
|
||||
final Object node = myBinding.serialize(v, context, filter);
|
||||
|
||||
return new org.jdom.Attribute(myAttribute.value(), ((Content)node).getValue());
|
||||
|
||||
@@ -323,6 +323,10 @@ public class VcsUtil {
|
||||
return getFilePath(new File(path), isDirectory);
|
||||
}
|
||||
|
||||
public static FilePath getFilePathOnNonLocal(String path, boolean isDirectory) {
|
||||
return VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(path, isDirectory);
|
||||
}
|
||||
|
||||
public static FilePath getFilePath(File file, boolean isDirectory) {
|
||||
return VcsContextFactory.SERVICE.getInstance().createFilePathOn(file, isDirectory);
|
||||
}
|
||||
|
||||
+20
-13
@@ -32,14 +32,23 @@ import java.util.*;
|
||||
*
|
||||
*/
|
||||
@SomeQueue
|
||||
// TODO: Used only in RemoteRevisionsNumberCache
|
||||
public class LazyRefreshingSelfQueue<T> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.LazyRefreshingSelfQueue");
|
||||
|
||||
// provides update interval in milliseconds.
|
||||
private final Getter<Long> myUpdateInterval;
|
||||
// head is old. tail is new
|
||||
// structure:
|
||||
// 1) pairs with First == null
|
||||
// 2) pairs with First != null sorted by First ascending
|
||||
// pair.First - time when T was last processed
|
||||
// pair.Second - some item T
|
||||
private final LinkedList<Pair<Long, T>> myQueue;
|
||||
// Set of items that should be processed by myUpdater
|
||||
private final Set<T> myInProgress;
|
||||
// checks if updateStep should be really performed
|
||||
private final Computable<Boolean> myShouldUpdateOldChecker;
|
||||
// performs some actions on item T, for instance - updates some data for T in cache
|
||||
private final Consumer<T> myUpdater;
|
||||
private final Object myLock;
|
||||
|
||||
@@ -52,20 +61,14 @@ public class LazyRefreshingSelfQueue<T> {
|
||||
myLock = new Object();
|
||||
}
|
||||
|
||||
// adds item that should be updated at next updateStep() call
|
||||
public void addRequest(@NotNull final T t) {
|
||||
synchronized (myLock) {
|
||||
myQueue.addFirst(new Pair<Long,T>(null, t));
|
||||
}
|
||||
}
|
||||
|
||||
public void addRequests(final Collection<T> values) {
|
||||
synchronized (myLock) {
|
||||
for (T value : values) {
|
||||
myQueue.addFirst(new Pair<Long,T>(null, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unschedules item from update at next updateStep() call
|
||||
public void forceRemove(@NotNull final T t) {
|
||||
synchronized (myLock) {
|
||||
for (Iterator<Pair<Long, T>> iterator = myQueue.iterator(); iterator.hasNext();) {
|
||||
@@ -80,11 +83,11 @@ public class LazyRefreshingSelfQueue<T> {
|
||||
|
||||
// called by outside timer or something
|
||||
public void updateStep() {
|
||||
final List<T> dirty = new LinkedList<T>();
|
||||
|
||||
final long startTime = System.currentTimeMillis() - myUpdateInterval.get();
|
||||
boolean onlyAbsolute = true;
|
||||
// check if we have some old items at all - if not, we would not check if repository latest revision had changed and will save time
|
||||
// TODO: Actually we could store items with pair.First == null in separate list.
|
||||
// checks item that has smallest update time - i.e. was not updated by the most time
|
||||
// if its update time greater than current - interval => we should not update any item with pair.First != null this time (as they are ordered)
|
||||
synchronized (myLock) {
|
||||
for (Pair<Long, T> pair : myQueue) {
|
||||
if (pair.getFirst() != null) {
|
||||
@@ -96,9 +99,10 @@ public class LazyRefreshingSelfQueue<T> {
|
||||
|
||||
// do not ask under lock
|
||||
final Boolean shouldUpdateOld = onlyAbsolute ? false : myShouldUpdateOldChecker.compute();
|
||||
final List<T> dirty = new LinkedList<T>();
|
||||
|
||||
synchronized (myLock) {
|
||||
// get absolute
|
||||
// adds all pairs with pair.First == null to dirty
|
||||
while (! myQueue.isEmpty()) {
|
||||
final Pair<Long, T> pair = myQueue.get(0);
|
||||
if (pair.getFirst() == null) {
|
||||
@@ -108,6 +112,7 @@ public class LazyRefreshingSelfQueue<T> {
|
||||
}
|
||||
}
|
||||
if (Boolean.TRUE.equals(shouldUpdateOld) && (! myQueue.isEmpty())) {
|
||||
// adds all pairs with update time (pair.First) < current - interval to dirty
|
||||
while (! myQueue.isEmpty()) {
|
||||
final Pair<Long, T> pair = myQueue.get(0);
|
||||
if (pair.getFirst() < startTime) {
|
||||
@@ -126,6 +131,8 @@ public class LazyRefreshingSelfQueue<T> {
|
||||
for (T t : dirty) {
|
||||
myUpdater.consume(t);
|
||||
synchronized (myLock) {
|
||||
// output value of remove() is tracked not to process items that were removed from myInProgress in forceRemove()
|
||||
// TODO: Probably more clear logic should be implemented
|
||||
if (myInProgress.remove(t)) {
|
||||
myQueue.addLast(new Pair<Long,T>(System.currentTimeMillis(), t));
|
||||
}
|
||||
|
||||
+18
@@ -88,11 +88,13 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
|
||||
public boolean updateStep() {
|
||||
mySomethingChanged = false;
|
||||
// copy under lock
|
||||
final HashMap<VcsRoot, LazyRefreshingSelfQueue> copyMap;
|
||||
synchronized (myLock) {
|
||||
copyMap = new HashMap<VcsRoot, LazyRefreshingSelfQueue>(myRefreshingQueues);
|
||||
}
|
||||
|
||||
// filter only items for vcs roots that support background operations
|
||||
for (Iterator<Map.Entry<VcsRoot, LazyRefreshingSelfQueue>> iterator = copyMap.entrySet().iterator(); iterator.hasNext();) {
|
||||
final Map.Entry<VcsRoot, LazyRefreshingSelfQueue> entry = iterator.next();
|
||||
final VcsRoot key = entry.getKey();
|
||||
@@ -103,6 +105,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
}
|
||||
}
|
||||
LOG.debug("queues refresh started, queues: " + copyMap.size());
|
||||
// refresh "up to date" info
|
||||
for (LazyRefreshingSelfQueue queue : copyMap.values()) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
queue.updateStep();
|
||||
@@ -111,10 +114,12 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
}
|
||||
|
||||
public void directoryMappingChanged() {
|
||||
// copy myData under lock
|
||||
HashSet<String> keys;
|
||||
synchronized (myLock) {
|
||||
keys = new HashSet<String>(myData.keySet());
|
||||
}
|
||||
// collect new vcs for scheduled files
|
||||
final Map<String, Pair<VirtualFile, AbstractVcs>> vFiles = new HashMap<String, Pair<VirtualFile, AbstractVcs>>();
|
||||
for (String key : keys) {
|
||||
final VirtualFile vf = myLfs.refreshAndFindFileByIoFile(new File(key));
|
||||
@@ -244,6 +249,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
public void consume(String s) {
|
||||
LOG.debug("update for: " + s);
|
||||
//todo check canceled - check VCS's ready for asynchronous queries
|
||||
// get last remote revision for file
|
||||
final VirtualFile vf = myLfs.refreshAndFindFileByIoFile(new File(s));
|
||||
final ItemLatestState state;
|
||||
final DiffProvider diffProvider = myVcsRoot.getVcs().getDiffProvider();
|
||||
@@ -256,6 +262,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
final VcsRevisionNumber newNumber = (state == null) || state.isDefaultHead() ? UNKNOWN : state.getNumber();
|
||||
|
||||
final Pair<VcsRoot, VcsRevisionNumber> oldPair;
|
||||
// update value in cache
|
||||
synchronized (myLock) {
|
||||
oldPair = myData.get(s);
|
||||
myData.put(s, new Pair<VcsRoot, VcsRevisionNumber>(myVcsRoot, newNumber));
|
||||
@@ -275,6 +282,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
myVcsRoot = vcsRoot;
|
||||
}
|
||||
|
||||
// Check if currently cached vcs root latest revision is less than latest vcs root revision
|
||||
// => update should be performed in this case
|
||||
public Boolean compute() {
|
||||
final AbstractVcs vcs = myVcsRoot.getVcs();
|
||||
// won't be called in parallel for same vcs -> just synchronized map is ok
|
||||
@@ -282,6 +291,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
LOG.debug("should update for: " + vcsName + " root: " + myVcsRoot.getPath().getPath());
|
||||
final VcsRevisionNumber latestNew = vcs.getDiffProvider().getLatestCommittedRevision(myVcsRoot.getPath());
|
||||
|
||||
// TODO: Why vcsName is used as key and not myVcsRoot.getKey()???
|
||||
// TODO: This seems to be invalid logic as we get latest revision for vcs root
|
||||
final VcsRevisionNumber latestKnown = myLatestRevisionsMap.get(vcsName);
|
||||
// not known
|
||||
if (latestNew == null) return true;
|
||||
@@ -307,8 +318,15 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
|
||||
return getRevisionState(change.getBeforeRevision()) && getRevisionState(change.getAfterRevision());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if passed revision is up to date, comparing to latest repository revision.
|
||||
*
|
||||
* @param revision
|
||||
* @return
|
||||
*/
|
||||
private boolean getRevisionState(final ContentRevision revision) {
|
||||
if (revision != null) {
|
||||
// TODO: Seems peg revision should also be tracked here.
|
||||
final VcsRevisionNumber local = revision.getRevisionNumber();
|
||||
final String path = revision.getFile().getIOFile().getAbsolutePath();
|
||||
final VcsRevisionNumber remote = getNumber(path);
|
||||
|
||||
+16
-1
@@ -27,10 +27,14 @@ import java.util.*;
|
||||
|
||||
public class RemoteRevisionsStateCache implements ChangesOnServerTracker {
|
||||
private final static long DISCRETE = 3600000;
|
||||
// true -> changed
|
||||
// All files that were checked during cache update and were not invalidated.
|
||||
// pair.First - if file is changed (true means changed)
|
||||
// pair.Second - vcs root where file belongs to
|
||||
private final Map<String, Pair<Boolean, VcsRoot>> myChanged;
|
||||
|
||||
// All files that needs to be checked during next cache update, grouped by vcs root
|
||||
private final MultiMap<VcsRoot, String> myQueries;
|
||||
// All vcs roots for which cache update was performed with update timestamp
|
||||
private final Map<VcsRoot, Long> myTs;
|
||||
private final Object myLock;
|
||||
private final ProjectLevelVcsManager myVcsManager;
|
||||
@@ -104,6 +108,7 @@ public class RemoteRevisionsStateCache implements ChangesOnServerTracker {
|
||||
myVcsConfiguration.CHANGED_ON_SERVER_INTERVAL * 60000 : DISCRETE);
|
||||
|
||||
synchronized (myLock) {
|
||||
// just copies myQueries MultiMap to dirty MultiMap
|
||||
for (VcsRoot root : myQueries.keySet()) {
|
||||
final Collection<String> collection = myQueries.get(root);
|
||||
for (String s : collection) {
|
||||
@@ -112,15 +117,23 @@ public class RemoteRevisionsStateCache implements ChangesOnServerTracker {
|
||||
}
|
||||
myQueries.clear();
|
||||
|
||||
// collect roots for which cache update should be performed (by timestamp)
|
||||
final Set<VcsRoot> roots = new HashSet<VcsRoot>();
|
||||
for (Map.Entry<VcsRoot, Long> entry : myTs.entrySet()) {
|
||||
// ignore timestamp, as still remote changes checking is required
|
||||
// TODO: why not to add in roots anyway??? - as dirty is still checked when adding myChanged files.
|
||||
if (! dirty.get(entry.getKey()).isEmpty()) continue;
|
||||
|
||||
// update only if timeout expired
|
||||
final Long ts = entry.getValue();
|
||||
if ((ts == null) || (oldPoint > ts)) {
|
||||
roots.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
// Add dirty files from those vcs roots, that
|
||||
// - needs to be update by timestamp criteria
|
||||
// - that already contain files for update through manually added requests
|
||||
for (Map.Entry<String, Pair<Boolean, VcsRoot>> entry : myChanged.entrySet()) {
|
||||
final VcsRoot vcsRoot = entry.getValue().getSecond();
|
||||
if ((! dirty.get(vcsRoot).isEmpty()) || roots.contains(vcsRoot)) {
|
||||
@@ -142,6 +155,8 @@ public class RemoteRevisionsStateCache implements ChangesOnServerTracker {
|
||||
final Collection<String> paths = dirty.get(vcsRoot);
|
||||
final Collection<String> remotelyChanged = provider.getRemotelyChanged(vcsRoot.getPath(), paths);
|
||||
for (String path : paths) {
|
||||
// TODO: Contains invoked for each file - better to use Set (implementations just use List)
|
||||
// TODO: Why to store boolean for changed or not - why not just remove such values from myChanged???
|
||||
results.put(path, new Pair<Boolean, VcsRoot>(remotelyChanged.contains(path), vcsRoot));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -74,13 +74,7 @@ public class ChangeListDetailsAction extends AnAction implements DumbAware {
|
||||
detailsBuilder.append("<br>");
|
||||
|
||||
if (provider != null) {
|
||||
final CommittedChangeList originalChangeList;
|
||||
if (changeList instanceof ReceivedChangeList) {
|
||||
originalChangeList = ((ReceivedChangeList) changeList).getBaseList();
|
||||
}
|
||||
else {
|
||||
originalChangeList = changeList;
|
||||
}
|
||||
final CommittedChangeList originalChangeList = ReceivedChangeList.unwrap(changeList);
|
||||
for(ChangeListColumn column: provider.getColumns()) {
|
||||
if (ChangeListColumn.isCustom(column)) {
|
||||
String value = column.getValue(originalChangeList).toString();
|
||||
|
||||
+2
-3
@@ -688,14 +688,13 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
|
||||
if (lists.size() == 1) {
|
||||
return lists.get(0);
|
||||
}
|
||||
final CommittedChangeList victim = lists.get(0) instanceof ReceivedChangeList ? (((ReceivedChangeList) lists.get(0)).getBaseList()) :
|
||||
lists.get(0);
|
||||
final CommittedChangeList victim = ReceivedChangeList.unwrap(lists.get(0));
|
||||
final ReceivedChangeList result = new ReceivedChangeList(victim);
|
||||
result.setForcePartial(false);
|
||||
final Set<Change> baseChanges = new HashSet<Change>();
|
||||
|
||||
for (CommittedChangeList list : lists) {
|
||||
baseChanges.addAll(list instanceof ReceivedChangeList ? ((ReceivedChangeList) list).getBaseList().getChanges() : list.getChanges());
|
||||
baseChanges.addAll(ReceivedChangeList.unwrap(list).getChanges());
|
||||
|
||||
final Collection<Change> changes = list.getChanges();
|
||||
for (Change change : changes) {
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
<reference id="Compare.SameVersion" text="Compare with BASE revision"/>
|
||||
<reference id="Compare.LastVersion" text="Compare with revision at HEAD"/>
|
||||
<reference id="Compare.Selected"/>
|
||||
<action id="Subversion.CompareWithBranch" class="org.jetbrains.idea.svn.actions.CompareWithBranchAction"/>
|
||||
<action id="Subversion.CompareWithBranch" class="org.jetbrains.idea.svn.diff.CompareWithBranchAction"/>
|
||||
<reference id="Vcs.ShowTabbedFileHistory"/>
|
||||
<reference id="Vcs.ShowHistoryForBlock"/>
|
||||
<reference id="Annotate"/>
|
||||
@@ -139,5 +139,7 @@
|
||||
|
||||
<vcs name="svn" vcsClass="org.jetbrains.idea.svn.SvnVcs" displayName="Subversion" administrativeAreaName=".svn, _svn" crawlUpToCheckUnderVcs="true"/>
|
||||
<vcsPopupProvider implementation="org.jetbrains.idea.svn.actions.SvnQuickListContentProvider"/>
|
||||
|
||||
<statistics.usagesCollector implementation="org.jetbrains.idea.svn.statistics.SvnWorkingCopyFormatUsagesCollector"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -15,16 +15,24 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.config.DefaultProxyGroup;
|
||||
import org.jetbrains.idea.svn.config.ProxyGroup;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNConfigFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class IdeaSVNConfigFile {
|
||||
|
||||
public final static String SERVERS_FILE_NAME = "servers";
|
||||
|
||||
private final Map<String, String> myPatternsMap;
|
||||
private final long myLatestUpdate;
|
||||
private final File myFile;
|
||||
@@ -41,6 +49,59 @@ public class IdeaSVNConfigFile {
|
||||
myPatternsMap = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public static void putProxyIntoServersFile(final File configDir, final String host, final Proxy proxyInfo) {
|
||||
final IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(new File(configDir, SERVERS_FILE_NAME));
|
||||
configFile.updateGroups();
|
||||
|
||||
String groupName = ensureHostGroup(host, configFile);
|
||||
|
||||
final HashMap<String, String> map = new HashMap<String, String>();
|
||||
final InetSocketAddress address = ((InetSocketAddress) proxyInfo.address());
|
||||
map.put(SvnAuthenticationManager.HTTP_PROXY_HOST, address.getHostName());
|
||||
map.put(SvnAuthenticationManager.HTTP_PROXY_PORT, String.valueOf(address.getPort()));
|
||||
configFile.addGroup(groupName, host + "*", map);
|
||||
configFile.save();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String ensureHostGroup(@NotNull String host, @NotNull IdeaSVNConfigFile configFile) {
|
||||
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
|
||||
|
||||
if (StringUtil.isEmptyOrSpaces(groupName)) {
|
||||
groupName = getNewGroupName(host, configFile);
|
||||
}
|
||||
|
||||
return groupName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNewGroupName(@NotNull String host, @NotNull IdeaSVNConfigFile configFile) {
|
||||
String groupName = host;
|
||||
final Map<String,ProxyGroup> groups = configFile.getAllGroups();
|
||||
while (StringUtil.isEmptyOrSpaces(groupName) || groups.containsKey(groupName)) {
|
||||
groupName += "1";
|
||||
}
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public static boolean putProxyCredentialsIntoServerFile(@NotNull final File configDir, @NotNull final String host,
|
||||
@NotNull final PasswordAuthentication authentication) {
|
||||
final IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(new File(configDir, SERVERS_FILE_NAME));
|
||||
configFile.updateGroups();
|
||||
|
||||
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
|
||||
// no proxy defined in group -> no sense in password
|
||||
if (StringUtil.isEmptyOrSpaces(groupName)) return false;
|
||||
final Map<String, String> properties = configFile.getAllGroups().get(groupName).getProperties();
|
||||
if (StringUtil.isEmptyOrSpaces(properties.get(SvnAuthenticationManager.HTTP_PROXY_HOST))) return false;
|
||||
if (StringUtil.isEmptyOrSpaces(properties.get(SvnAuthenticationManager.HTTP_PROXY_PORT))) return false;
|
||||
|
||||
configFile.setValue(groupName, SvnAuthenticationManager.HTTP_PROXY_USERNAME, authentication.getUserName());
|
||||
configFile.setValue(groupName, SvnAuthenticationManager.HTTP_PROXY_PASSWORD, String.valueOf(authentication.getPassword()));
|
||||
configFile.save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateGroups() {
|
||||
if (myLatestUpdate != myFile.lastModified()) {
|
||||
myPatternsMap.clear();
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.vcs.CalledInAwt;
|
||||
import com.intellij.openapi.vcs.changes.committed.AbstractCalledLater;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import com.intellij.util.proxy.CommonProxy;
|
||||
@@ -119,6 +120,40 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
});
|
||||
}
|
||||
|
||||
public String getDefaultUsername(String kind, SVNURL url) {
|
||||
String result = SystemProperties.getUserName();
|
||||
|
||||
// USERNAME authentication is also requested in SVNSSHConnector.open()
|
||||
if (ISVNAuthenticationManager.SSH.equals(kind) ||
|
||||
(ISVNAuthenticationManager.USERNAME.equals(kind) && SVN_SSH.equals(url.getProtocol()))) {
|
||||
result = url != null && !StringUtil.isEmpty(url.getUserInfo()) ? url.getUserInfo() : getDefaultOptions().getDefaultSSHUserName();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SVNSSHAuthentication getDefaultSSHAuthentication(SVNURL url) {
|
||||
String userName = getDefaultUsername(ISVNAuthenticationManager.SSH, url);
|
||||
|
||||
// This is fully copied from base class - DefaultSVNAuthenticationManager - as there are no setters in Authentication classes
|
||||
// and there is no url parameter if overriding getDefaultOptions()
|
||||
String password = getDefaultOptions().getDefaultSSHPassword();
|
||||
String keyFile = getDefaultOptions().getDefaultSSHKeyFile();
|
||||
int port = getDefaultOptions().getDefaultSSHPortNumber();
|
||||
String passphrase = getDefaultOptions().getDefaultSSHPassphrase();
|
||||
|
||||
if (userName != null && password != null) {
|
||||
return new SVNSSHAuthentication(userName, password, port, getHostOptionsProvider().getHostOptions(url).isAuthStorageEnabled(), url,
|
||||
false);
|
||||
}
|
||||
else if (userName != null && keyFile != null) {
|
||||
return new SVNSSHAuthentication(userName, new File(keyFile), passphrase, port,
|
||||
getHostOptionsProvider().getHostOptions(url).isAuthStorageEnabled(), url, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class AuthenticationProviderProxy implements ISVNAuthenticationProvider {
|
||||
private final ISVNAuthenticationProvider myDelegate;
|
||||
|
||||
@@ -674,7 +709,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
return DEFAULT_READ_TIMEOUT;
|
||||
}
|
||||
if (SVN_SSH.equals(protocol)) {
|
||||
return (int) getConfig().mySSHReadTimeout;
|
||||
return (int)getConfig().getSshReadTimeout();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -683,7 +718,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
public int getConnectTimeout(SVNRepository repository) {
|
||||
String protocol = repository.getLocation().getProtocol();
|
||||
if (SVN_SSH.equals(protocol)) {
|
||||
return (int) getConfig().mySSHConnectionTimeout;
|
||||
return (int)getConfig().getSshConnectionTimeout();
|
||||
}
|
||||
final int connectTimeout = super.getConnectTimeout(repository);
|
||||
if ((HTTP.equals(protocol) || HTTPS.equals(protocol)) && (connectTimeout <= 0)) {
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.NamedRunnable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.impl.GenericNotifierImpl;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
@@ -45,12 +49,15 @@ import org.tmatesoft.svn.core.SVNAuthenticationException;
|
||||
import org.tmatesoft.svn.core.SVNCancelException;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
@@ -59,6 +66,9 @@ import java.util.Timer;
|
||||
public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthenticationNotifier.AuthenticationRequest, SVNURL> {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnAuthenticationNotifier");
|
||||
|
||||
private static final List<String> ourAuthKinds = Arrays.asList(ISVNAuthenticationManager.PASSWORD, ISVNAuthenticationManager.SSH,
|
||||
ISVNAuthenticationManager.SSL, ISVNAuthenticationManager.USERNAME, "svn.ssl.server", "svn.ssh.server");
|
||||
|
||||
private final SvnVcs myVcs;
|
||||
private final RootsToWorkingCopies myRootsToWorkingCopies;
|
||||
private final Map<SVNURL, Boolean> myCopiesPassiveResults;
|
||||
@@ -414,7 +424,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache")) {
|
||||
@Override
|
||||
public void run() {
|
||||
SvnConfigurable.clearAuthenticationCache(project, null, configuration
|
||||
clearAuthenticationCache(project, null, configuration
|
||||
.getConfigurationDirectory());
|
||||
}
|
||||
},
|
||||
@@ -436,4 +446,58 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
}
|
||||
}, ModalityState.NON_MODAL, project.getDisposed());
|
||||
}
|
||||
|
||||
public static void clearAuthenticationCache(@NotNull final Project project, final Component component, final String configDirPath) {
|
||||
if (configDirPath != null) {
|
||||
int result;
|
||||
if (component == null) {
|
||||
result = Messages.showYesNoDialog(project, SvnBundle.message("confirmation.text.delete.stored.authentication.information"),
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache"),
|
||||
Messages.getWarningIcon());
|
||||
} else {
|
||||
result = Messages.showYesNoDialog(component, SvnBundle.message("confirmation.text.delete.stored.authentication.information"),
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache"),
|
||||
Messages.getWarningIcon());
|
||||
}
|
||||
if (result == Messages.YES) {
|
||||
SvnConfiguration.RUNTIME_AUTH_CACHE.clear();
|
||||
clearAuthenticationDirectory(SvnConfiguration.getInstance(project));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearAuthenticationDirectory(@NotNull SvnConfiguration configuration) {
|
||||
final File authDir = new File(configuration.getConfigurationDirectory(), "auth");
|
||||
if (authDir.exists()) {
|
||||
final Runnable process = new Runnable() {
|
||||
public void run() {
|
||||
final ProgressIndicator ind = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (ind != null) {
|
||||
ind.setIndeterminate(true);
|
||||
ind.setText("Clearing stored credentials in " + authDir.getAbsolutePath());
|
||||
}
|
||||
final File[] files = authDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return ourAuthKinds.contains(name);
|
||||
}
|
||||
});
|
||||
|
||||
for (File dir : files) {
|
||||
if (ind != null) {
|
||||
ind.setText("Deleting " + dir.getAbsolutePath());
|
||||
}
|
||||
FileUtil.delete(dir);
|
||||
}
|
||||
}
|
||||
};
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (application.isUnitTestMode() || !application.isDispatchThread()) {
|
||||
process.run();
|
||||
}
|
||||
else {
|
||||
ProgressManager.getInstance()
|
||||
.runProcessWithProgressSynchronously(process, "button.text.clear.authentication.cache", false, configuration.getProject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
return result;
|
||||
}
|
||||
|
||||
private String serializeUrl(final String url, final Ref<Boolean> withUserInfo) {
|
||||
private static String serializeUrl(final String url, final Ref<Boolean> withUserInfo) {
|
||||
if (Boolean.FALSE.equals(withUserInfo.get())) {
|
||||
return url;
|
||||
}
|
||||
@@ -306,7 +306,8 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
withUserInfo.set((userInfo != null) && (userInfo.length() > 0));
|
||||
}
|
||||
if (withUserInfo.get()) {
|
||||
return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), svnurl.getPort(), svnurl.getURIEncodedPath(), true).toString();
|
||||
return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(), true)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
@@ -321,10 +322,11 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
|
||||
return svnurl != null ? svnurl.getUserInfo() : null;
|
||||
}
|
||||
|
||||
private String deserializeUrl(final String url, final String userInfo) {
|
||||
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(), svnurl.getPort(), svnurl.getURIEncodedPath(), true).toString();
|
||||
return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), SvnUtil.resolvePort(svnurl), svnurl.getURIEncodedPath(),
|
||||
true).toString();
|
||||
} catch (SVNException e) {
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
@@ -102,7 +101,7 @@ public class SvnConfigurable implements Configurable {
|
||||
|
||||
myClearAuthButton.addActionListener(new ActionListener(){
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
clearAuthenticationCache(myProject, myComponent, myConfigurationDirectoryText.getText());
|
||||
SvnAuthenticationNotifier.clearAuthenticationCache(myProject, myComponent, myConfigurationDirectoryText.getText());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -180,25 +179,6 @@ public class SvnConfigurable implements Configurable {
|
||||
dirConsumer.consume(resultPath);
|
||||
}
|
||||
|
||||
public static void clearAuthenticationCache(@NotNull final Project project, final Component component, final String configDirPath) {
|
||||
if (configDirPath != null) {
|
||||
int result;
|
||||
if (component == null) {
|
||||
result = Messages.showYesNoDialog(project, SvnBundle.message("confirmation.text.delete.stored.authentication.information"),
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache"),
|
||||
Messages.getWarningIcon());
|
||||
} else {
|
||||
result = Messages.showYesNoDialog(component, SvnBundle.message("confirmation.text.delete.stored.authentication.information"),
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache"),
|
||||
Messages.getWarningIcon());
|
||||
}
|
||||
if (result == Messages.YES) {
|
||||
SvnConfiguration.RUNTIME_AUTH_CACHE.clear();
|
||||
SvnConfiguration.getInstance(project).clearAuthenticationDirectory(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static FileChooserDescriptor createFileDescriptor() {
|
||||
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
|
||||
descriptor.setShowFileSystemRoots(true);
|
||||
@@ -239,19 +219,19 @@ public class SvnConfigurable implements Configurable {
|
||||
if (configuration.isIsUseDefaultProxy() != myUseCommonProxy.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.UPDATE_LOCK_ON_DEMAND != myLockOnDemand.isSelected()) {
|
||||
if (configuration.isUpdateLockOnDemand() != myLockOnDemand.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.CHECK_NESTED_FOR_QUICK_MERGE != myCheckNestedInQuickMerge.isSelected()) {
|
||||
if (configuration.isCheckNestedForQuickMerge() != myCheckNestedInQuickMerge.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.IGNORE_SPACES_IN_ANNOTATE != myIgnoreWhitespaceDifferenciesInCheckBox.isSelected()) {
|
||||
if (configuration.isIgnoreSpacesInAnnotate() != myIgnoreWhitespaceDifferenciesInCheckBox.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE != myShowMergeSourceInAnnotate.isSelected()) {
|
||||
if (configuration.isShowMergeSourcesInAnnotate() != myShowMergeSourceInAnnotate.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
if (! configuration.myUseAcceleration.equals(acceleration())) return true;
|
||||
if (! configuration.getUseAcceleration().equals(acceleration())) return true;
|
||||
final int annotateRevisions = configuration.getMaxAnnotateRevisions();
|
||||
final boolean useMaxInAnnot = annotateRevisions != -1;
|
||||
if (useMaxInAnnot != myMaximumNumberOfRevisionsCheckBox.isSelected()) {
|
||||
@@ -262,16 +242,16 @@ public class SvnConfigurable implements Configurable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (configuration.mySSHConnectionTimeout/1000 != ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue()) {
|
||||
if (configuration.getSshConnectionTimeout() /1000 != ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.mySSHReadTimeout/1000 != ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue()) {
|
||||
if (configuration.getSshReadTimeout() /1000 != ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue()) {
|
||||
return true;
|
||||
}
|
||||
if (configuration.getHttpTimeout()/1000 != ((SpinnerNumberModel) myHttpTimeout.getModel()).getNumber().longValue()) {
|
||||
return true;
|
||||
}
|
||||
if (! getSelectedSSL().equals(configuration.SSL_PROTOCOLS)) return true;
|
||||
if (! getSelectedSSL().equals(configuration.getSslProtocols())) return true;
|
||||
final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance();
|
||||
if (! Comparing.equal(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim())) return true;
|
||||
return !configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim());
|
||||
@@ -288,23 +268,23 @@ public class SvnConfigurable implements Configurable {
|
||||
|
||||
configuration.setIsUseDefaultProxy(myUseCommonProxy.isSelected());
|
||||
final SvnVcs vcs17 = SvnVcs.getInstance(myProject);
|
||||
configuration.CHECK_NESTED_FOR_QUICK_MERGE = myCheckNestedInQuickMerge.isSelected();
|
||||
configuration.UPDATE_LOCK_ON_DEMAND = myLockOnDemand.isSelected();
|
||||
configuration.setCheckNestedForQuickMerge(myCheckNestedInQuickMerge.isSelected());
|
||||
configuration.setUpdateLockOnDemand(myLockOnDemand.isSelected());
|
||||
configuration.setIgnoreSpacesInAnnotate(myIgnoreWhitespaceDifferenciesInCheckBox.isSelected());
|
||||
configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE = myShowMergeSourceInAnnotate.isSelected();
|
||||
configuration.setShowMergeSourcesInAnnotate(myShowMergeSourceInAnnotate.isSelected());
|
||||
if (! myMaximumNumberOfRevisionsCheckBox.isSelected()) {
|
||||
configuration.setMaxAnnotateRevisions(-1);
|
||||
} else {
|
||||
configuration.setMaxAnnotateRevisions(((SpinnerNumberModel) myNumRevsInAnnotations.getModel()).getNumber().intValue());
|
||||
}
|
||||
configuration.mySSHConnectionTimeout = ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000;
|
||||
configuration.mySSHReadTimeout = ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue() * 1000;
|
||||
configuration.setSshConnectionTimeout(((SpinnerNumberModel)mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000);
|
||||
configuration.setSshReadTimeout(((SpinnerNumberModel)mySSHReadTimeout.getModel()).getNumber().longValue() * 1000);
|
||||
|
||||
final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance();
|
||||
boolean reloadWorkingCopies = !acceleration().equals(configuration.myUseAcceleration) ||
|
||||
boolean reloadWorkingCopies = !acceleration().equals(configuration.getUseAcceleration()) ||
|
||||
!StringUtil.equals(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim());
|
||||
configuration.myUseAcceleration = acceleration();
|
||||
configuration.SSL_PROTOCOLS = getSelectedSSL();
|
||||
configuration.setUseAcceleration(acceleration());
|
||||
configuration.setSslProtocols(getSelectedSSL());
|
||||
SvnVcs.getInstance(myProject).refreshSSLProperty();
|
||||
|
||||
applicationSettings17.setCommandLinePath(myCommandLineClient.getText().trim());
|
||||
@@ -325,15 +305,15 @@ public class SvnConfigurable implements Configurable {
|
||||
myConfigurationDirectoryText.setText(path);
|
||||
myUseDefaultCheckBox.setSelected(configuration.isUseDefaultConfiguation());
|
||||
myUseCommonProxy.setSelected(configuration.isIsUseDefaultProxy());
|
||||
myCheckNestedInQuickMerge.setSelected(configuration.CHECK_NESTED_FOR_QUICK_MERGE);
|
||||
myCheckNestedInQuickMerge.setSelected(configuration.isCheckNestedForQuickMerge());
|
||||
|
||||
boolean enabled = !myUseDefaultCheckBox.isSelected();
|
||||
myConfigurationDirectoryText.setEnabled(enabled);
|
||||
myConfigurationDirectoryText.setEditable(enabled);
|
||||
myConfigurationDirectoryLabel.setEnabled(enabled);
|
||||
myLockOnDemand.setSelected(configuration.UPDATE_LOCK_ON_DEMAND);
|
||||
myIgnoreWhitespaceDifferenciesInCheckBox.setSelected(configuration.IGNORE_SPACES_IN_ANNOTATE);
|
||||
myShowMergeSourceInAnnotate.setSelected(configuration.SHOW_MERGE_SOURCES_IN_ANNOTATE);
|
||||
myLockOnDemand.setSelected(configuration.isUpdateLockOnDemand());
|
||||
myIgnoreWhitespaceDifferenciesInCheckBox.setSelected(configuration.isIgnoreSpacesInAnnotate());
|
||||
myShowMergeSourceInAnnotate.setSelected(configuration.isShowMergeSourcesInAnnotate());
|
||||
|
||||
final int annotateRevisions = configuration.getMaxAnnotateRevisions();
|
||||
if (annotateRevisions == -1) {
|
||||
@@ -344,16 +324,16 @@ public class SvnConfigurable implements Configurable {
|
||||
myNumRevsInAnnotations.setValue(annotateRevisions);
|
||||
}
|
||||
myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected());
|
||||
mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000));
|
||||
mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000));
|
||||
mySSHConnectionTimeout.setValue(Long.valueOf(configuration.getSshConnectionTimeout() / 1000));
|
||||
mySSHReadTimeout.setValue(Long.valueOf(configuration.getSshReadTimeout() / 1000));
|
||||
myHttpTimeout.setValue(Long.valueOf(configuration.getHttpTimeout() / 1000));
|
||||
myWithCommandLineClient.setSelected(configuration.isCommandLine());
|
||||
final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance();
|
||||
myCommandLineClient.setText(applicationSettings17.getCommandLinePath());
|
||||
|
||||
if (SvnConfiguration.SSLProtocols.sslv3.equals(configuration.SSL_PROTOCOLS)) {
|
||||
if (SvnConfiguration.SSLProtocols.sslv3.equals(configuration.getSslProtocols())) {
|
||||
mySSLv3RadioButton.setSelected(true);
|
||||
} else if (SvnConfiguration.SSLProtocols.tlsv1.equals(configuration.SSL_PROTOCOLS)) {
|
||||
} else if (SvnConfiguration.SSLProtocols.tlsv1.equals(configuration.getSslProtocols())) {
|
||||
myTLSv1RadioButton.setSelected(true);
|
||||
} else {
|
||||
myAllRadioButton.setSelected(true);
|
||||
@@ -381,8 +361,8 @@ public class SvnConfigurable implements Configurable {
|
||||
myNumRevsInAnnotations = new JSpinner(new SpinnerNumberModel(value, 10, 100000, 100));
|
||||
|
||||
final Long maximum = 30 * 60 * 1000L;
|
||||
final long connection = configuration.mySSHConnectionTimeout <= maximum ? configuration.mySSHConnectionTimeout : maximum;
|
||||
final long read = configuration.mySSHReadTimeout <= maximum ? configuration.mySSHReadTimeout : maximum;
|
||||
final long connection = configuration.getSshConnectionTimeout() <= maximum ? configuration.getSshConnectionTimeout() : maximum;
|
||||
final long read = configuration.getSshReadTimeout() <= maximum ? configuration.getSshReadTimeout() : maximum;
|
||||
mySSHConnectionTimeout = new JSpinner(new SpinnerNumberModel(Long.valueOf(connection / 1000), Long.valueOf(0L), maximum, Long.valueOf(10L)));
|
||||
mySSHReadTimeout = new JSpinner(new SpinnerNumberModel(Long.valueOf(read / 1000), Long.valueOf(0L), maximum, Long.valueOf(10L)));
|
||||
myHttpTimeout = new JSpinner(new SpinnerNumberModel(Long.valueOf(read / 1000), Long.valueOf(0L), maximum, Long.valueOf(10L)));
|
||||
|
||||
@@ -18,23 +18,14 @@
|
||||
package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.changes.VcsAnnotationRefresher;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.DataConversionException;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.config.ProxyGroup;
|
||||
import org.jetbrains.idea.svn.config.SvnServerFileKeys;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnAuthenticationProvider;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider;
|
||||
@@ -43,7 +34,6 @@ import org.jetbrains.idea.svn.update.UpdateRootInfo;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
import org.tmatesoft.svn.core.internal.wc.ISVNAuthenticationStorage;
|
||||
@@ -54,10 +44,6 @@ import org.tmatesoft.svn.core.wc.SVNDiffOptions;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.util.*;
|
||||
|
||||
@State(
|
||||
@@ -73,26 +59,18 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.SvnConfiguration");
|
||||
public final static int ourMaxAnnotateRevisionsDefault = 500;
|
||||
|
||||
private final static String SERVERS_FILE_NAME = "servers";
|
||||
|
||||
public static final String CLEANUP_ON_START_RUN = "cleanupOnStartRun";
|
||||
private final Project myProject;
|
||||
|
||||
public String USER = "";
|
||||
public String PASSWORD = "";
|
||||
public String[] ADD_PATHS = null;
|
||||
|
||||
private String myConfigurationDirectory;
|
||||
private boolean myIsUseDefaultConfiguration;
|
||||
private boolean myIsUseDefaultProxy;
|
||||
private ISVNOptions myOptions;
|
||||
private boolean myIsKeepLocks;
|
||||
private boolean myAutoUpdateAfterCommit;
|
||||
private boolean myRemoteStatus;
|
||||
private SvnAuthenticationManager myAuthManager;
|
||||
private SvnAuthenticationManager myPassiveAuthManager;
|
||||
private SvnAuthenticationManager myInteractiveManager;
|
||||
private String myUpgradeMode;
|
||||
private SvnSupportOptions mySupportOptions;
|
||||
private boolean myCleanupRun;
|
||||
private int myMaxAnnotateRevisions = ourMaxAnnotateRevisionsDefault;
|
||||
@@ -101,14 +79,14 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
public long mySSHReadTimeout = DEFAULT_SSH_TIMEOUT;
|
||||
|
||||
public static final AuthStorage RUNTIME_AUTH_CACHE = new AuthStorage();
|
||||
public String LAST_MERGED_REVISION = null;
|
||||
// TODO: update depth is not stored in configuration as SVNDepth has wrong type for DefaultJDOMExternalizer
|
||||
// TODO: check if it should be stored
|
||||
public SVNDepth UPDATE_DEPTH = SVNDepth.UNKNOWN;
|
||||
|
||||
public boolean MERGE_DRY_RUN = false;
|
||||
public boolean MERGE_DIFF_USE_ANCESTRY = true;
|
||||
public boolean UPDATE_LOCK_ON_DEMAND = false;
|
||||
public boolean IGNORE_SPACES_IN_MERGE = false;
|
||||
//public boolean DETECT_NESTED_COPIES = true;
|
||||
public boolean CHECK_NESTED_FOR_QUICK_MERGE = false;
|
||||
public boolean IGNORE_SPACES_IN_ANNOTATE = true;
|
||||
public boolean SHOW_MERGE_SOURCES_IN_ANNOTATE = true;
|
||||
@@ -126,7 +104,7 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
private IdeaSVNConfigFile myConfigFile;
|
||||
|
||||
public boolean isCommandLine() {
|
||||
return UseAcceleration.commandLine.equals(myUseAcceleration);
|
||||
return UseAcceleration.commandLine.equals(getUseAcceleration());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,12 +140,12 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
}
|
||||
|
||||
public SVNDiffOptions getMergeOptions() {
|
||||
return new SVNDiffOptions(IGNORE_SPACES_IN_MERGE, IGNORE_SPACES_IN_MERGE, IGNORE_SPACES_IN_MERGE);
|
||||
return new SVNDiffOptions(isIgnoreSpacesInMerge(), isIgnoreSpacesInMerge(), isIgnoreSpacesInMerge());
|
||||
}
|
||||
|
||||
private void initServers() {
|
||||
if (myConfigFile == null) {
|
||||
myConfigFile = new IdeaSVNConfigFile(new File(getConfigurationDirectory(), SERVERS_FILE_NAME));
|
||||
myConfigFile = new IdeaSVNConfigFile(new File(getConfigurationDirectory(), IdeaSVNConfigFile.SERVERS_FILE_NAME));
|
||||
}
|
||||
myConfigFile.updateGroups();
|
||||
}
|
||||
@@ -180,59 +158,6 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
myConfigFile.save();
|
||||
}
|
||||
|
||||
public static void putProxyIntoServersFile(final File configDir, final String host, final Proxy proxyInfo) {
|
||||
final IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(new File(configDir, SERVERS_FILE_NAME));
|
||||
configFile.updateGroups();
|
||||
|
||||
String groupName = ensureHostGroup(host, configFile);
|
||||
|
||||
final HashMap<String, String> map = new HashMap<String, String>();
|
||||
final InetSocketAddress address = ((InetSocketAddress) proxyInfo.address());
|
||||
map.put(SvnAuthenticationManager.HTTP_PROXY_HOST, address.getHostName());
|
||||
map.put(SvnAuthenticationManager.HTTP_PROXY_PORT, String.valueOf(address.getPort()));
|
||||
configFile.addGroup(groupName, host + "*", map);
|
||||
configFile.save();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String ensureHostGroup(@NotNull String host, @NotNull IdeaSVNConfigFile configFile) {
|
||||
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
|
||||
|
||||
if (StringUtil.isEmptyOrSpaces(groupName)) {
|
||||
groupName = getNewGroupName(host, configFile);
|
||||
}
|
||||
|
||||
return groupName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNewGroupName(@NotNull String host, @NotNull IdeaSVNConfigFile configFile) {
|
||||
String groupName = host;
|
||||
final Map<String,ProxyGroup> groups = configFile.getAllGroups();
|
||||
while (StringUtil.isEmptyOrSpaces(groupName) || groups.containsKey(groupName)) {
|
||||
groupName += "1";
|
||||
}
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public static boolean putProxyCredentialsIntoServerFile(@NotNull final File configDir, @NotNull final String host,
|
||||
@NotNull final PasswordAuthentication authentication) {
|
||||
final IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(new File(configDir, SERVERS_FILE_NAME));
|
||||
configFile.updateGroups();
|
||||
|
||||
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
|
||||
// no proxy defined in group -> no sense in password
|
||||
if (StringUtil.isEmptyOrSpaces(groupName)) return false;
|
||||
final Map<String, String> properties = configFile.getAllGroups().get(groupName).getProperties();
|
||||
if (StringUtil.isEmptyOrSpaces(properties.get(SvnAuthenticationManager.HTTP_PROXY_HOST))) return false;
|
||||
if (StringUtil.isEmptyOrSpaces(properties.get(SvnAuthenticationManager.HTTP_PROXY_PORT))) return false;
|
||||
|
||||
configFile.setValue(groupName, SvnAuthenticationManager.HTTP_PROXY_USERNAME, authentication.getUserName());
|
||||
configFile.setValue(groupName, SvnAuthenticationManager.HTTP_PROXY_PASSWORD, String.valueOf(authentication.getPassword()));
|
||||
configFile.save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SvnConfiguration getInstance(final Project project) {
|
||||
return ServiceManager.getService(project, SvnConfiguration.class);
|
||||
}
|
||||
@@ -245,10 +170,130 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
final boolean changed = IGNORE_SPACES_IN_ANNOTATE != value;
|
||||
IGNORE_SPACES_IN_ANNOTATE = value;
|
||||
if (changed) {
|
||||
myProject.getMessageBus().syncPublisher(VcsAnnotationRefresher.LOCAL_CHANGES_CHANGED).configurationChanged(SvnVcs.getKey());
|
||||
getProject().getMessageBus().syncPublisher(VcsAnnotationRefresher.LOCAL_CHANGES_CHANGED).configurationChanged(SvnVcs.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
public long getSshConnectionTimeout() {
|
||||
return mySSHConnectionTimeout;
|
||||
}
|
||||
|
||||
public void setSshConnectionTimeout(long sshConnectionTimeout) {
|
||||
mySSHConnectionTimeout = sshConnectionTimeout;
|
||||
}
|
||||
|
||||
public long getSshReadTimeout() {
|
||||
return mySSHReadTimeout;
|
||||
}
|
||||
|
||||
public void setSshReadTimeout(long sshReadTimeout) {
|
||||
mySSHReadTimeout = sshReadTimeout;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
public Boolean isKeepNewFilesAsIsForTreeConflictMerge() {
|
||||
return TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE;
|
||||
}
|
||||
|
||||
public void setKeepNewFilesAsIsForTreeConflictMerge(Boolean keepNewFilesAsIsForTreeConflictMerge) {
|
||||
this.TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE = keepNewFilesAsIsForTreeConflictMerge;
|
||||
}
|
||||
|
||||
public SSLProtocols getSslProtocols() {
|
||||
return SSL_PROTOCOLS;
|
||||
}
|
||||
|
||||
public void setSslProtocols(SSLProtocols sslProtocols) {
|
||||
this.SSL_PROTOCOLS = sslProtocols;
|
||||
}
|
||||
|
||||
public SVNDepth getUpdateDepth() {
|
||||
return UPDATE_DEPTH;
|
||||
}
|
||||
|
||||
public void setUpdateDepth(SVNDepth updateDepth) {
|
||||
this.UPDATE_DEPTH = updateDepth;
|
||||
}
|
||||
|
||||
public UseAcceleration getUseAcceleration() {
|
||||
return myUseAcceleration;
|
||||
}
|
||||
|
||||
public void setUseAcceleration(UseAcceleration useAcceleration) {
|
||||
myUseAcceleration = useAcceleration;
|
||||
}
|
||||
|
||||
public boolean isIgnoreExternals() {
|
||||
return IGNORE_EXTERNALS;
|
||||
}
|
||||
|
||||
public void setIgnoreExternals(boolean ignoreExternals) {
|
||||
this.IGNORE_EXTERNALS = ignoreExternals;
|
||||
}
|
||||
|
||||
public boolean isMergeDryRun() {
|
||||
return MERGE_DRY_RUN;
|
||||
}
|
||||
|
||||
public void setMergeDryRun(boolean mergeDryRun) {
|
||||
this.MERGE_DRY_RUN = mergeDryRun;
|
||||
}
|
||||
|
||||
public boolean isMergeDiffUseAncestry() {
|
||||
return MERGE_DIFF_USE_ANCESTRY;
|
||||
}
|
||||
|
||||
public void setMergeDiffUseAncestry(boolean mergeDiffUseAncestry) {
|
||||
this.MERGE_DIFF_USE_ANCESTRY = mergeDiffUseAncestry;
|
||||
}
|
||||
|
||||
public boolean isUpdateLockOnDemand() {
|
||||
return UPDATE_LOCK_ON_DEMAND;
|
||||
}
|
||||
|
||||
public void setUpdateLockOnDemand(boolean updateLockOnDemand) {
|
||||
this.UPDATE_LOCK_ON_DEMAND = updateLockOnDemand;
|
||||
}
|
||||
|
||||
public boolean isIgnoreSpacesInMerge() {
|
||||
return IGNORE_SPACES_IN_MERGE;
|
||||
}
|
||||
|
||||
public void setIgnoreSpacesInMerge(boolean ignoreSpacesInMerge) {
|
||||
this.IGNORE_SPACES_IN_MERGE = ignoreSpacesInMerge;
|
||||
}
|
||||
|
||||
public boolean isCheckNestedForQuickMerge() {
|
||||
return CHECK_NESTED_FOR_QUICK_MERGE;
|
||||
}
|
||||
|
||||
public void setCheckNestedForQuickMerge(boolean checkNestedForQuickMerge) {
|
||||
this.CHECK_NESTED_FOR_QUICK_MERGE = checkNestedForQuickMerge;
|
||||
}
|
||||
|
||||
public boolean isIgnoreSpacesInAnnotate() {
|
||||
return IGNORE_SPACES_IN_ANNOTATE;
|
||||
}
|
||||
|
||||
public boolean isShowMergeSourcesInAnnotate() {
|
||||
return SHOW_MERGE_SOURCES_IN_ANNOTATE;
|
||||
}
|
||||
|
||||
public void setShowMergeSourcesInAnnotate(boolean showMergeSourcesInAnnotate) {
|
||||
this.SHOW_MERGE_SOURCES_IN_ANNOTATE = showMergeSourcesInAnnotate;
|
||||
}
|
||||
|
||||
public boolean isForceUpdate() {
|
||||
return FORCE_UPDATE;
|
||||
}
|
||||
|
||||
public void setForceUpdate(boolean forceUpdate) {
|
||||
this.FORCE_UPDATE = forceUpdate;
|
||||
}
|
||||
|
||||
public class SvnSupportOptions {
|
||||
/**
|
||||
* version of "support SVN in IDEA". for features tracking. should grow
|
||||
@@ -267,10 +312,6 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
private final static long CHANGELIST_SUPPORT = 124;
|
||||
private final static long UPGRADE_TO_16_VERSION_ASKED = 125;
|
||||
|
||||
public boolean upgradeTo16Asked() {
|
||||
return (myVersion != null) && (UPGRADE_TO_16_VERSION_ASKED <= myVersion);
|
||||
}
|
||||
|
||||
public boolean changeListsSynchronized() {
|
||||
return (myVersion != null) && (CHANGELIST_SUPPORT <= myVersion);
|
||||
}
|
||||
@@ -347,34 +388,6 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
return myOptions;
|
||||
}
|
||||
|
||||
public static SvnAuthenticationManager createForTmpDir(final Project project, final File dir) {
|
||||
return createForTmpDir(project, dir, null);
|
||||
}
|
||||
|
||||
public static SvnAuthenticationManager createForTmpDir(final Project project, final File dir,
|
||||
@Nullable final SvnInteractiveAuthenticationProvider provider) {
|
||||
final SvnVcs vcs = SvnVcs.getInstance(project);
|
||||
|
||||
final SvnAuthenticationManager interactive = new SvnAuthenticationManager(project, dir);
|
||||
interactive.setRuntimeStorage(RUNTIME_AUTH_CACHE);
|
||||
final SvnInteractiveAuthenticationProvider interactiveProvider = provider == null ?
|
||||
new SvnInteractiveAuthenticationProvider(vcs, interactive) : provider;
|
||||
interactive.setAuthenticationProvider(interactiveProvider);
|
||||
|
||||
return interactive;
|
||||
}
|
||||
|
||||
public SvnAuthenticationManager getManager(final AuthManagerType type, final SvnVcs vcs) {
|
||||
if (AuthManagerType.active.equals(type)) {
|
||||
return getInteractiveManager(vcs);
|
||||
} else if (AuthManagerType.passive.equals(type)) {
|
||||
return getPassiveAuthenticationManager(vcs.getProject());
|
||||
} else if (AuthManagerType.usual.equals(type)) {
|
||||
return getAuthenticationManager(vcs);
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public SvnAuthenticationManager getAuthenticationManager(final SvnVcs svnVcs) {
|
||||
if (myAuthManager == null) {
|
||||
// reloaded when configuration directory changes
|
||||
@@ -434,29 +447,14 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
SVNConfigFile.createDefaultConfiguration(dir);
|
||||
}
|
||||
|
||||
systemManager.set(new SvnServerFileManagerImpl(new IdeaSVNConfigFile(new File(SVNFileUtil.getSystemConfigurationDirectory(), SERVERS_FILE_NAME))));
|
||||
systemManager.set(new SvnServerFileManagerImpl(new IdeaSVNConfigFile(new File(SVNFileUtil.getSystemConfigurationDirectory(), IdeaSVNConfigFile.SERVERS_FILE_NAME))));
|
||||
initServers();
|
||||
userManager.set(new SvnServerFileManagerImpl(myConfigFile));
|
||||
}
|
||||
|
||||
public String getUpgradeMode() {
|
||||
return myUpgradeMode;
|
||||
}
|
||||
|
||||
public void setUpgradeMode(String upgradeMode) {
|
||||
myUpgradeMode = upgradeMode;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
DefaultJDOMExternalizer.readExternal(this, element);
|
||||
List elems = element.getChildren("addpath");
|
||||
LOG.debug(elems.toString());
|
||||
ADD_PATHS = new String[elems.size()];
|
||||
for (int i = 0; i < elems.size(); i++) {
|
||||
Element elem = (Element)elems.get(i);
|
||||
ADD_PATHS[i] = elem.getAttributeValue("path");
|
||||
}
|
||||
Element configurationDirectory = element.getChild("configuration");
|
||||
if (configurationDirectory != null) {
|
||||
myConfigurationDirectory = configurationDirectory.getText();
|
||||
@@ -471,18 +469,7 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
else {
|
||||
myIsUseDefaultConfiguration = true;
|
||||
}
|
||||
// compatibility: this setting was moved from .iws to global settings
|
||||
List urls = element.getChildren("checkoutURL");
|
||||
for (Object url1 : urls) {
|
||||
Element child = (Element)url1;
|
||||
String url = child.getText();
|
||||
if (url != null) {
|
||||
SvnApplicationSettings.getInstance().addCheckoutURL(url);
|
||||
}
|
||||
}
|
||||
myIsKeepLocks = element.getChild("keepLocks") != null;
|
||||
myRemoteStatus = element.getChild("remoteStatus") != null;
|
||||
myUpgradeMode = element.getChild("upgradeMode") != null ? element.getChild("upgradeMode").getText() : null;
|
||||
final Element useProxy = element.getChild("myIsUseDefaultProxy");
|
||||
if (useProxy == null) {
|
||||
myIsUseDefaultProxy = false;
|
||||
@@ -508,7 +495,7 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
final Attribute acceleration = element.getAttribute("myUseAcceleration");
|
||||
if (acceleration != null) {
|
||||
try {
|
||||
myUseAcceleration = UseAcceleration.valueOf(acceleration.getValue());
|
||||
setUseAcceleration(UseAcceleration.valueOf(acceleration.getValue()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
//
|
||||
}
|
||||
@@ -526,26 +513,19 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
final Attribute protocols = element.getAttribute("SSL_PROTOCOLS");
|
||||
if (protocols != null) {
|
||||
try {
|
||||
SSL_PROTOCOLS = SSLProtocols.valueOf(protocols.getValue());
|
||||
setSslProtocols(SSLProtocols.valueOf(protocols.getValue()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
if (treeConflictMergeNewFilesPlace != null) {
|
||||
TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE = Boolean.parseBoolean(treeConflictMergeNewFilesPlace.getValue());
|
||||
setKeepNewFilesAsIsForTreeConflictMerge(Boolean.parseBoolean(treeConflictMergeNewFilesPlace.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
DefaultJDOMExternalizer.writeExternal(this, element);
|
||||
if (ADD_PATHS != null) {
|
||||
for (String aADD_PATHS : ADD_PATHS) {
|
||||
Element elem = new Element("addpath");
|
||||
elem.setAttribute("path", aADD_PATHS);
|
||||
element.addContent(elem);
|
||||
}
|
||||
}
|
||||
if (myConfigurationDirectory != null) {
|
||||
Element configurationDirectory = new Element("configuration");
|
||||
configurationDirectory.setText(myConfigurationDirectory);
|
||||
@@ -555,23 +535,18 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
if (myIsKeepLocks) {
|
||||
element.addContent(new Element("keepLocks"));
|
||||
}
|
||||
if (myRemoteStatus) {
|
||||
element.addContent(new Element("remoteStatus"));
|
||||
}
|
||||
if (myUpgradeMode != null) {
|
||||
element.addContent(new Element("upgradeMode").setText(myUpgradeMode));
|
||||
}
|
||||
element.addContent(new Element("myIsUseDefaultProxy").setText(myIsUseDefaultProxy ? "true" : "false"));
|
||||
if (mySupportOptions != null) {
|
||||
element.addContent(new Element("supportedVersion").setText("" + mySupportOptions.myVersion));
|
||||
element.addContent(new Element("supportedVersion").setText(String.valueOf(mySupportOptions.myVersion)));
|
||||
}
|
||||
element.setAttribute("maxAnnotateRevisions", "" + myMaxAnnotateRevisions);
|
||||
element.setAttribute("myUseAcceleration", "" + myUseAcceleration);
|
||||
element.setAttribute("myAutoUpdateAfterCommit", "" + myAutoUpdateAfterCommit);
|
||||
element.setAttribute(CLEANUP_ON_START_RUN, "" + myCleanupRun);
|
||||
element.setAttribute("SSL_PROTOCOLS", SSL_PROTOCOLS.name());
|
||||
if (TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE != null) {
|
||||
element.setAttribute("TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE", "" + TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE);
|
||||
element.setAttribute("maxAnnotateRevisions", String.valueOf(myMaxAnnotateRevisions));
|
||||
element.setAttribute("myUseAcceleration", String.valueOf(getUseAcceleration()));
|
||||
element.setAttribute("myAutoUpdateAfterCommit", String.valueOf(myAutoUpdateAfterCommit));
|
||||
element.setAttribute(CLEANUP_ON_START_RUN, String.valueOf(myCleanupRun));
|
||||
element.setAttribute("SSL_PROTOCOLS", getSslProtocols().name());
|
||||
if (isKeepNewFilesAsIsForTreeConflictMerge() != null) {
|
||||
element.setAttribute("TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE", String.valueOf(
|
||||
isKeepNewFilesAsIsForTreeConflictMerge()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,14 +566,6 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
myIsKeepLocks = keepLocks;
|
||||
}
|
||||
|
||||
public boolean isRemoteStatus() {
|
||||
return myRemoteStatus;
|
||||
}
|
||||
|
||||
public void setRemoteStatus(boolean remote) {
|
||||
myRemoteStatus = remote;
|
||||
}
|
||||
|
||||
public boolean isIsUseDefaultProxy() {
|
||||
return myIsUseDefaultProxy;
|
||||
}
|
||||
@@ -643,50 +610,11 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
return myUpdateRootInfos.get(file);
|
||||
}
|
||||
|
||||
// TODO: Check why SvnUpdateEnvironment.validationOptions is fully commented and then remove this method if necessary
|
||||
public Map<File, UpdateRootInfo> getUpdateInfosMap() {
|
||||
return Collections.unmodifiableMap(myUpdateRootInfos);
|
||||
}
|
||||
|
||||
private static final List<String> ourAuthKinds = Arrays.asList(ISVNAuthenticationManager.PASSWORD, ISVNAuthenticationManager.SSH,
|
||||
ISVNAuthenticationManager.SSL, ISVNAuthenticationManager.USERNAME, "svn.ssl.server", "svn.ssh.server");
|
||||
|
||||
public void clearAuthenticationDirectory(@Nullable Project project) {
|
||||
final File authDir = new File(getConfigurationDirectory(), "auth");
|
||||
if (authDir.exists()) {
|
||||
final Runnable process = new Runnable() {
|
||||
public void run() {
|
||||
final ProgressIndicator ind = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (ind != null) {
|
||||
ind.setIndeterminate(true);
|
||||
ind.setText("Clearing stored credentials in " + authDir.getAbsolutePath());
|
||||
}
|
||||
final File[] files = authDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return ourAuthKinds.contains(name);
|
||||
}
|
||||
});
|
||||
|
||||
for (File dir : files) {
|
||||
if (ind != null) {
|
||||
ind.setText("Deleting " + dir.getAbsolutePath());
|
||||
}
|
||||
FileUtil.delete(dir);
|
||||
}
|
||||
}
|
||||
};
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (application.isUnitTestMode() || ! application.isDispatchThread()) {
|
||||
process.run();
|
||||
} else {
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(process, "button.text.clear.authentication.cache", false, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean haveCredentialsFor(final String kind, final String realm) {
|
||||
return RUNTIME_AUTH_CACHE.getData(kind, realm) != null;
|
||||
}
|
||||
|
||||
public void acknowledge(final String kind, final String realm, final Object object) {
|
||||
RUNTIME_AUTH_CACHE.putData(kind, realm, object);
|
||||
}
|
||||
@@ -721,7 +649,7 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
|
||||
myCleanupRun = cleanupRun;
|
||||
}
|
||||
|
||||
public static enum SSLProtocols {
|
||||
public enum SSLProtocols {
|
||||
sslv3, tlsv1, all
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.portable.PortableStatus;
|
||||
import org.tmatesoft.svn.core.wc.SVNStatus;
|
||||
import org.tmatesoft.svn.core.wc.SVNStatusType;
|
||||
|
||||
@@ -24,11 +26,18 @@ public class SvnStatusConvertor {
|
||||
private SvnStatusConvertor() {
|
||||
}
|
||||
|
||||
public static FileStatus convertStatus(final SVNStatus status) throws SVNException {
|
||||
return convertStatus(status, true);
|
||||
@NotNull
|
||||
public static FileStatus convertStatus(@Nullable SVNStatusType itemStatus, @Nullable SVNStatusType propertiesStatus) {
|
||||
PortableStatus status = new PortableStatus();
|
||||
|
||||
status.setContentsStatus(itemStatus);
|
||||
status.setPropertiesStatus(propertiesStatus);
|
||||
|
||||
return convertStatus(status);
|
||||
}
|
||||
|
||||
public static FileStatus convertStatus(final SVNStatus status, final boolean noticeProperties) throws SVNException {
|
||||
@NotNull
|
||||
public static FileStatus convertStatus(@Nullable final SVNStatus status) {
|
||||
if (status == null) {
|
||||
return FileStatus.UNKNOWN;
|
||||
}
|
||||
@@ -57,17 +66,18 @@ public class SvnStatusConvertor {
|
||||
return SvnFileStatus.REPLACED;
|
||||
}
|
||||
else if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED ||
|
||||
noticeProperties && status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED &&
|
||||
noticeProperties && status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
return FileStatus.MERGED_WITH_BOTH_CONFLICTS;
|
||||
} else if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
}
|
||||
else if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED) {
|
||||
return FileStatus.MERGED_WITH_CONFLICTS;
|
||||
}
|
||||
return FileStatus.MERGED_WITH_PROPERTY_CONFLICTS;
|
||||
}
|
||||
else if (status.getContentsStatus() == SVNStatusType.STATUS_MODIFIED ||
|
||||
noticeProperties && status.getPropertiesStatus() == SVNStatusType.STATUS_MODIFIED) {
|
||||
status.getPropertiesStatus() == SVNStatusType.STATUS_MODIFIED) {
|
||||
return FileStatus.MODIFIED;
|
||||
}
|
||||
else if (status.isSwitched()) {
|
||||
@@ -79,15 +89,8 @@ public class SvnStatusConvertor {
|
||||
return FileStatus.NOT_CHANGED;
|
||||
}
|
||||
|
||||
public static FileStatus convertPropertyStatus(final SVNStatusType status) throws SVNException {
|
||||
return convertSingleStatus(status, FileStatus.MERGED_WITH_PROPERTY_CONFLICTS);
|
||||
}
|
||||
|
||||
public static FileStatus convertContentsStatus(final SVNStatus status) throws SVNException {
|
||||
return convertStatus(status, false);
|
||||
}
|
||||
|
||||
private static FileStatus convertSingleStatus(final SVNStatusType status, final FileStatus defaultConflictStatus) throws SVNException {
|
||||
@NotNull
|
||||
public static FileStatus convertPropertyStatus(final SVNStatusType status) {
|
||||
if (status == null) {
|
||||
return FileStatus.UNKNOWN;
|
||||
}
|
||||
@@ -116,7 +119,7 @@ public class SvnStatusConvertor {
|
||||
return SvnFileStatus.REPLACED;
|
||||
}
|
||||
else if (status == SVNStatusType.STATUS_CONFLICTED) {
|
||||
return defaultConflictStatus;
|
||||
return FileStatus.MERGED_WITH_PROPERTY_CONFLICTS;
|
||||
}
|
||||
else if (status == SVNStatusType.STATUS_MODIFIED) {
|
||||
return FileStatus.MODIFIED;
|
||||
|
||||
@@ -73,6 +73,7 @@ public class SvnUtil {
|
||||
@NonNls public static final String WC_DB_FILE_NAME = "wc.db";
|
||||
@NonNls public static final String DIR_PROPS_FILE_NAME = "dir-props";
|
||||
@NonNls public static final String PATH_TO_LOCK_FILE = SVN_ADMIN_DIR_NAME + "/lock";
|
||||
public static final int DEFAULT_PORT_INDICATOR = -1;
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnUtil");
|
||||
|
||||
public static final Pattern ERROR_PATTERN = Pattern.compile("^svn: (E(\\d+)): (.*)$", Pattern.MULTILINE);
|
||||
@@ -738,7 +739,7 @@ public class SvnUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String appendMultiParts(@NotNull final String base, @NotNull final String subPath) throws SVNException {
|
||||
public static String appendMultiParts(@NotNull final String base, @NotNull final String subPath) {
|
||||
if (StringUtil.isEmpty(subPath)) return base;
|
||||
final List<String> parts = StringUtil.split(subPath.replace('\\', '/'), "/", true);
|
||||
String result = base;
|
||||
@@ -768,6 +769,31 @@ public class SvnUtil {
|
||||
return factory.createContentClient().getContent(target, revision, pegRevision);
|
||||
}
|
||||
|
||||
public static boolean hasDefaultPort(@NotNull SVNURL result) {
|
||||
return !result.hasPort() || SVNURL.getDefaultPortNumber(result.getProtocol()) == result.getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* When creating SVNURL with default port, some negative value should be specified as port number, otherwise specified port value (even
|
||||
* if equals to default) will occur in toString() result.
|
||||
*/
|
||||
public static int resolvePort(@NotNull SVNURL url) {
|
||||
return !hasDefaultPort(url) ? url.getPort() : DEFAULT_PORT_INDICATOR;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SVNURL createUrl(@NotNull String url) throws SVNException {
|
||||
SVNURL result = SVNURL.parseURIEncoded(url);
|
||||
|
||||
// explicitly check if port corresponds to default port and recreate url specifying default port indicator
|
||||
if (result.hasPort() && hasDefaultPort(result)) {
|
||||
result = SVNURL
|
||||
.create(result.getProtocol(), result.getUserInfo(), result.getHost(), DEFAULT_PORT_INDICATOR, result.getURIEncodedPath(), true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static SVNURL parseUrl(@NotNull String url) {
|
||||
try {
|
||||
return SVNURL.parseURIEncoded(url);
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.SoftHashMap;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
@@ -979,6 +980,33 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void collectInfo(@NotNull Collection<File> files, @Nullable ISVNInfoHandler handler) {
|
||||
File first = ContainerUtil.getFirstItem(files);
|
||||
|
||||
if (first != null) {
|
||||
ClientFactory factory = getFactory(first);
|
||||
|
||||
try {
|
||||
if (factory instanceof CmdClientFactory) {
|
||||
factory.createInfoClient().doInfo(files, handler);
|
||||
}
|
||||
else {
|
||||
// TODO: Generally this should be moved in SvnKit info client implementation.
|
||||
// TODO: Currently left here to have exception logic as in handleInfoException to be applied for each file separately.
|
||||
for (File file : files) {
|
||||
SVNInfo info = getInfo(file);
|
||||
if (handler != null) {
|
||||
handler.handleInfo(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
handleInfoException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SVNInfo getInfo(@NotNull File ioFile, @NotNull SVNRevision revision) {
|
||||
SVNInfo result = null;
|
||||
@@ -1027,11 +1055,11 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
|
||||
public void refreshSSLProperty() {
|
||||
if (ourSSLProtocolsExplicitlySet) return;
|
||||
if (SvnConfiguration.SSLProtocols.all.equals(myConfiguration.SSL_PROTOCOLS)) {
|
||||
if (SvnConfiguration.SSLProtocols.all.equals(myConfiguration.getSslProtocols())) {
|
||||
System.clearProperty(SVNKIT_HTTP_SSL_PROTOCOLS);
|
||||
} else if (SvnConfiguration.SSLProtocols.sslv3.equals(myConfiguration.SSL_PROTOCOLS)) {
|
||||
} else if (SvnConfiguration.SSLProtocols.sslv3.equals(myConfiguration.getSslProtocols())) {
|
||||
System.setProperty(SVNKIT_HTTP_SSL_PROTOCOLS, "SSLv3");
|
||||
} else if (SvnConfiguration.SSLProtocols.tlsv1.equals(myConfiguration.SSL_PROTOCOLS)) {
|
||||
} else if (SvnConfiguration.SSLProtocols.tlsv1.equals(myConfiguration.getSslProtocols())) {
|
||||
System.setProperty(SVNKIT_HTTP_SSL_PROTOCOLS, "TLSv1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,367 +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.actions;
|
||||
|
||||
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.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffManager;
|
||||
import com.intellij.openapi.diff.FileContent;
|
||||
import com.intellij.openapi.diff.SimpleContent;
|
||||
import com.intellij.openapi.diff.SimpleDiffRequest;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vcs.FileStatusManager;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import org.jetbrains.idea.svn.status.SvnDiffEditor;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNCancellableEditor;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminAreaInfo;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNReporter;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
|
||||
import org.tmatesoft.svn.core.internal.wc17.SVNReporter17;
|
||||
import org.tmatesoft.svn.core.internal.wc17.SVNWCContext;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
import org.tmatesoft.svn.util.SVNDebugLog;
|
||||
import org.tmatesoft.svn.util.SVNLogType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CompareWithBranchAction extends AnAction implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.actions.CompareWithBranchAction");
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
assert project != null;
|
||||
final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
|
||||
|
||||
SelectBranchPopup.show(project, virtualFile, new SelectBranchPopup.BranchSelectedCallback() {
|
||||
public void branchSelected(final Project project, final SvnBranchConfigurationNew configuration, final String url, final long revision) {
|
||||
new CompareWithBranchOperation(project, virtualFile, configuration).compareWithBranch(url, revision);
|
||||
}
|
||||
}, SvnBundle.message("compare.with.branch.popup.title"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
|
||||
e.getPresentation().setEnabled(isEnabled(project, virtualFile));
|
||||
}
|
||||
|
||||
private static boolean isEnabled(final Project project, final VirtualFile virtualFile) {
|
||||
if (project == null || virtualFile == null) {
|
||||
return false;
|
||||
}
|
||||
final FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(virtualFile);
|
||||
if (fileStatus == FileStatus.UNKNOWN || fileStatus == FileStatus.ADDED || fileStatus == FileStatus.IGNORED) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private class CompareWithBranchOperation {
|
||||
private final Project myProject;
|
||||
private final VirtualFile myVirtualFile;
|
||||
private final SvnBranchConfigurationNew myConfiguration;
|
||||
|
||||
public CompareWithBranchOperation(final Project project, final VirtualFile virtualFile, final SvnBranchConfigurationNew config) {
|
||||
myProject = project;
|
||||
myVirtualFile = virtualFile;
|
||||
myConfiguration = config;
|
||||
}
|
||||
|
||||
public void compareWithBranch(final String baseUrl, final long revision) {
|
||||
if (myVirtualFile.isDirectory()) {
|
||||
compareDirectoryWithBranch(baseUrl, revision);
|
||||
}
|
||||
else {
|
||||
compareFileWithBranch(baseUrl, revision);
|
||||
}
|
||||
}
|
||||
final StringBuilder titleBuilder = new StringBuilder();
|
||||
|
||||
public void compareDirectoryWithBranch(final String baseUrl, final long revision) {
|
||||
final List<Change> changes = new ArrayList<Change>();
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final SvnVcs vcs = SvnVcs.getInstance(myProject);
|
||||
final SVNURL url = getURLInBranch(vcs, baseUrl);
|
||||
if (url == null) return; // todo diagnostics
|
||||
titleBuilder.append(SvnBundle.message("repository.browser.compare.title",
|
||||
url.toString(),
|
||||
FileUtil.toSystemDependentName(myVirtualFile.getPresentableUrl())));
|
||||
|
||||
final File ioFile = new File(myVirtualFile.getPath());
|
||||
if (SvnUtil.is17CopyPart(ioFile)) {
|
||||
report17DirDiff(vcs, url);
|
||||
} else {
|
||||
report16DirDiff(vcs, url);
|
||||
}
|
||||
|
||||
/* final SVNInfo info1 = vcs.createWCClient().doInfo(new File(myVirtualFile.getPath()), SVNRevision.HEAD);
|
||||
if (info1 == null) return;
|
||||
|
||||
if (info1 == null) {
|
||||
SVNErrorMessage err =
|
||||
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
else if (info1.getURL() == null) {
|
||||
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
*/
|
||||
|
||||
// todo
|
||||
|
||||
|
||||
/*final SVNDiffClient diffClient = vcs.createDiffClient();
|
||||
diffClient.doDiffStatus(info1.getURL(), info1.getRevision(), url, info1.getRevision(), SVNDepth.INFINITY, false,
|
||||
new ISVNDiffStatusHandler() {
|
||||
@Override
|
||||
public void handleDiffStatus(SVNDiffStatus diffStatus) throws SVNException {
|
||||
diffStatus.getModificationType()
|
||||
}
|
||||
});*/
|
||||
|
||||
/*public void doDiffStatus(File path1, SVNRevision rN, File path2, SVNRevision rM, SVNDepth depth, boolean useAncestry, ISVNDiffStatusHandler handler) throws SVNException {*/
|
||||
}
|
||||
catch(SVNCancelException ex) {
|
||||
changes.clear();
|
||||
}
|
||||
catch (SVNException ex) {
|
||||
reportException(ex, baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private void report17DirDiff(SvnVcs vcs, SVNURL url) throws SVNException {
|
||||
final File ioFile = new File(myVirtualFile.getPath());
|
||||
final SVNWCClient wcClient = vcs.createWCClient();
|
||||
final SVNInfo info1 = wcClient.doInfo(ioFile, SVNRevision.HEAD);
|
||||
|
||||
if (info1 == null) {
|
||||
SVNErrorMessage err =
|
||||
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
else if (info1.getURL() == null) {
|
||||
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
|
||||
final SVNReporter17 reporter17 =
|
||||
new SVNReporter17(ioFile, new SVNWCContext(SvnConfiguration.getInstance(myProject).getOptions(myProject), new ISVNEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(SVNEvent event, double progress) throws SVNException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCancelled() throws SVNCancelException {
|
||||
}
|
||||
}),
|
||||
false, true, SVNDepth.INFINITY, false, false, true, false,
|
||||
SVNDebugLog.getDefaultLog());
|
||||
SVNRepository repository = null;
|
||||
SVNRepository repository2 = null;
|
||||
try {
|
||||
repository = vcs.createRepository(info1.getURL());
|
||||
long rev = repository.getLatestRevision();
|
||||
repository2 = vcs.createRepository(url.toString());
|
||||
SvnDiffEditor diffEditor = new SvnDiffEditor(myVirtualFile, repository2, rev, true);
|
||||
repository.diff(url, rev, rev, null, true, SVNDepth.INFINITY, false, reporter17,
|
||||
SVNCancellableEditor.newInstance(diffEditor, new SvnProgressCanceller(), null));
|
||||
changes.addAll(diffEditor.getChangesMap().values());
|
||||
} finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
if (repository2 != null) {
|
||||
repository2.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void report16DirDiff(SvnVcs vcs, SVNURL url) throws SVNException {
|
||||
// here there's 1.6 copy so ok to use SVNWCAccess
|
||||
final SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
|
||||
wcAccess.setOptions(vcs.getSvnOptions());
|
||||
SVNRepository repository = null;
|
||||
SVNRepository repository2 = null;
|
||||
try {
|
||||
SVNAdminAreaInfo info = wcAccess.openAnchor(new File(myVirtualFile.getPath()), false, SVNWCAccess.INFINITE_DEPTH);
|
||||
File anchorPath = info.getAnchor().getRoot();
|
||||
String target = "".equals(info.getTargetName()) ? null : info.getTargetName();
|
||||
|
||||
SVNEntry anchorEntry = info.getAnchor().getEntry("", false);
|
||||
if (anchorEntry == null) {
|
||||
SVNErrorMessage err =
|
||||
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", anchorPath);
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
else if (anchorEntry.getURL() == null) {
|
||||
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", anchorPath);
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
|
||||
SVNURL anchorURL = anchorEntry.getSVNURL();
|
||||
SVNReporter reporter = new SVNReporter(info, info.getAnchor().getFile(info.getTargetName()), false, true, SVNDepth.INFINITY,
|
||||
false, false, true, SVNDebugLog.getDefaultLog());
|
||||
|
||||
repository = vcs.createRepository(anchorURL.toString());
|
||||
long rev = repository.getLatestRevision();
|
||||
repository2 = vcs.createRepository((target == null) ? url.toString() : url.removePathTail().toString());
|
||||
SvnDiffEditor diffEditor = new SvnDiffEditor((target == null) ? myVirtualFile : myVirtualFile.getParent(),
|
||||
repository2, rev, true);
|
||||
repository.diff(url, rev, rev, target, true, true, false, reporter,
|
||||
SVNCancellableEditor.newInstance(diffEditor, new SvnProgressCanceller(), null));
|
||||
changes.addAll(diffEditor.getChangesMap().values());
|
||||
}
|
||||
finally {
|
||||
wcAccess.close();
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
if (repository2 != null) {
|
||||
repository2.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, SvnBundle.message("progress.computing.difference"), true, myProject);
|
||||
if (!changes.isEmpty()) {
|
||||
AbstractVcsHelper.getInstance(myProject).showWhatDiffersBrowser(null, changes, titleBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void compareFileWithBranch(final String baseUrl, final long revision) {
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final StringBuilder remoteTitleBuilder = new StringBuilder();
|
||||
final Ref<Boolean> success = new Ref<Boolean>();
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(true);
|
||||
}
|
||||
final SvnVcs vcs = SvnVcs.getInstance(myProject);
|
||||
SVNURL svnurl = getURLInBranch(vcs, baseUrl);
|
||||
if (svnurl == null) {
|
||||
reportNotFound(baseUrl);
|
||||
return;
|
||||
}
|
||||
remoteTitleBuilder.append(svnurl.toString());
|
||||
SVNWCClient client = vcs.createWCClient();
|
||||
client.doGetFileContents(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD, true, baos);
|
||||
success.set(true);
|
||||
}
|
||||
catch (SVNException ex) {
|
||||
reportException(ex, baseUrl);
|
||||
}
|
||||
}
|
||||
}, SvnBundle.message("compare.with.branch.progress.loading.content"), true, myProject);
|
||||
if (success.isNull()) {
|
||||
return;
|
||||
}
|
||||
SimpleDiffRequest req = new SimpleDiffRequest(myProject, SvnBundle.message("compare.with.branch.diff.title"));
|
||||
req.setContents(new SimpleContent(CharsetToolkit.bytesToString(baos.toByteArray(), myVirtualFile.getCharset())),
|
||||
new FileContent(myProject, myVirtualFile));
|
||||
req.setContentTitles(remoteTitleBuilder.toString(), myVirtualFile.getPresentableUrl());
|
||||
DiffManager.getInstance().getDiffTool().show(req);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SVNURL getURLInBranch(final SvnVcs vcs, final String baseUrl) throws SVNException {
|
||||
final SvnFileUrlMapping urlMapping = vcs.getSvnFileUrlMapping();
|
||||
final File file = new File(myVirtualFile.getPath());
|
||||
final SVNURL fileUrl = urlMapping.getUrlForFile(file);
|
||||
if (fileUrl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String fileUrlString = fileUrl.toString();
|
||||
final RootUrlInfo rootMixed = urlMapping.getWcRootForUrl(fileUrlString);
|
||||
if (rootMixed == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final SVNURL thisBranchForUrl = SvnUtil.getBranchForUrl(vcs, rootMixed.getVirtualFile(), fileUrlString);
|
||||
if (thisBranchForUrl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String relativePath = SVNPathUtil.getRelativePath(thisBranchForUrl.toString(), fileUrlString);
|
||||
return SVNURL.parseURIEncoded(SVNPathUtil.append(baseUrl, relativePath));
|
||||
}
|
||||
|
||||
private void reportException(final SVNException ex, final String baseUrl) {
|
||||
final SVNErrorCode errorCode = ex.getErrorMessage().getErrorCode();
|
||||
if (errorCode.equals(SVNErrorCode.RA_ILLEGAL_URL) ||
|
||||
errorCode.equals(SVNErrorCode.CLIENT_UNRELATED_RESOURCES) ||
|
||||
errorCode.equals(SVNErrorCode.RA_DAV_PATH_NOT_FOUND) ||
|
||||
errorCode.equals(SVNErrorCode.FS_NOT_FOUND)) {
|
||||
reportNotFound(baseUrl);
|
||||
}
|
||||
else {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(myProject, ex.getMessage(),
|
||||
SvnBundle.message("compare.with.branch.error.title"), Messages.getErrorIcon());
|
||||
}
|
||||
}, null, myProject);
|
||||
LOG.info(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportNotFound(final String baseUrl) {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(myProject,
|
||||
SvnBundle.message("compare.with.branch.location.error", myVirtualFile.getPresentableUrl(), baseUrl),
|
||||
SvnBundle.message("compare.with.branch.error.title"), Messages.getErrorIcon());
|
||||
}
|
||||
}, null, myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.CurrentContentRevision;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnRevisionNumber;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
@@ -53,7 +54,10 @@ public class ShowPropertiesDiffAction extends AbstractShowPropertiesDiffAction {
|
||||
protected SVNRevision getAfterRevisionValue(final Change change, final SvnVcs vcs) throws SVNException {
|
||||
final ContentRevision afterRevision = change.getAfterRevision();
|
||||
if (afterRevision != null) {
|
||||
return ((SvnRevisionNumber) afterRevision.getRevisionNumber()).getRevision();
|
||||
// CurrentContentRevision will be here, for instance, if invoked from changes dialog for "Compare with Branch" action
|
||||
return afterRevision instanceof CurrentContentRevision
|
||||
? SVNRevision.WORKING
|
||||
: ((SvnRevisionNumber)afterRevision.getRevisionNumber()).getRevision();
|
||||
} else {
|
||||
return SVNRevision.create(((SvnRevisionNumber) change.getBeforeRevision().getRevisionNumber()).getRevision().getNumber() + 1);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation {
|
||||
myContents = contents;
|
||||
myBaseRevision = baseRevision;
|
||||
myConfiguration = SvnConfiguration.getInstance(vcs.getProject());
|
||||
myShowMergeSources = myConfiguration.SHOW_MERGE_SOURCES_IN_ANNOTATE;
|
||||
myShowMergeSources = myConfiguration.isShowMergeSourcesInAnnotate();
|
||||
|
||||
myInfos = new MyPartiallyCreatedInfos();
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
// ignore mime type=true : IDEA-19562
|
||||
final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(progress, result);
|
||||
|
||||
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
|
||||
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate() &&
|
||||
SvnUtil.checkRepositoryVersion15(myVcs, url);
|
||||
final MySteppedLogGetter logGetter = new MySteppedLogGetter(
|
||||
myVcs, ioFile, progress,
|
||||
@@ -248,7 +248,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
pair.getSecond().getPath(), current);
|
||||
final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result);
|
||||
|
||||
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
|
||||
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate() &&
|
||||
SvnUtil.checkRepositoryVersion15(myVcs, wasUrl.toString());
|
||||
AnnotateClient client = myVcs.getFactory().createAnnotateClient();
|
||||
client.annotate(SvnTarget.fromURL(wasUrl), SVNRevision.create(1), svnRevision, svnRevision, calculateMergeinfo,
|
||||
@@ -478,6 +478,6 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
}
|
||||
|
||||
private static SVNDiffOptions getLogClientOptions(@NotNull SvnVcs vcs) {
|
||||
return SvnConfiguration.getInstance(vcs.getProject()).IGNORE_SPACES_IN_ANNOTATE ? new SVNDiffOptions(true, true, true) : null;
|
||||
return SvnConfiguration.getInstance(vcs.getProject()).isIgnoreSpacesInAnnotate() ? new SVNDiffOptions(true, true, true) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,13 @@ public abstract class BaseSvnClient implements SvnClient {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertDirectory(@NotNull SvnTarget target) {
|
||||
assertFile(target);
|
||||
if (!target.getFile().isDirectory()) {
|
||||
throw new IllegalArgumentException("Target should be directory " + target);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateFormat(@NotNull WorkingCopyFormat format, @NotNull Collection<WorkingCopyFormat> supported) throws VcsException {
|
||||
if (!supported.contains(format)) {
|
||||
throw new VcsException(
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.idea.svn.conflict.ConflictClient;
|
||||
import org.jetbrains.idea.svn.content.ContentClient;
|
||||
import org.jetbrains.idea.svn.copy.CopyMoveClient;
|
||||
import org.jetbrains.idea.svn.delete.DeleteClient;
|
||||
import org.jetbrains.idea.svn.diff.DiffClient;
|
||||
import org.jetbrains.idea.svn.history.HistoryClient;
|
||||
import org.jetbrains.idea.svn.integrate.MergeClient;
|
||||
import org.jetbrains.idea.svn.lock.LockClient;
|
||||
@@ -55,6 +56,7 @@ public abstract class ClientFactory {
|
||||
protected ExportClient myExportClient;
|
||||
protected UpgradeClient myUpgradeClient;
|
||||
protected BrowseClient myBrowseClient;
|
||||
protected DiffClient myDiffClient;
|
||||
|
||||
protected ClientFactory(@NotNull SvnVcs vcs) {
|
||||
myVcs = vcs;
|
||||
@@ -180,6 +182,11 @@ public abstract class ClientFactory {
|
||||
return prepare(myBrowseClient);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DiffClient createDiffClient() {
|
||||
return prepare(myDiffClient);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T extends SvnClient> T prepare(@NotNull T client) {
|
||||
client.setVcs(myVcs);
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.idea.svn.checkin.CmdImportClient;
|
||||
import org.jetbrains.idea.svn.checkout.CmdCheckoutClient;
|
||||
import org.jetbrains.idea.svn.checkout.CmdExportClient;
|
||||
import org.jetbrains.idea.svn.cleanup.CmdCleanupClient;
|
||||
import org.jetbrains.idea.svn.diff.CmdDiffClient;
|
||||
import org.jetbrains.idea.svn.update.CmdUpdateClient;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
|
||||
@@ -57,6 +58,7 @@ public class CmdClientFactory extends ClientFactory {
|
||||
myExportClient = new CmdExportClient();
|
||||
myUpgradeClient = new CmdUpgradeClient();
|
||||
myBrowseClient = new CmdBrowseClient();
|
||||
myDiffClient = new CmdDiffClient();
|
||||
statusClient = new SvnCommandLineStatusClient(myVcs);
|
||||
infoClient = new SvnCommandLineInfoClient(myVcs);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.idea.svn.conflict.SvnKitConflictClient;
|
||||
import org.jetbrains.idea.svn.content.SvnKitContentClient;
|
||||
import org.jetbrains.idea.svn.copy.SvnKitCopyMoveClient;
|
||||
import org.jetbrains.idea.svn.delete.SvnKitDeleteClient;
|
||||
import org.jetbrains.idea.svn.diff.SvnKitDiffClient;
|
||||
import org.jetbrains.idea.svn.history.SvnKitHistoryClient;
|
||||
import org.jetbrains.idea.svn.integrate.SvnKitMergeClient;
|
||||
import org.jetbrains.idea.svn.lock.SvnKitLockClient;
|
||||
@@ -57,6 +58,7 @@ public class SvnKitClientFactory extends ClientFactory {
|
||||
myExportClient = new SvnKitExportClient();
|
||||
myUpgradeClient = new SvnKitUpgradeClient();
|
||||
myBrowseClient = new SvnKitBrowseClient();
|
||||
myDiffClient = new SvnKitDiffClient();
|
||||
statusClient = new SvnkitSvnStatusClient(myVcs, null);
|
||||
infoClient = new SvnkitSvnWcClient(myVcs);
|
||||
}
|
||||
|
||||
+10
-7
@@ -33,12 +33,10 @@ import com.intellij.util.net.HttpConfigurable;
|
||||
import com.intellij.util.proxy.CommonProxy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.commandLine.AuthenticationCallback;
|
||||
import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.auth.*;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNBase64;
|
||||
@@ -221,7 +219,7 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
|
||||
|
||||
final Proxy proxy = getIdeaDefinedProxy(repositoryUrl);
|
||||
if (proxy != null){
|
||||
SvnConfiguration.putProxyIntoServersFile(myTempDirectory, repositoryUrl.getHost(), proxy);
|
||||
IdeaSVNConfigFile.putProxyIntoServersFile(myTempDirectory, repositoryUrl.getHost(), proxy);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -301,7 +299,7 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
|
||||
PopupUtil.showBalloonForActiveComponent("Failed to authenticate to proxy: " + e.getMessage(), MessageType.ERROR);
|
||||
return false;
|
||||
}
|
||||
return SvnConfiguration.putProxyCredentialsIntoServerFile(myTempDirectory, repositoryUrl.getHost(), authentication);
|
||||
return IdeaSVNConfigFile.putProxyCredentialsIntoServerFile(myTempDirectory, repositoryUrl.getHost(), authentication);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -358,7 +356,12 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
|
||||
}
|
||||
|
||||
protected SvnAuthenticationManager createTmpManager() {
|
||||
return SvnConfiguration.createForTmpDir(myVcs.getProject(), myTempDirectory);
|
||||
final SvnAuthenticationManager interactive = new SvnAuthenticationManager(myVcs.getProject(), myTempDirectory);
|
||||
|
||||
interactive.setRuntimeStorage(SvnConfiguration.RUNTIME_AUTH_CACHE);
|
||||
interactive.setAuthenticationProvider(new SvnInteractiveAuthenticationProvider(myVcs, interactive));
|
||||
|
||||
return interactive;
|
||||
}
|
||||
|
||||
protected abstract T getWithPassive(SvnAuthenticationManager passive) throws SVNException;
|
||||
|
||||
@@ -25,6 +25,17 @@ import java.util.List;
|
||||
*/
|
||||
public class CommandUtil {
|
||||
|
||||
@NotNull
|
||||
public static File resolvePath(@NotNull File base, @NotNull String path) {
|
||||
File result = new File(path);
|
||||
|
||||
if (!result.isAbsolute()) {
|
||||
result = ".".equals(path) ? base : new File(base, path);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts given value to parameters if condition is satisfied
|
||||
*
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.IdeaSVNConfigFile;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
@@ -73,7 +72,7 @@ public class ProxyModule extends BaseCommandRuntimeModule {
|
||||
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
|
||||
|
||||
if (StringUtil.isEmptyOrSpaces(groupName)) {
|
||||
groupName = SvnConfiguration.getNewGroupName(host, configFile);
|
||||
groupName = IdeaSVNConfigFile.getNewGroupName(host, configFile);
|
||||
|
||||
command.put("--config-option");
|
||||
command.put(String.format("servers:groups:%s=%s*", groupName, host));
|
||||
|
||||
+28
-3
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
@@ -124,13 +125,15 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
|
||||
final String text = e.getMessage();
|
||||
final boolean notEmpty = !StringUtil.isEmptyOrSpaces(text);
|
||||
if (notEmpty && text.contains("W155010")) {
|
||||
// just null
|
||||
return null;
|
||||
// if "svn info" is executed for several files at once, then this warning could be printed only for some files, but info for other
|
||||
// files should be parsed from output
|
||||
return output.getStdout();
|
||||
}
|
||||
// not a working copy exception
|
||||
// "E155007: '' is not a working copy"
|
||||
if (notEmpty && text.contains("is not a working copy")) {
|
||||
if (StringUtil.isNotEmpty(output.getStdout())) {
|
||||
// TODO: Seems not reproducible in 1.8.4
|
||||
// workaround: as in subversion 1.8 "svn info" on a working copy root outputs such error for parent folder,
|
||||
// if there are files with conflicts.
|
||||
// but the requested info is still in the output except root closing tag
|
||||
@@ -152,7 +155,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseResult(@NotNull final ISVNInfoHandler handler, @Nullable File base, @Nullable String result) throws SVNException {
|
||||
private static void parseResult(@NotNull final ISVNInfoHandler handler, @Nullable File base, @Nullable String result) throws SVNException {
|
||||
if (StringUtil.isEmpty(result)) {
|
||||
return;
|
||||
}
|
||||
@@ -246,4 +249,26 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
|
||||
});
|
||||
return infoArr[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInfo(@NotNull Collection<File> paths, @Nullable ISVNInfoHandler handler) throws SVNException {
|
||||
File base = ContainerUtil.getFirstItem(paths);
|
||||
|
||||
if (base != null) {
|
||||
base = CommandUtil.correctUpToExistingParent(base);
|
||||
|
||||
List<String> parameters = ContainerUtil.newArrayList();
|
||||
for (File file : paths) {
|
||||
CommandUtil.put(parameters, file);
|
||||
}
|
||||
CommandUtil.put(parameters, true, "--xml");
|
||||
|
||||
// Currently do not handle exceptions here like in SvnVcs.handleInfoException - just continue with parsing in case of warnings for
|
||||
// some of the requested items
|
||||
String result = execute(parameters, base);
|
||||
if (handler != null) {
|
||||
parseResult(handler, base, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ public enum SvnCommandName {
|
||||
importFolder("import", false),
|
||||
export("export", false),
|
||||
upgrade("upgrade", true),
|
||||
list("list", false);
|
||||
list("list", false),
|
||||
diff("diff", false);
|
||||
|
||||
private final String myName;
|
||||
private final boolean myWriteable;
|
||||
|
||||
@@ -213,13 +213,7 @@ public class SvnCommitRunner {
|
||||
|
||||
@NotNull
|
||||
private File toFile(@NotNull String path) {
|
||||
File result = new File(path);
|
||||
|
||||
if (!result.isAbsolute()) {
|
||||
result = new File(myBase, result.getPath());
|
||||
}
|
||||
|
||||
return result;
|
||||
return CommandUtil.resolvePath(myBase, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -887,7 +887,7 @@ public class SvnInfoHandler extends DefaultHandler {
|
||||
if (myBase != null) {
|
||||
final String path = attributes.getValue("path");
|
||||
assertSAX(!StringUtil.isEmptyOrSpaces(path));
|
||||
structure.myFile = new File(myBase, path);
|
||||
structure.myFile = CommandUtil.resolvePath(myBase, path);
|
||||
}
|
||||
|
||||
final String revision = attributes.getValue("revision");
|
||||
|
||||
@@ -119,7 +119,7 @@ public class SvnInfoStructure {
|
||||
|
||||
private SVNConflictAction parseConflictAction(@NotNull String actionName) {
|
||||
SVNConflictAction action = SVNConflictAction.fromString(actionName);
|
||||
action = action == null ? ourConflictActions.get(actionName) : null;
|
||||
action = action != null ? action : ourConflictActions.get(actionName);
|
||||
|
||||
if (action == null) {
|
||||
throw new IllegalArgumentException("Unknown conflict action " + actionName);
|
||||
@@ -130,10 +130,10 @@ public class SvnInfoStructure {
|
||||
|
||||
private SVNConflictReason parseConflictReason(@NotNull String reasonName) throws SAXException {
|
||||
SVNConflictReason reason = SVNConflictReason.fromString(reasonName);
|
||||
reason = reason == null ? ourConflictReasons.get(reasonName) : null;
|
||||
reason = reason != null ? reason : ourConflictReasons.get(reasonName);
|
||||
|
||||
if (reason == null) {
|
||||
throw new SAXException("Can not parse conflict reason: " + reason);
|
||||
throw new SAXException("Can not parse conflict reason: " + reasonName);
|
||||
}
|
||||
|
||||
return reason;
|
||||
|
||||
@@ -67,7 +67,7 @@ public class SvnStatusHandler extends DefaultHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static SVNStatusType getStatus(@NotNull String code) {
|
||||
public static SVNStatusType getStatus(@NotNull String code) {
|
||||
SVNStatusType result = ourStatusTypes.get(code);
|
||||
|
||||
if (result == null) {
|
||||
@@ -739,16 +739,7 @@ public class SvnStatusHandler extends DefaultHandler {
|
||||
protected void updateStatus(Attributes attributes, PortableStatus status, SVNLockWrapper lock) throws SAXException {
|
||||
final String path = attributes.getValue("path");
|
||||
assertSAX(path != null);
|
||||
final File file;
|
||||
if (new File(path).isAbsolute()) {
|
||||
file = new File(path);
|
||||
} else {
|
||||
if (".".equals(path)) {
|
||||
file = myBase;
|
||||
} else {
|
||||
file = new File(myBase, path);
|
||||
}
|
||||
}
|
||||
final File file = CommandUtil.resolvePath(myBase, path);
|
||||
status.setFile(file);
|
||||
final boolean exists = file.exists();
|
||||
if (exists) {
|
||||
|
||||
+1
-1
@@ -169,7 +169,7 @@ public class UpdateOutputLineConverter {
|
||||
}
|
||||
|
||||
private File createFile(String path) {
|
||||
return FileUtil.isAbsolute(path) ? new File(path) : new File(myBase, path);
|
||||
return CommandUtil.resolvePath(myBase, path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+36
-15
@@ -35,6 +35,9 @@ 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.integrate.SvnBranchItem;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
@@ -57,7 +60,11 @@ public class BranchConfigurationDialog extends DialogWrapper {
|
||||
private final SvnBranchConfigManager mySvnBranchConfigManager;
|
||||
private final VirtualFile myRoot;
|
||||
|
||||
public BranchConfigurationDialog(@NotNull final Project project, @NotNull final SvnBranchConfigurationNew configuration, final @NotNull String rootUrl, @NotNull final VirtualFile root, @NotNull String url) {
|
||||
public BranchConfigurationDialog(@NotNull final Project project,
|
||||
@NotNull final SvnBranchConfigurationNew configuration,
|
||||
final @NotNull SVNURL rootUrl,
|
||||
@NotNull final VirtualFile root,
|
||||
@NotNull String url) {
|
||||
super(project, true);
|
||||
myRoot = root;
|
||||
init();
|
||||
@@ -95,7 +102,7 @@ public class BranchConfigurationDialog extends DialogWrapper {
|
||||
.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
final String selectedUrl = SelectLocationDialog.selectLocation(project, rootUrl);
|
||||
final String selectedUrl = SelectLocationDialog.selectLocation(project, rootUrl.toDecodedString());
|
||||
if (selectedUrl != null) {
|
||||
if (!configuration.getBranchUrls().contains(selectedUrl)) {
|
||||
configuration
|
||||
@@ -127,27 +134,41 @@ public class BranchConfigurationDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private class TrunkUrlValidator extends DocumentAdapter {
|
||||
private final String myRootUrl;
|
||||
private final String myRootUrlPrefix;
|
||||
private final SVNURL myRootUrl;
|
||||
private final SvnBranchConfigurationNew myConfiguration;
|
||||
|
||||
private TrunkUrlValidator(final String rootUrl, final SvnBranchConfigurationNew configuration) {
|
||||
private TrunkUrlValidator(final SVNURL rootUrl, final SvnBranchConfigurationNew configuration) {
|
||||
myRootUrl = rootUrl;
|
||||
myRootUrlPrefix = rootUrl + "/";
|
||||
myConfiguration = configuration;
|
||||
}
|
||||
|
||||
protected void textChanged(final DocumentEvent e) {
|
||||
final String currentValue = myTrunkLocationTextField.getText();
|
||||
final boolean valueOk = (currentValue != null) && (currentValue.equals(myRootUrl) || currentValue.startsWith(myRootUrlPrefix));
|
||||
final boolean prefixOk = (currentValue != null) && (currentValue.startsWith(myRootUrlPrefix)) &&
|
||||
(currentValue.length() > myRootUrlPrefix.length());
|
||||
SVNURL url = parseUrl(myTrunkLocationTextField.getText());
|
||||
|
||||
myTrunkLocationTextField.getButton().setEnabled(valueOk);
|
||||
if (prefixOk) {
|
||||
myConfiguration.setTrunkUrl(currentValue.endsWith("/") ? currentValue.substring(0, currentValue.length() - 1) : currentValue);
|
||||
if (url != null) {
|
||||
boolean isAncestor = SVNURLUtil.isAncestor(myRootUrl, url);
|
||||
boolean areNotSame = isAncestor && !url.equals(myRootUrl);
|
||||
|
||||
myTrunkLocationTextField.getButton().setEnabled(isAncestor);
|
||||
if (areNotSame) {
|
||||
myConfiguration.setTrunkUrl(url.toDecodedString());
|
||||
}
|
||||
myErrorPrompt.setText(areNotSame ? "" : SvnBundle.message("configure.branches.error.wrong.url", myRootUrl));
|
||||
}
|
||||
myErrorPrompt.setText(prefixOk ? "" : SvnBundle.message("configure.branches.error.wrong.url", myRootUrl));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SVNURL parseUrl(@NotNull String url) {
|
||||
SVNURL result = null;
|
||||
|
||||
try {
|
||||
result = SvnUtil.createUrl(url);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
myErrorPrompt.setText(e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +201,7 @@ public class BranchConfigurationDialog extends DialogWrapper {
|
||||
if (wcRoot == null) {
|
||||
return;
|
||||
}
|
||||
final String rootUrl = wcRoot.getRepositoryUrl();
|
||||
final SVNURL rootUrl = wcRoot.getRepositoryUrlUrl();
|
||||
if (rootUrl == null) {
|
||||
Messages.showErrorDialog(project, SvnBundle.message("configure.branches.error.no.connection.title"),
|
||||
SvnBundle.message("configure.branches.title"));
|
||||
|
||||
@@ -60,6 +60,7 @@ import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -115,7 +116,12 @@ public class QuickMerge {
|
||||
|
||||
@Override
|
||||
public void run(ContinuationContext continuationContext) {
|
||||
if (SVNPathUtil.isAncestor(mySourceUrl, myWcInfo.getRootUrl()) || SVNPathUtil.isAncestor(myWcInfo.getRootUrl(), mySourceUrl)) {
|
||||
SVNURL url = parseUrl(continuationContext);
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SVNURLUtil.isAncestor(url, myWcInfo.getUrl()) || SVNURLUtil.isAncestor(myWcInfo.getUrl(), url)) {
|
||||
finishWithError(continuationContext, "Cannot merge from self", true);
|
||||
return;
|
||||
}
|
||||
@@ -124,6 +130,20 @@ public class QuickMerge {
|
||||
continuationContext.cancelEverything();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SVNURL parseUrl(ContinuationContext continuationContext) {
|
||||
SVNURL url = null;
|
||||
|
||||
try {
|
||||
url = SvnUtil.createUrl(mySourceUrl);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
finishWithError(continuationContext, e.getMessage(), true);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckRepositorySupportsMergeinfo extends TaskDescriptor {
|
||||
|
||||
+14
-26
@@ -20,11 +20,13 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
@@ -81,18 +83,13 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
final boolean authCredsOn = authMayBeStored && myManager.getHostOptionsProvider().getHostOptions(url).isAuthStorageEnabled();
|
||||
|
||||
final String userName =
|
||||
previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : SystemProperties.getUserName();
|
||||
previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : myManager.getDefaultUsername(kind, url);
|
||||
if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {// || ISVNAuthenticationManager.USERNAME.equals(kind)) {
|
||||
command = new Runnable() {
|
||||
public void run() {
|
||||
SimpleCredentialsDialog dialog = new SimpleCredentialsDialog(myProject);
|
||||
dialog.setup(realm, userName, authCredsOn);
|
||||
if (errorMessage == null) {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required"));
|
||||
}
|
||||
else {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required.was.failed"));
|
||||
}
|
||||
setTitle(dialog, errorMessage);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNPasswordAuthentication(dialog.getUserName(), dialog.getPassword(), dialog.isSaveAllowed(), url, false);
|
||||
@@ -108,12 +105,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
public void run() {
|
||||
UserNameCredentialsDialog dialog = new UserNameCredentialsDialog(myProject);
|
||||
dialog.setup(realm, userName, authCredsOn);
|
||||
if (errorMessage == null) {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required"));
|
||||
}
|
||||
else {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required.was.failed"));
|
||||
}
|
||||
setTitle(dialog, errorMessage);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNUserNameAuthentication(dialog.getUserName(), dialog.isSaveAllowed(), url, false);
|
||||
@@ -125,12 +117,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
command = new Runnable() {
|
||||
public void run() {
|
||||
SSHCredentialsDialog dialog = new SSHCredentialsDialog(myProject, realm, userName, authCredsOn, url.getPort());
|
||||
if (errorMessage == null) {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required"));
|
||||
}
|
||||
else {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required.was.failed"));
|
||||
}
|
||||
setTitle(dialog, errorMessage);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
int port = dialog.getPortNumber();
|
||||
@@ -158,12 +145,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
if (!StringUtil.isEmptyOrSpaces(file)) {
|
||||
dialog.setFile(file);
|
||||
}
|
||||
if (errorMessage == null) {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required"));
|
||||
}
|
||||
else {
|
||||
dialog.setTitle(SvnBundle.message("dialog.title.authentication.required.was.failed"));
|
||||
}
|
||||
setTitle(dialog, errorMessage);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNSSLAuthentication(new File(dialog.getCertificatePath()), String.valueOf(dialog.getCertificatePassword()),
|
||||
@@ -184,6 +166,12 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static void setTitle(@NotNull DialogWrapper dialog, @Nullable SVNErrorMessage errorMessage) {
|
||||
dialog.setTitle(errorMessage == null
|
||||
? SvnBundle.message("dialog.title.authentication.required")
|
||||
: SvnBundle.message("dialog.title.authentication.required.was.failed"));
|
||||
}
|
||||
|
||||
public int acceptServerAuthentication(final SVNURL url, String realm, final Object certificate, final boolean resultMayBeStored) {
|
||||
final int[] result = new int[1];
|
||||
Runnable command;
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diff;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.CurrentContentRevision;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnStatusConvertor;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.commandLine.*;
|
||||
import org.jetbrains.idea.svn.history.SvnRepositoryContentRevision;
|
||||
import org.tmatesoft.svn.core.SVNNodeKind;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class CmdDiffClient extends BaseSvnClient implements DiffClient {
|
||||
|
||||
@Override
|
||||
public List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException {
|
||||
// TODO: Currently implemented only for "Compare with Branch" action - target1 is assumed to be file, target2 - repository url
|
||||
// Such combination (file and url) with "--summarize" option is supported only in svn 1.8.
|
||||
// For svn 1.7 "--summarize" is only supported when both targets are repository urls.
|
||||
assertDirectory(target1);
|
||||
assertUrl(target2);
|
||||
|
||||
List<String> parameters = new ArrayList<String>();
|
||||
CommandUtil.put(parameters, target1);
|
||||
CommandUtil.put(parameters, target2);
|
||||
parameters.add("--xml");
|
||||
parameters.add("--summarize");
|
||||
|
||||
CommandExecutor executor = CommandUtil.execute(myVcs, target1, SvnCommandName.diff, parameters, null);
|
||||
return parseOutput(target1, target2, executor);
|
||||
}
|
||||
|
||||
private List<Change> parseOutput(@NotNull SvnTarget target1, @NotNull SvnTarget target2, @NotNull CommandExecutor executor)
|
||||
throws SvnBindException {
|
||||
try {
|
||||
DiffInfo diffInfo = CommandUtil.parse(executor.getOutput(), DiffInfo.class);
|
||||
List<Change> result = ContainerUtil.newArrayList();
|
||||
|
||||
if (diffInfo != null && diffInfo.paths != null) {
|
||||
for (DiffPath path : diffInfo.paths.diffPaths) {
|
||||
result.add(createChange(target1, target2, path));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (JAXBException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ContentRevision createRemoteRevision(@NotNull FilePath remotePath, @NotNull FilePath localPath, @NotNull FileStatus status) {
|
||||
// explicitly use local path for deleted items - so these items will be correctly displayed as deleted under local working copy node
|
||||
// and not as deleted under remote branch node (in ChangesBrowser)
|
||||
// NOTE, that content is still retrieved using remotePath.
|
||||
return SvnRepositoryContentRevision
|
||||
.create(myVcs, remotePath, status == FileStatus.DELETED ? localPath : null, SVNRevision.HEAD.getNumber());
|
||||
}
|
||||
|
||||
private static ContentRevision createLocalRevision(@NotNull FilePath path) {
|
||||
return CurrentContentRevision.create(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Change createChange(@NotNull SvnTarget target1, @NotNull SvnTarget target2, @NotNull DiffPath diffPath) throws SvnBindException {
|
||||
// TODO: 1) Unify logic of creating Change instance with SvnDiffEditor and SvnChangeProviderContext
|
||||
// TODO: 2) If some directory is switched, files inside it are returned as modified in "svn diff --summarize", even if they are equal
|
||||
// TODO: to branch files by content - possibly add separate processing of all switched files
|
||||
// TODO: 3) Properties change is currently not added as part of result change like in SvnChangeProviderContext.patchWithPropertyChange
|
||||
|
||||
File oldTarget = CommandUtil.resolvePath(target1.getFile(), diffPath.path);
|
||||
String relativePath = FileUtil.getRelativePath(target1.getFile(), oldTarget);
|
||||
|
||||
if (relativePath == null) {
|
||||
throw new SvnBindException("Could not get relative path for " + target1.getFile() + " and " + oldTarget);
|
||||
}
|
||||
|
||||
FilePath localPath = VcsUtil.getFilePath(oldTarget, diffPath.isDirectory());
|
||||
FilePath remotePath = VcsUtil
|
||||
.getFilePathOnNonLocal(SVNPathUtil.append(target2.getPathOrUrlDecodedString(), FileUtil.toSystemIndependentName(relativePath)),
|
||||
diffPath.isDirectory());
|
||||
|
||||
FileStatus status = SvnStatusConvertor
|
||||
.convertStatus(SvnStatusHandler.getStatus(diffPath.itemStatus), SvnStatusHandler.getStatus(diffPath.propertiesStatus));
|
||||
|
||||
ContentRevision beforeRevision = status == FileStatus.ADDED ? null : createRemoteRevision(remotePath, localPath, status);
|
||||
ContentRevision afterRevision = status == FileStatus.DELETED ? null : createLocalRevision(localPath);
|
||||
|
||||
return createChange(status, beforeRevision, afterRevision);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Change createChange(@NotNull final FileStatus status,
|
||||
@Nullable final ContentRevision beforeRevision,
|
||||
@Nullable final ContentRevision afterRevision) {
|
||||
// isRenamed() and isMoved() are always false here not to have text like "moved from ..." in changes window - by default different
|
||||
// paths in before and after revisions are treated as move, but this is not the case for "Compare with Branch"
|
||||
return new Change(beforeRevision, afterRevision, status) {
|
||||
@Override
|
||||
public boolean isRenamed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMoved() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@XmlRootElement(name = "diff")
|
||||
public static class DiffInfo {
|
||||
|
||||
@XmlElement(name = "paths")
|
||||
public DiffPaths paths;
|
||||
}
|
||||
|
||||
public static class DiffPaths {
|
||||
|
||||
@XmlElement(name = "path")
|
||||
public List<DiffPath> diffPaths = new ArrayList<DiffPath>();
|
||||
}
|
||||
|
||||
public static class DiffPath {
|
||||
|
||||
@XmlAttribute(name = "kind")
|
||||
public String kind;
|
||||
|
||||
@XmlAttribute(name = "props")
|
||||
public String propertiesStatus;
|
||||
|
||||
@XmlAttribute(name = "item")
|
||||
public String itemStatus;
|
||||
|
||||
@XmlValue
|
||||
public String path;
|
||||
|
||||
public boolean isDirectory() {
|
||||
return SVNNodeKind.DIR.equals(SVNNodeKind.parseKind(kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.diff;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
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.SvnBranchConfigurationNew;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CompareWithBranchAction extends AnAction implements DumbAware {
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
assert project != null;
|
||||
final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
|
||||
|
||||
SelectBranchPopup
|
||||
.show(project, virtualFile, new MyBranchSelectedCallback(virtualFile), SvnBundle.message("compare.with.branch.popup.title"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
|
||||
e.getPresentation().setEnabled(isEnabled(project, virtualFile));
|
||||
}
|
||||
|
||||
private static boolean isEnabled(final Project project, final VirtualFile virtualFile) {
|
||||
if (project == null || virtualFile == null) {
|
||||
return false;
|
||||
}
|
||||
final FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(virtualFile);
|
||||
if (fileStatus == FileStatus.UNKNOWN || fileStatus == FileStatus.ADDED || fileStatus == FileStatus.IGNORED) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class MyBranchSelectedCallback implements SelectBranchPopup.BranchSelectedCallback {
|
||||
|
||||
@NotNull private final VirtualFile myVirtualFile;
|
||||
|
||||
public MyBranchSelectedCallback(@NotNull VirtualFile virtualFile) {
|
||||
myVirtualFile = virtualFile;
|
||||
}
|
||||
|
||||
public void branchSelected(Project project, SvnBranchConfigurationNew configuration, String url, long revision) {
|
||||
ElementWithBranchComparer comparer =
|
||||
myVirtualFile.isDirectory()
|
||||
? new DirectoryWithBranchComparer(project, myVirtualFile, url, revision)
|
||||
: new FileWithBranchComparer(project, myVirtualFile, url, revision);
|
||||
|
||||
comparer.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -13,14 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn;
|
||||
package org.jetbrains.idea.svn.diff;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.api.SvnClient;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/28/13
|
||||
* Time: 10:14 AM
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public enum AuthManagerType {
|
||||
active, passive, usual;
|
||||
public interface DiffClient extends SvnClient {
|
||||
|
||||
List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException;
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diff;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnProgressCanceller;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.status.SvnDiffEditor;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNCancellableEditor;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminAreaInfo;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNReporter;
|
||||
import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
|
||||
import org.tmatesoft.svn.core.internal.wc17.SVNReporter17;
|
||||
import org.tmatesoft.svn.core.internal.wc17.SVNWCContext;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNEvent;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
import org.tmatesoft.svn.util.SVNDebugLog;
|
||||
import org.tmatesoft.svn.util.SVNLogType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class DirectoryWithBranchComparer extends ElementWithBranchComparer {
|
||||
|
||||
@NotNull private final StringBuilder titleBuilder = new StringBuilder();
|
||||
@NotNull private final List<Change> changes = new ArrayList<Change>();
|
||||
|
||||
public DirectoryWithBranchComparer(@NotNull Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String branchUrl,
|
||||
long branchRevision) {
|
||||
super(project, virtualFile, branchUrl, branchRevision);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compare() throws SVNException, VcsException {
|
||||
titleBuilder.append(SvnBundle.message("repository.browser.compare.title", myElementUrl,
|
||||
FileUtil.toSystemDependentName(myVirtualFile.getPresentableUrl())));
|
||||
|
||||
final File ioFile = new File(myVirtualFile.getPath());
|
||||
WorkingCopyFormat format = myVcs.getWorkingCopyFormat(ioFile);
|
||||
|
||||
if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format)) {
|
||||
// svn 1.7 command line "--summarize" option for "diff" command does not support comparing working copy directories with repository
|
||||
// directories - that is why command line is only used explicitly for svn 1.8
|
||||
compareWithCommandLine();
|
||||
}
|
||||
else if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
|
||||
report17DirDiff();
|
||||
}
|
||||
else {
|
||||
report16DirDiff();
|
||||
}
|
||||
}
|
||||
|
||||
private void compareWithCommandLine() throws VcsException {
|
||||
SvnTarget target1 = SvnTarget.fromFile(new File(myVirtualFile.getPath()));
|
||||
SvnTarget target2 = SvnTarget.fromURL(myElementUrl);
|
||||
|
||||
changes.addAll(myVcs.getFactory(target1).createDiffClient().compare(target1, target2));
|
||||
}
|
||||
|
||||
private void report17DirDiff() throws SVNException {
|
||||
final File ioFile = new File(myVirtualFile.getPath());
|
||||
final SVNInfo info1 = myVcs.getInfo(ioFile, SVNRevision.HEAD);
|
||||
|
||||
if (info1 == null) {
|
||||
SVNErrorMessage err =
|
||||
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
else if (info1.getURL() == null) {
|
||||
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", myVirtualFile.getPath());
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
|
||||
final SVNReporter17 reporter17 =
|
||||
new SVNReporter17(ioFile, new SVNWCContext(SvnConfiguration.getInstance(myProject).getOptions(myProject), new ISVNEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(SVNEvent event, double progress) throws SVNException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCancelled() throws SVNCancelException {
|
||||
}
|
||||
}),
|
||||
false, true, SVNDepth.INFINITY, false, false, true, false,
|
||||
SVNDebugLog.getDefaultLog());
|
||||
SVNRepository repository = null;
|
||||
SVNRepository repository2 = null;
|
||||
try {
|
||||
repository = myVcs.createRepository(info1.getURL());
|
||||
long rev = repository.getLatestRevision();
|
||||
repository2 = myVcs.createRepository(myElementUrl.toString());
|
||||
SvnDiffEditor diffEditor = new SvnDiffEditor(myVirtualFile, repository2, rev, true);
|
||||
repository.diff(myElementUrl, rev, rev, null, true, SVNDepth.INFINITY, false, reporter17,
|
||||
SVNCancellableEditor.newInstance(diffEditor, new SvnProgressCanceller(), null));
|
||||
changes.addAll(diffEditor.getChangesMap().values());
|
||||
}
|
||||
finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
if (repository2 != null) {
|
||||
repository2.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void report16DirDiff() throws SVNException {
|
||||
// here there's 1.6 copy so ok to use SVNWCAccess
|
||||
final SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
|
||||
wcAccess.setOptions(myVcs.getSvnOptions());
|
||||
SVNRepository repository = null;
|
||||
SVNRepository repository2 = null;
|
||||
try {
|
||||
SVNAdminAreaInfo info = wcAccess.openAnchor(new File(myVirtualFile.getPath()), false, SVNWCAccess.INFINITE_DEPTH);
|
||||
File anchorPath = info.getAnchor().getRoot();
|
||||
String target = "".equals(info.getTargetName()) ? null : info.getTargetName();
|
||||
|
||||
SVNEntry anchorEntry = info.getAnchor().getEntry("", false);
|
||||
if (anchorEntry == null) {
|
||||
SVNErrorMessage err =
|
||||
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND, "''{0}'' is not under version control", anchorPath);
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
else if (anchorEntry.getURL() == null) {
|
||||
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", anchorPath);
|
||||
SVNErrorManager.error(err, SVNLogType.WC);
|
||||
}
|
||||
|
||||
SVNURL anchorURL = anchorEntry.getSVNURL();
|
||||
SVNReporter reporter = new SVNReporter(info, info.getAnchor().getFile(info.getTargetName()), false, true, SVNDepth.INFINITY,
|
||||
false, false, true, SVNDebugLog.getDefaultLog());
|
||||
|
||||
repository = myVcs.createRepository(anchorURL.toString());
|
||||
long rev = repository.getLatestRevision();
|
||||
repository2 = myVcs.createRepository((target == null) ? myElementUrl.toString() : myElementUrl.removePathTail().toString());
|
||||
SvnDiffEditor diffEditor = new SvnDiffEditor((target == null) ? myVirtualFile : myVirtualFile.getParent(),
|
||||
repository2, rev, true);
|
||||
repository.diff(myElementUrl, rev, rev, target, true, true, false, reporter,
|
||||
SVNCancellableEditor.newInstance(diffEditor, new SvnProgressCanceller(), null));
|
||||
changes.addAll(diffEditor.getChangesMap().values());
|
||||
}
|
||||
finally {
|
||||
wcAccess.close();
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
if (repository2 != null) {
|
||||
repository2.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancel() {
|
||||
changes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showResult() {
|
||||
if (!changes.isEmpty()) {
|
||||
AbstractVcsHelper.getInstance(myProject).showWhatDiffersBrowser(null, changes, titleBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return SvnBundle.message("progress.computing.difference");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diff;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNCancelException;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public abstract class ElementWithBranchComparer {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(ElementWithBranchComparer.class);
|
||||
|
||||
@NotNull protected final Project myProject;
|
||||
@NotNull protected final SvnVcs myVcs;
|
||||
@NotNull protected final VirtualFile myVirtualFile;
|
||||
@NotNull protected final String myBranchUrl;
|
||||
protected final long myBranchRevision;
|
||||
protected SVNURL myElementUrl;
|
||||
|
||||
ElementWithBranchComparer(@NotNull Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String branchUrl,
|
||||
long branchRevision) {
|
||||
myProject = project;
|
||||
myVcs = SvnVcs.getInstance(myProject);
|
||||
myVirtualFile = virtualFile;
|
||||
myBranchUrl = branchUrl;
|
||||
myBranchRevision = branchRevision;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
new Task.Modal(myProject, getTitle(), true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
beforeCompare();
|
||||
myElementUrl = resolveElementUrl();
|
||||
if (myElementUrl == null) {
|
||||
reportNotFound();
|
||||
}
|
||||
else {
|
||||
compare();
|
||||
}
|
||||
}
|
||||
catch (SVNCancelException ex) {
|
||||
ElementWithBranchComparer.this.onCancel();
|
||||
}
|
||||
catch (SVNException ex) {
|
||||
reportException(new SvnBindException(ex));
|
||||
}
|
||||
catch (SvnBindException ex) {
|
||||
reportException(ex);
|
||||
}
|
||||
catch (VcsException ex) {
|
||||
reportGeneralException(ex);
|
||||
}
|
||||
}
|
||||
}.queue();
|
||||
showResult();
|
||||
}
|
||||
|
||||
protected void beforeCompare() {
|
||||
}
|
||||
|
||||
protected abstract void compare() throws SVNException, VcsException;
|
||||
|
||||
protected abstract void showResult();
|
||||
|
||||
protected void onCancel() {
|
||||
}
|
||||
|
||||
public abstract String getTitle();
|
||||
|
||||
@Nullable
|
||||
protected SVNURL resolveElementUrl() throws SVNException {
|
||||
final SvnFileUrlMapping urlMapping = myVcs.getSvnFileUrlMapping();
|
||||
final File file = new File(myVirtualFile.getPath());
|
||||
final SVNURL fileUrl = urlMapping.getUrlForFile(file);
|
||||
if (fileUrl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String fileUrlString = fileUrl.toString();
|
||||
final RootUrlInfo rootMixed = urlMapping.getWcRootForUrl(fileUrlString);
|
||||
if (rootMixed == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final SVNURL thisBranchForUrl = SvnUtil.getBranchForUrl(myVcs, rootMixed.getVirtualFile(), fileUrlString);
|
||||
if (thisBranchForUrl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String relativePath = SVNPathUtil.getRelativePath(thisBranchForUrl.toString(), fileUrlString);
|
||||
return SVNURL.parseURIEncoded(SVNPathUtil.append(myBranchUrl, relativePath));
|
||||
}
|
||||
|
||||
private void reportException(final SvnBindException e) {
|
||||
if (e.contains(SVNErrorCode.RA_ILLEGAL_URL) ||
|
||||
e.contains(SVNErrorCode.CLIENT_UNRELATED_RESOURCES) ||
|
||||
e.contains(SVNErrorCode.RA_DAV_PATH_NOT_FOUND) ||
|
||||
e.contains(SVNErrorCode.FS_NOT_FOUND) ||
|
||||
e.contains(SVNErrorCode.ILLEGAL_TARGET)) {
|
||||
reportNotFound();
|
||||
}
|
||||
else {
|
||||
reportGeneralException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportGeneralException(final Exception e) {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(myProject, e.getMessage(),
|
||||
SvnBundle.message("compare.with.branch.error.title"), Messages.getErrorIcon());
|
||||
}
|
||||
}, null, myProject);
|
||||
LOG.info(e);
|
||||
}
|
||||
|
||||
private void reportNotFound() {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showMessageDialog(myProject,
|
||||
SvnBundle
|
||||
.message("compare.with.branch.location.error", myVirtualFile.getPresentableUrl(), myBranchUrl),
|
||||
SvnBundle.message("compare.with.branch.error.title"), Messages.getErrorIcon());
|
||||
}
|
||||
}, null, myProject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diff;
|
||||
|
||||
import com.intellij.openapi.diff.DiffManager;
|
||||
import com.intellij.openapi.diff.FileContent;
|
||||
import com.intellij.openapi.diff.SimpleContent;
|
||||
import com.intellij.openapi.diff.SimpleDiffRequest;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class FileWithBranchComparer extends ElementWithBranchComparer {
|
||||
|
||||
@NotNull private final Ref<byte[]> content = new Ref<byte[]>();
|
||||
@NotNull private final StringBuilder remoteTitleBuilder = new StringBuilder();
|
||||
@NotNull private final Ref<Boolean> success = new Ref<Boolean>();
|
||||
|
||||
public FileWithBranchComparer(@NotNull Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String branchUrl,
|
||||
long branchRevision) {
|
||||
super(project, virtualFile, branchUrl, branchRevision);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeCompare() {
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compare() throws SVNException, VcsException {
|
||||
remoteTitleBuilder.append(myElementUrl);
|
||||
content.set(SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(myElementUrl), SVNRevision.HEAD, SVNRevision.UNDEFINED));
|
||||
success.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showResult() {
|
||||
if (!success.isNull()) {
|
||||
SimpleDiffRequest req = new SimpleDiffRequest(myProject, SvnBundle.message("compare.with.branch.diff.title"));
|
||||
req.setContents(new SimpleContent(CharsetToolkit.bytesToString(content.get(), myVirtualFile.getCharset())),
|
||||
new FileContent(myProject, myVirtualFile));
|
||||
req.setContentTitles(remoteTitleBuilder.toString(), myVirtualFile.getPresentableUrl());
|
||||
DiffManager.getInstance().getDiffTool().show(req);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return SvnBundle.message("compare.with.branch.progress.loading.content");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diff;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SvnKitDiffClient extends BaseSvnClient implements DiffClient {
|
||||
|
||||
@Override
|
||||
public List<Change> compare(@NotNull SvnTarget target1, @NotNull SvnTarget target2) throws VcsException {
|
||||
throw new UnsupportedOperationException("Diff client is not implemented for SVNKit");
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,9 @@ import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO: This one seem to determine revision in which branch was created - copied from trunk.
|
||||
// TODO: This could be done in one command "svn log <folder> -r 0:HEAD --stop-on-copy --limit 1".
|
||||
// TODO: Check for 1.7 and rewrite using this approach.
|
||||
public class FirstInBranch implements Runnable {
|
||||
private final SvnVcs myVcs;
|
||||
private final String myBranchUrl;
|
||||
|
||||
@@ -188,7 +188,7 @@ public class SvnHistoryProvider
|
||||
}
|
||||
}
|
||||
|
||||
final boolean showMergeSources = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE;
|
||||
final boolean showMergeSources = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate();
|
||||
final LogLoader logLoader;
|
||||
if (path.isNonLocal()) {
|
||||
logLoader = new RepositoryLoader(myVcs, committedPath, from, to, limit, peg, forceBackwards, showMergeSources);
|
||||
|
||||
+3
-2
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.history;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
|
||||
@@ -27,9 +28,9 @@ import org.jetbrains.idea.svn.SvnVcs;
|
||||
public class SvnRepositoryBinaryContentRevision extends SvnRepositoryContentRevision implements BinaryContentRevision {
|
||||
private byte[] myBinaryContent;
|
||||
|
||||
public SvnRepositoryBinaryContentRevision(final SvnVcs vcs, final String repositoryRoot, final String path,
|
||||
public SvnRepositoryBinaryContentRevision(final SvnVcs vcs, @NotNull final FilePath remotePath,
|
||||
@Nullable final FilePath localPath, final long revision) {
|
||||
super(vcs, repositoryRoot, path, localPath, revision);
|
||||
super(vcs, remotePath, localPath, revision);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+23
-39
@@ -23,23 +23,24 @@
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Throwable2Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.VcsKey;
|
||||
import com.intellij.openapi.vcs.actions.VcsContextFactory;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnRevisionNumber;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
@@ -48,32 +49,16 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsContentRevision {
|
||||
private final String myRepositoryRoot;
|
||||
private final SvnVcs myVcs;
|
||||
private final String myPath;
|
||||
@NotNull private final FilePath myFilePath;
|
||||
private final long myRevision;
|
||||
|
||||
SvnRepositoryContentRevision(final SvnVcs vcs, final String repositoryRoot, final String path, @Nullable final FilePath localPath,
|
||||
public SvnRepositoryContentRevision(final SvnVcs vcs, @NotNull final FilePath remotePath, @Nullable final FilePath localPath,
|
||||
final long revision) {
|
||||
myVcs = vcs;
|
||||
myPath = path;
|
||||
myRepositoryRoot = repositoryRoot;
|
||||
if (localPath != null) {
|
||||
myFilePath = localPath;
|
||||
}
|
||||
else {
|
||||
FilePath local;
|
||||
try {
|
||||
final String fullPath = SvnUtil.appendMultiParts(repositoryRoot, myPath);
|
||||
local = VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(fullPath, false);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
// todo what to do safely?
|
||||
local = VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(repositoryRoot, false);
|
||||
}
|
||||
myFilePath = local;
|
||||
}
|
||||
myPath = FileUtil.toSystemIndependentName(remotePath.getPath());
|
||||
myFilePath = localPath != null ? localPath : remotePath;
|
||||
myRevision = revision;
|
||||
}
|
||||
|
||||
@@ -125,15 +110,19 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
|
||||
|
||||
public static SvnRepositoryContentRevision create(final SvnVcs vcs, final String repositoryRoot, final String path,
|
||||
@Nullable final FilePath localPath, final long revision) {
|
||||
int fileNamePos = path.lastIndexOf('/');
|
||||
if (fileNamePos >= 0) {
|
||||
String fileName = path.substring(fileNamePos);
|
||||
final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
|
||||
if (fileType.isBinary()) {
|
||||
return new SvnRepositoryBinaryContentRevision(vcs, repositoryRoot, path, localPath, revision);
|
||||
}
|
||||
}
|
||||
return new SvnRepositoryContentRevision(vcs, repositoryRoot, path, localPath, revision);
|
||||
// TODO: Check if isDirectory = false always true for this method calls
|
||||
FilePath remotePath = VcsUtil.getFilePathOnNonLocal(SvnUtil.appendMultiParts(repositoryRoot, path), false);
|
||||
|
||||
return create(vcs, remotePath, localPath, revision);
|
||||
}
|
||||
|
||||
public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
|
||||
@NotNull FilePath remotePath,
|
||||
@Nullable FilePath localPath,
|
||||
long revision) {
|
||||
return remotePath.getFileType().isBinary()
|
||||
? new SvnRepositoryBinaryContentRevision(vcs, remotePath, localPath, revision)
|
||||
: new SvnRepositoryContentRevision(vcs, remotePath, localPath, revision);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,12 +169,7 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
|
||||
}
|
||||
|
||||
public String getFullPath() {
|
||||
String fullPath = myRepositoryRoot;
|
||||
if (!fullPath.endsWith("/") && !myPath.startsWith("/")) {
|
||||
fullPath += "/";
|
||||
}
|
||||
fullPath += myPath;
|
||||
return fullPath;
|
||||
return myPath;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.idea.svn.update.UpdateEventHandler;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.SVNDiffOptions;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevisionRange;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
@@ -132,7 +131,7 @@ public class GroupMerger implements IMerger {
|
||||
SvnTarget source = SvnTarget.fromURL(myCurrentBranchUrl);
|
||||
MergeClient client = myVcs.getFactory(myTarget).createMergeClient();
|
||||
|
||||
client.merge(source, createRange(), myTarget, SVNDepth.INFINITY, mySvnConfig.MERGE_DRY_RUN, myDryRun, true,
|
||||
client.merge(source, createRange(), myTarget, SVNDepth.INFINITY, mySvnConfig.isMergeDryRun(), myDryRun, true,
|
||||
mySvnConfig.getMergeOptions(), myHandler);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -97,8 +97,8 @@ public class IntegratedSelectedOptionsDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
SvnConfiguration svnConfig = SvnConfiguration.getInstance(myVcs.getProject());
|
||||
myDryRunCheckbox.setSelected(svnConfig.MERGE_DRY_RUN);
|
||||
myIgnoreWhitespacesCheckBox.setSelected(svnConfig.IGNORE_SPACES_IN_MERGE);
|
||||
myDryRunCheckbox.setSelected(svnConfig.isMergeDryRun());
|
||||
myIgnoreWhitespacesCheckBox.setSelected(svnConfig.isIgnoreSpacesInMerge());
|
||||
|
||||
mySourceInfoLabel.setText(SvnBundle.message("action.Subversion.integrate.changes.branch.info.source.label.text", currentBranch));
|
||||
myTargetInfoLabel.setText(SvnBundle.message("action.Subversion.integrate.changes.branch.info.target.label.text", selectedBranchUrl));
|
||||
@@ -223,8 +223,8 @@ public class IntegratedSelectedOptionsDialog extends DialogWrapper {
|
||||
|
||||
public void saveOptions() {
|
||||
SvnConfiguration svnConfig = SvnConfiguration.getInstance(myVcs.getProject());
|
||||
svnConfig.MERGE_DRY_RUN = myDryRunCheckbox.isSelected();
|
||||
svnConfig.IGNORE_SPACES_IN_MERGE = myIgnoreWhitespacesCheckBox.isSelected();
|
||||
svnConfig.setMergeDryRun(myDryRunCheckbox.isSelected());
|
||||
svnConfig.setIgnoreSpacesInMerge(myIgnoreWhitespacesCheckBox.isSelected());
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
|
||||
@@ -128,7 +128,7 @@ public class Merger implements IMerger {
|
||||
SvnTarget source = SvnTarget.fromURL(myCurrentBranchUrl);
|
||||
MergeClient client = myVcs.getFactory(myTarget).createMergeClient();
|
||||
|
||||
client.merge(source, createRange(), myTarget, SVNDepth.INFINITY, mySvnConfig.MERGE_DRY_RUN, isRecordOnly(), true,
|
||||
client.merge(source, createRange(), myTarget, SVNDepth.INFINITY, mySvnConfig.isMergeDryRun(), isRecordOnly(), true,
|
||||
mySvnConfig.getMergeOptions(), myHandler);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.idea.svn.integrate;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnRevisionNumber;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
@@ -88,7 +87,7 @@ public class PointMerger extends Merger {
|
||||
SvnTarget source1 = SvnTarget.fromURL(SVNURL.parseURIEncoded(beforeUrl), ((SvnRevisionNumber)before.getRevisionNumber()).getRevision());
|
||||
SvnTarget source2 = SvnTarget.fromURL(SVNURL.parseURIEncoded(afterUrl), ((SvnRevisionNumber) after.getRevisionNumber()).getRevision());
|
||||
|
||||
client.merge(source1, source2, afterPath, SVNDepth.FILES, true, mySvnConfig.MERGE_DRY_RUN, false, false, mySvnConfig.getMergeOptions(),
|
||||
client.merge(source1, source2, afterPath, SVNDepth.FILES, true, mySvnConfig.isMergeDryRun(), false, false, mySvnConfig.getMergeOptions(),
|
||||
myHandler);
|
||||
}
|
||||
|
||||
@@ -99,7 +98,7 @@ public class PointMerger extends Merger {
|
||||
final File beforePath = SvnUtil.fileFromUrl(myTarget, path, beforeUrl);
|
||||
|
||||
DeleteClient client = myVcs.getFactory(myTarget).createDeleteClient();
|
||||
client.delete(beforePath, false, mySvnConfig.MERGE_DRY_RUN, myHandler);
|
||||
client.delete(beforePath, false, mySvnConfig.isMergeDryRun(), myHandler);
|
||||
}
|
||||
|
||||
private void add(final Change change) throws SVNException, VcsException {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ResolveWorker {
|
||||
}
|
||||
|
||||
return ((! myConflictedVirtualFiles.isEmpty()) || (! haveUnresolvedConflicts(updatedFiles))) &&
|
||||
(! SvnConfiguration.getInstance(myProject).MERGE_DRY_RUN);
|
||||
(!SvnConfiguration.getInstance(myProject).isMergeDryRun());
|
||||
}
|
||||
|
||||
public static boolean haveUnresolvedConflicts(final UpdatedFiles updatedFiles) {
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ public class SvnIntegrateChangesActionPerformer implements SelectBranchPopup.Bra
|
||||
return;
|
||||
}
|
||||
final SvnIntegrateChangesTask task = new SvnIntegrateChangesTask(myVcs, info, myMergerFactory, sourceUrl, SvnBundle.message("action.Subversion.integrate.changes.messages.title"),
|
||||
SvnConfiguration.getInstance(myVcs.getProject()).MERGE_DRY_RUN, name);
|
||||
SvnConfiguration.getInstance(myVcs.getProject()).isMergeDryRun(), name);
|
||||
ProgressManager.getInstance().run(task);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class OneRecursiveShotMergeInfoWorker implements MergeInfoWorker {
|
||||
}
|
||||
|
||||
public void prepare() throws VcsException {
|
||||
final SVNDepth depth = SvnConfiguration.getInstance(myProject).CHECK_NESTED_FOR_QUICK_MERGE ? SVNDepth.INFINITY : SVNDepth.EMPTY;
|
||||
final SVNDepth depth = SvnConfiguration.getInstance(myProject).isCheckNestedForQuickMerge() ? SVNDepth.INFINITY : SVNDepth.EMPTY;
|
||||
ISVNPropertyHandler handler = new ISVNPropertyHandler() {
|
||||
public void handleProperty(File path, SVNPropertyData property) throws SVNException {
|
||||
final String key = keyFromFile(path);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.portable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
|
||||
@@ -38,4 +40,6 @@ public interface SvnWcClientI extends SvnMarkerInterface {
|
||||
ISVNInfoHandler handler) throws SVNException;
|
||||
SVNInfo doInfo(File path, SVNRevision revision) throws SVNException;
|
||||
SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException;
|
||||
|
||||
void doInfo(@NotNull Collection<File> paths, @Nullable ISVNInfoHandler handler) throws SVNException;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.idea.svn.portable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
@@ -83,4 +84,9 @@ public class SvnkitSvnWcClient implements SvnWcClientI {
|
||||
public SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
|
||||
return getClient().doInfo(url, pegRevision, revision);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInfo(@NotNull Collection<File> paths, @Nullable ISVNInfoHandler handler) throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.statistics;
|
||||
|
||||
import com.intellij.internal.statistic.beans.GroupDescriptor;
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vcs.statistics.VcsUsagesCollector;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.NestedCopyType;
|
||||
import org.jetbrains.idea.svn.RootUrlInfo;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SvnWorkingCopyFormatUsagesCollector extends VcsUsagesCollector {
|
||||
|
||||
private static final String GROUP_ID = "svn working copy format";
|
||||
|
||||
@NotNull
|
||||
public GroupDescriptor getGroupId() {
|
||||
return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<UsageDescriptor> getProjectUsages(@NotNull Project project) {
|
||||
SvnVcs vcs = SvnVcs.getInstance(project);
|
||||
|
||||
// do not track roots with errors (SvnFileUrlMapping.getErrorRoots()) as they are "not usable" until errors are resolved
|
||||
// skip externals and switched directories as they will have the same format
|
||||
List<RootUrlInfo> roots = ContainerUtil.filter(vcs.getSvnFileUrlMapping().getAllWcInfos(), new Condition<RootUrlInfo>() {
|
||||
@Override
|
||||
public boolean value(RootUrlInfo info) {
|
||||
return info.getType() == null || NestedCopyType.inner.equals(info.getType());
|
||||
}
|
||||
});
|
||||
|
||||
return ContainerUtil.map2Set(roots, new Function<RootUrlInfo, UsageDescriptor>() {
|
||||
@Override
|
||||
public UsageDescriptor fun(RootUrlInfo info) {
|
||||
return new UsageDescriptor(info.getFormat().toString(), 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -587,8 +587,8 @@ public class MergeFromTheirsResolver {
|
||||
|
||||
private boolean getAddedFilesPlaceOption() {
|
||||
final SvnConfiguration configuration = SvnConfiguration.getInstance(myVcs.getProject());
|
||||
boolean add = Boolean.TRUE.equals(configuration.TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE);
|
||||
if (configuration.TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE != null) {
|
||||
boolean add = Boolean.TRUE.equals(configuration.isKeepNewFilesAsIsForTreeConflictMerge());
|
||||
if (configuration.isKeepNewFilesAsIsForTreeConflictMerge() != null) {
|
||||
return add;
|
||||
}
|
||||
if (!containAdditions(myTheirsChanges) && !containAdditions(myTheirsBinaryChanges)) {
|
||||
@@ -606,10 +606,10 @@ public class MergeFromTheirsResolver {
|
||||
if (!value) {
|
||||
if (exitCode == 0) {
|
||||
// yes
|
||||
configuration.TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE = true;
|
||||
configuration.setKeepNewFilesAsIsForTreeConflictMerge(true);
|
||||
}
|
||||
else {
|
||||
configuration.TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE = false;
|
||||
configuration.setKeepNewFilesAsIsForTreeConflictMerge(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public abstract class AbstractSvnUpdatePanel {
|
||||
}
|
||||
|
||||
public void reset(final SvnConfiguration configuration) {
|
||||
getDepthBox().setSelectedItem(configuration.UPDATE_DEPTH);
|
||||
getDepthBox().setSelectedItem(configuration.getUpdateDepth());
|
||||
|
||||
for (FilePath filePath : myRootToPanel.keySet()) {
|
||||
myRootToPanel.get(filePath).reset(configuration);
|
||||
@@ -94,7 +94,7 @@ public abstract class AbstractSvnUpdatePanel {
|
||||
}
|
||||
|
||||
public void apply(final SvnConfiguration configuration) throws ConfigurationException {
|
||||
configuration.UPDATE_DEPTH = getDepthBox().getDepth();
|
||||
configuration.setUpdateDepth(getDepthBox().getDepth());
|
||||
|
||||
for (FilePath filePath : myRootToPanel.keySet()) {
|
||||
final SvnPanel svnPanel = myRootToPanel.get(filePath);
|
||||
|
||||
@@ -47,9 +47,9 @@ public class AutoSvnUpdater extends AbstractCommonUpdateAction {
|
||||
@Override
|
||||
protected void actionPerformed(VcsContext context) {
|
||||
final SvnConfiguration configuration17 = SvnConfiguration.getInstance(myProject);
|
||||
configuration17.FORCE_UPDATE = false;
|
||||
configuration17.UPDATE_LOCK_ON_DEMAND = false;
|
||||
configuration17.UPDATE_DEPTH = SVNDepth.INFINITY;
|
||||
configuration17.setForceUpdate(false);
|
||||
configuration17.setUpdateLockOnDemand(false);
|
||||
configuration17.setUpdateDepth(SVNDepth.INFINITY);
|
||||
final SvnVcs vcs = SvnVcs.getInstance(myProject);
|
||||
for (FilePath root : myRoots) {
|
||||
final UpdateRootInfo info = configuration17.getUpdateRootInfo(root.getIOFile(), vcs);
|
||||
|
||||
@@ -20,15 +20,10 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.update.UpdatedFiles;
|
||||
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.integrate.MergeClient;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
@@ -66,10 +61,10 @@ public class SvnIntegrateEnvironment extends AbstractSvnUpdateIntegrateEnvironme
|
||||
|
||||
@Override
|
||||
protected boolean isDryRun() {
|
||||
return SvnConfiguration.getInstance(myVcs.getProject()).MERGE_DRY_RUN;
|
||||
return SvnConfiguration.getInstance(myVcs.getProject()).isMergeDryRun();
|
||||
}
|
||||
|
||||
private class IntegrateCrawler extends AbstractUpdateIntegrateCrawler {
|
||||
private static class IntegrateCrawler extends AbstractUpdateIntegrateCrawler {
|
||||
|
||||
public IntegrateCrawler(SvnVcs vcs,
|
||||
UpdateEventHandler handler,
|
||||
@@ -83,7 +78,7 @@ public class SvnIntegrateEnvironment extends AbstractSvnUpdateIntegrateEnvironme
|
||||
}
|
||||
|
||||
protected void showProgressMessage(final ProgressIndicator progress, final File root) {
|
||||
if (SvnConfiguration.getInstance(myVcs.getProject()).MERGE_DRY_RUN) {
|
||||
if (SvnConfiguration.getInstance(myVcs.getProject()).isMergeDryRun()) {
|
||||
progress.setText(SvnBundle.message("progress.text.merging.dry.run.changes", root.getAbsolutePath()));
|
||||
}
|
||||
else {
|
||||
@@ -104,9 +99,8 @@ public class SvnIntegrateEnvironment extends AbstractSvnUpdateIntegrateEnvironme
|
||||
SvnTarget source1 = SvnTarget.fromURL(info.getUrl1(), info.getRevision1());
|
||||
SvnTarget source2 = SvnTarget.fromURL(info.getUrl2(), info.getRevision2());
|
||||
|
||||
client.merge(source1, source2, root, svnConfig.UPDATE_DEPTH, svnConfig.MERGE_DIFF_USE_ANCESTRY, svnConfig.MERGE_DRY_RUN, false, false,
|
||||
client.merge(source1, source2, root, svnConfig.getUpdateDepth(), svnConfig.isMergeDiffUseAncestry(), svnConfig.isMergeDryRun(), false, false,
|
||||
svnConfig.getMergeOptions(), myHandler);
|
||||
svnConfig.LAST_MERGED_REVISION = getLastMergedRevision(info.getRevision2(), info.getUrl2());
|
||||
return info.getResultRevision();
|
||||
}
|
||||
|
||||
@@ -115,36 +109,6 @@ public class SvnIntegrateEnvironment extends AbstractSvnUpdateIntegrateEnvironme
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getLastMergedRevision(final SVNRevision rev2, final SVNURL svnURL2) {
|
||||
if (!rev2.isValid() || rev2.isLocal()) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final long number = rev2.getNumber();
|
||||
if (number > 0) {
|
||||
return String.valueOf(number);
|
||||
}
|
||||
else {
|
||||
|
||||
// TODO: Rewrite with command line implementation
|
||||
SVNRepository repos = null;
|
||||
try {
|
||||
repos = myVcs.createRepository(svnURL2.toString());
|
||||
final long latestRev = repos.getLatestRevision();
|
||||
return String.valueOf(latestRev);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
return null;
|
||||
} finally {
|
||||
if (repos != null) {
|
||||
repos.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validateOptions(final Collection<FilePath> roots) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -65,13 +65,13 @@ public class SvnIntegratePanel extends AbstractSvnUpdatePanel{
|
||||
|
||||
public void reset(final SvnConfiguration configuration) {
|
||||
super.reset(configuration);
|
||||
myDryRunCheckbox.setSelected(configuration.MERGE_DRY_RUN);
|
||||
myUseAncestry.setSelected(configuration.MERGE_DIFF_USE_ANCESTRY);
|
||||
myDryRunCheckbox.setSelected(configuration.isMergeDryRun());
|
||||
myUseAncestry.setSelected(configuration.isMergeDiffUseAncestry());
|
||||
}
|
||||
public void apply(final SvnConfiguration configuration) throws ConfigurationException {
|
||||
super.apply(configuration);
|
||||
configuration.MERGE_DRY_RUN = myDryRunCheckbox.isSelected();
|
||||
configuration.MERGE_DIFF_USE_ANCESTRY = myUseAncestry.isSelected();
|
||||
configuration.setMergeDryRun(myDryRunCheckbox.isSelected());
|
||||
configuration.setMergeDiffUseAncestry(myUseAncestry.isSelected());
|
||||
}
|
||||
|
||||
protected JComponent getPanel() {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class SvnUpdateContext implements SequentialUpdatesContext {
|
||||
result = false;
|
||||
}
|
||||
else if (NestedCopyType.external.equals(info.getType())) {
|
||||
result = !myVcs.getSvnConfiguration().IGNORE_EXTERNALS;
|
||||
result = !myVcs.getSvnConfiguration().isIgnoreExternals();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,10 +83,11 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
|
||||
if (isSwitch) {
|
||||
final UpdateClient updateClient = createUpdateClient(configuration, root, true, sourceUrl);
|
||||
myHandler.addToSwitch(root, sourceUrl);
|
||||
rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, updateTo, configuration.getUpdateDepth(),
|
||||
configuration.isForceUpdate(), false);
|
||||
} else {
|
||||
final UpdateClient updateClient = createUpdateClient(configuration, root, false, sourceUrl);
|
||||
rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
rev = updateClient.doUpdate(root, updateTo, configuration.getUpdateDepth(), configuration.isForceUpdate(), false);
|
||||
}
|
||||
|
||||
myPostUpdateFiles.setRevisions(root.getAbsolutePath(), myVcs, new SvnRevisionNumber(SVNRevision.create(rev)));
|
||||
@@ -104,10 +105,10 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
|
||||
final UpdateClient updateClient = factory.createUpdateClient();
|
||||
|
||||
if (! isSwitch) {
|
||||
updateClient.setIgnoreExternals(configuration.IGNORE_EXTERNALS);
|
||||
updateClient.setIgnoreExternals(configuration.isIgnoreExternals());
|
||||
}
|
||||
updateClient.setEventHandler(myHandler);
|
||||
updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND);
|
||||
updateClient.setUpdateLocksOnDemand(configuration.isUpdateLockOnDemand());
|
||||
|
||||
return updateClient;
|
||||
}
|
||||
|
||||
@@ -52,24 +52,24 @@ public class SvnUpdatePanel extends AbstractSvnUpdatePanel {
|
||||
myDepthLabel.setLabelFor(myDepthCombo);
|
||||
|
||||
final SvnConfiguration svnConfiguration = SvnConfiguration.getInstance(myVCS.getProject());
|
||||
myLockOnDemand.setSelected(svnConfiguration.UPDATE_LOCK_ON_DEMAND);
|
||||
myLockOnDemand.setSelected(svnConfiguration.isUpdateLockOnDemand());
|
||||
myLockOnDemand.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
svnConfiguration.UPDATE_LOCK_ON_DEMAND = myLockOnDemand.isSelected();
|
||||
svnConfiguration.setUpdateLockOnDemand(myLockOnDemand.isSelected());
|
||||
}
|
||||
});
|
||||
myForceBox.setSelected(svnConfiguration.FORCE_UPDATE);
|
||||
myIgnoreExternalsCheckBox.setSelected(svnConfiguration.IGNORE_EXTERNALS);
|
||||
myForceBox.setSelected(svnConfiguration.isForceUpdate());
|
||||
myIgnoreExternalsCheckBox.setSelected(svnConfiguration.isIgnoreExternals());
|
||||
myForceBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
svnConfiguration.FORCE_UPDATE = myForceBox.isSelected();
|
||||
svnConfiguration.setForceUpdate(myForceBox.isSelected());
|
||||
}
|
||||
});
|
||||
myIgnoreExternalsCheckBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
svnConfiguration.IGNORE_EXTERNALS = myIgnoreExternalsCheckBox.isSelected();
|
||||
svnConfiguration.setIgnoreExternals(myIgnoreExternalsCheckBox.isSelected());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
@@ -71,9 +70,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -219,7 +216,7 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
|
||||
@Override
|
||||
protected void projectCreated() {
|
||||
if (isUseNativeAcceleration()) {
|
||||
SvnConfiguration.getInstance(myProject).myUseAcceleration = SvnConfiguration.UseAcceleration.commandLine;
|
||||
SvnConfiguration.getInstance(myProject).setUseAcceleration(SvnConfiguration.UseAcceleration.commandLine);
|
||||
SvnApplicationSettings.getInstance().setCommandLinePath(myClientBinaryPath + File.separator + "svn");
|
||||
}
|
||||
}
|
||||
@@ -618,8 +615,8 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
|
||||
|
||||
protected void setNativeAcceleration(final boolean value) {
|
||||
System.out.println("Set native acceleration to " + value);
|
||||
SvnConfiguration.getInstance(myProject).myUseAcceleration =
|
||||
value ? SvnConfiguration.UseAcceleration.commandLine : SvnConfiguration.UseAcceleration.nothing;
|
||||
SvnConfiguration.getInstance(myProject).setUseAcceleration(
|
||||
value ? SvnConfiguration.UseAcceleration.commandLine : SvnConfiguration.UseAcceleration.nothing);
|
||||
SvnApplicationSettings.getInstance().setCommandLinePath(myClientBinaryPath + File.separator + "svn");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,7 +730,7 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myConfiguration.clearAuthenticationDirectory(getProject());
|
||||
clearAuthCache();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -780,6 +780,10 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
SVNJNAUtil.setJNAEnabled(true);
|
||||
}
|
||||
|
||||
private void clearAuthCache() {
|
||||
SvnAuthenticationNotifier.clearAuthenticationDirectory(myConfiguration);
|
||||
}
|
||||
|
||||
public void testPlaintextPromptAndSecondPrompt() throws Exception {
|
||||
SVNJNAUtil.setJNAEnabled(false);
|
||||
|
||||
@@ -875,7 +879,7 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myConfiguration.clearAuthenticationDirectory(getProject());
|
||||
clearAuthCache();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class SvnMergeInfoTest extends Svn17TestCase {
|
||||
myWCInfo = new WCInfo(root, true, SVNDepth.INFINITY);
|
||||
myOneShotMergeInfoHelper = new OneShotMergeInfoHelper(myProject, myWCInfo, myRepoUrl + "/trunk");
|
||||
|
||||
SvnConfiguration.getInstance(myProject).CHECK_NESTED_FOR_QUICK_MERGE = true;
|
||||
SvnConfiguration.getInstance(myProject).setCheckNestedForQuickMerge(true);
|
||||
// AbstractVcs vcsFound = myProjectLevelVcsManager.findVcsByName(SvnVcs.VCS_NAME);
|
||||
// Assert.assertEquals(1, myProjectLevelVcsManager.getRootsUnderVcs(vcsFound).length);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider;
|
||||
import org.junit.Before;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
@@ -143,10 +144,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
|
||||
updateSimple(wc1);
|
||||
@@ -166,10 +166,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
|
||||
updateSimple(wc1);
|
||||
@@ -191,10 +190,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = true;
|
||||
|
||||
updateSimple(wc1);
|
||||
@@ -215,10 +213,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = true;
|
||||
|
||||
updateSimple(wc1);
|
||||
@@ -237,10 +234,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
|
||||
testCommitImpl(wc1);
|
||||
@@ -260,10 +256,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
|
||||
testCommitImpl(wc1);
|
||||
@@ -285,10 +280,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = true;
|
||||
|
||||
testCommitImpl(wc1);
|
||||
@@ -310,10 +304,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = true;
|
||||
myCertificateAnswer = ISVNAuthenticationProvider.ACCEPTED;
|
||||
|
||||
@@ -329,6 +322,11 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
}
|
||||
|
||||
private static void clearAuthCache(@NotNull SvnConfiguration instance) {
|
||||
SvnAuthenticationNotifier.clearAuthenticationDirectory(instance);
|
||||
instance.clearRuntimeStorage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedSSLCommit() throws Exception {
|
||||
final File wc1 = testCheckoutImpl(ourHTTPS_URL);
|
||||
@@ -336,10 +334,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCertificateAnswer = ISVNAuthenticationProvider.ACCEPTED;
|
||||
|
||||
@@ -354,8 +351,7 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
//------------
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
mySaveCredentials = true;
|
||||
myCertificateAnswer = ISVNAuthenticationProvider.ACCEPTED_TEMPORARY;
|
||||
|
||||
@@ -373,10 +369,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = true;
|
||||
|
||||
testCommitImpl(wc1);
|
||||
@@ -395,10 +390,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCredentialsCorrect = false;
|
||||
|
||||
@@ -419,10 +413,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCredentialsCorrect = false;
|
||||
|
||||
@@ -446,10 +439,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCertificateAnswer = ISVNAuthenticationProvider.REJECTED;
|
||||
|
||||
@@ -480,10 +472,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCreds, myCredentialsAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCredentialsCorrect = false;
|
||||
myCancelAuth = true;
|
||||
@@ -507,10 +498,9 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
|
||||
//Assert.assertEquals(myExpectedCert, myCertificateAskedInteractivelyCount);
|
||||
|
||||
final SvnConfiguration instance = SvnConfiguration.getInstance(myProject);
|
||||
instance.clearAuthenticationDirectory(myProject);
|
||||
instance.clearRuntimeStorage();
|
||||
clearAuthCache(instance);
|
||||
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.myUseAcceleration);
|
||||
Assert.assertEquals(SvnConfiguration.UseAcceleration.commandLine, instance.getUseAcceleration());
|
||||
mySaveCredentials = false;
|
||||
myCredentialsCorrect = false;
|
||||
myCancelAuth = true;
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationNotifier;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.auth.ProviderType;
|
||||
@@ -733,7 +734,7 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myConfiguration.clearAuthenticationDirectory(getProject());
|
||||
clearAuthCache();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -783,6 +784,10 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
SVNJNAUtil.setJNAEnabled(true);
|
||||
}
|
||||
|
||||
private void clearAuthCache() {
|
||||
SvnAuthenticationNotifier.clearAuthenticationDirectory(myConfiguration);
|
||||
}
|
||||
|
||||
public void testPlaintextPromptAndSecondPrompt() throws Exception {
|
||||
SVNJNAUtil.setJNAEnabled(false);
|
||||
|
||||
@@ -878,7 +883,7 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myConfiguration.clearAuthenticationDirectory(getProject());
|
||||
clearAuthCache();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class SvnMergeInfoTest extends Svn16TestCase {
|
||||
myWCInfo = new WCInfo(root, true, SVNDepth.INFINITY);
|
||||
myOneShotMergeInfoHelper = new OneShotMergeInfoHelper(myProject, myWCInfo, myRepoUrl + "/trunk");
|
||||
|
||||
SvnConfiguration.getInstance(myProject).CHECK_NESTED_FOR_QUICK_MERGE = true;
|
||||
SvnConfiguration.getInstance(myProject).setCheckNestedForQuickMerge(true);
|
||||
// AbstractVcs vcsFound = myProjectLevelVcsManager.findVcsByName(SvnVcs.VCS_NAME);
|
||||
// Assert.assertEquals(1, myProjectLevelVcsManager.getRootsUnderVcs(vcsFound).length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user