mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'svn_18_3'
This commit is contained in:
@@ -310,6 +310,10 @@ public class VcsUtil {
|
||||
return getFilePath(new File(path));
|
||||
}
|
||||
|
||||
public static FilePath getFilePath(@NotNull VirtualFile file) {
|
||||
return VcsContextFactory.SERVICE.getInstance().createFilePathOn(file);
|
||||
}
|
||||
|
||||
public static FilePath getFilePath(File file) {
|
||||
return VcsContextFactory.SERVICE.getInstance().createFilePathOn(file);
|
||||
}
|
||||
|
||||
@@ -152,12 +152,6 @@ public class SvnUtil {
|
||||
return info != null && info.getURL() != null ? info.getURL().toString() : null;
|
||||
}
|
||||
|
||||
public static Map<String, File> getLocationInfoForModule(final SvnVcs vcs, File path, ProgressIndicator progress) {
|
||||
final LocationsCrawler crawler = new LocationsCrawler(vcs);
|
||||
crawlWCRoots(vcs.getProject(), path, crawler, progress);
|
||||
return crawler.getLocationInfos();
|
||||
}
|
||||
|
||||
public static void doLockFiles(Project project, final SvnVcs activeVcs, @NotNull final File[] ioFiles) throws VcsException {
|
||||
final String lockMessage;
|
||||
final boolean force;
|
||||
@@ -414,35 +408,6 @@ public class SvnUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class LocationsCrawler implements SvnWCRootCrawler {
|
||||
private final SvnVcs myVcs;
|
||||
private final Map<String, File> myLocations;
|
||||
|
||||
public LocationsCrawler(SvnVcs vcs) {
|
||||
myVcs = vcs;
|
||||
myLocations = new HashMap<String, File>();
|
||||
}
|
||||
|
||||
public Map<String, File> getLocationInfos() {
|
||||
return Collections.unmodifiableMap(myLocations);
|
||||
}
|
||||
|
||||
public void handleWorkingCopyRoot(File root, ProgressIndicator progress) {
|
||||
String oldText = null;
|
||||
if (progress != null) {
|
||||
oldText = progress.getText();
|
||||
progress.setText(SvnBundle.message("progress.text.discovering.location", root.getAbsolutePath()));
|
||||
}
|
||||
SVNInfo info = myVcs.getInfo(root);
|
||||
if (info != null && info.getURL() != null) {
|
||||
myLocations.put(info.getURL().toString(), info.getFile());
|
||||
}
|
||||
if (progress != null) {
|
||||
progress.setText(oldText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getRepositoryUUID(final SvnVcs vcs, final File file) {
|
||||
final SVNInfo info = vcs.getInfo(file);
|
||||
@@ -569,6 +534,7 @@ public class SvnUtil {
|
||||
return repository.hasCapability(SVNCapability.MERGE_INFO);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
// TODO: Exception is thrown when url just not exist (was deleted, for instance) => and false is returned which seems not to be correct.
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@@ -739,6 +705,23 @@ public class SvnUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRelativeUrl(@NotNull String parentUrl, @NotNull String childUrl) {
|
||||
return FileUtilRt.getRelativePath(parentUrl, childUrl, '/', true);
|
||||
}
|
||||
|
||||
public static String getRelativePath(@NotNull String parentPath, @NotNull String childPath) {
|
||||
return FileUtilRt.getRelativePath(FileUtil.toSystemIndependentName(parentPath), FileUtil.toSystemIndependentName(childPath), '/');
|
||||
}
|
||||
|
||||
public static String ensureStartSlash(@NotNull String path) {
|
||||
return StringUtil.startsWithChar(path, '/') ? path : '/' + path;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String join(@NotNull final String... parts) {
|
||||
return StringUtil.join(parts, "/");
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -764,9 +747,7 @@ public class SvnUtil {
|
||||
@Nullable final SVNRevision revision,
|
||||
@Nullable final SVNRevision pegRevision)
|
||||
throws VcsException {
|
||||
ClientFactory factory = target.isFile() ? vcs.getFactory(target.getFile()) : vcs.getFactory();
|
||||
|
||||
return factory.createContentClient().getContent(target, revision, pegRevision);
|
||||
return vcs.getFactory(target).createContentClient().getContent(target, revision, pegRevision);
|
||||
}
|
||||
|
||||
public static boolean hasDefaultPort(@NotNull SVNURL result) {
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.commandLine;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.util.LineSeparator;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -38,6 +40,9 @@ import java.util.regex.Matcher;
|
||||
*/
|
||||
public class SvnBindException extends VcsException {
|
||||
|
||||
public static final int ERROR_BASE = 120000;
|
||||
public static final int CATEGORY_SIZE = 5000;
|
||||
|
||||
private Map<Integer, String> errors = new HashMap<Integer, String>();
|
||||
|
||||
public SvnBindException(String message) {
|
||||
@@ -67,6 +72,21 @@ public class SvnBindException extends VcsException {
|
||||
return errors.containsKey(error.getCode());
|
||||
}
|
||||
|
||||
public boolean containsCategory(int category) {
|
||||
final int categoryCode = getCategoryCode(category);
|
||||
|
||||
return ContainerUtil.exists(errors.keySet(), new Condition<Integer>() {
|
||||
@Override
|
||||
public boolean value(Integer code) {
|
||||
return getCategoryCode(code) == categoryCode;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static int getCategoryCode(int category) {
|
||||
return (category - ERROR_BASE) / CATEGORY_SIZE;
|
||||
}
|
||||
|
||||
private void parseErrors(@NotNull String message) {
|
||||
Matcher matcher = SvnUtil.ERROR_PATTERN.matcher(message);
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.actions.VcsContextFactory;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangesUtil;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
@@ -47,6 +46,7 @@ import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -57,7 +57,6 @@ import org.jetbrains.idea.svn.dialogs.browser.*;
|
||||
import org.jetbrains.idea.svn.dialogs.browserCache.Expander;
|
||||
import org.jetbrains.idea.svn.dialogs.browserCache.KeepingExpandedExpander;
|
||||
import org.jetbrains.idea.svn.dialogs.browserCache.SyntheticWorker;
|
||||
import org.jetbrains.idea.svn.history.SvnHistoryProvider;
|
||||
import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
|
||||
import org.jetbrains.idea.svn.status.SvnDiffEditor;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
@@ -355,9 +354,10 @@ public class RepositoryBrowserDialog extends DialogWrapper {
|
||||
}
|
||||
boolean isDirectory = node.getUserObject() instanceof SVNURL ||
|
||||
(node.getSVNDirEntry() != null && node.getSVNDirEntry().getKind() == SVNNodeKind.DIR);
|
||||
AbstractVcsHelper.getInstance(myProject).showFileHistory(new SvnHistoryProvider(myVCS),
|
||||
VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(node.getURL().toDecodedString(), isDirectory),
|
||||
myVCS, node.getURL().toDecodedString());
|
||||
String url = node.getURL().toDecodedString();
|
||||
|
||||
AbstractVcsHelper.getInstance(myProject)
|
||||
.showFileHistory(myVCS.getVcsHistoryProvider(), VcsUtil.getFilePathOnNonLocal(url, isDirectory), myVCS, url);
|
||||
node.reload(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -57,7 +57,7 @@ public class BunchFactory {
|
||||
myYoungest = -1;
|
||||
}
|
||||
|
||||
public List<Fragment> goBack(final int bunchSize, final Ref<Boolean> myYoungestRead) throws SVNException {
|
||||
public List<Fragment> goBack(final int bunchSize, final Ref<Boolean> myYoungestRead) throws VcsException {
|
||||
execute(bunchSize);
|
||||
myYoungestRead.set(myLiveProvider.isEarliestRevisionWasAccessed());
|
||||
return new ArrayList<Fragment>(myResult);
|
||||
@@ -78,7 +78,7 @@ public class BunchFactory {
|
||||
myYoungest = subList.get(subList.size() - 1).getNumber();
|
||||
}
|
||||
|
||||
private void execute(final int bunchSize) throws SVNException {
|
||||
private void execute(final int bunchSize) throws VcsException {
|
||||
myBunchSize = bunchSize;
|
||||
myResult.clear();
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
|
||||
public interface BunchProvider {
|
||||
long getEarliestRevision();
|
||||
@@ -29,6 +29,6 @@ public interface BunchProvider {
|
||||
*/
|
||||
@Nullable
|
||||
Fragment getEarliestBunchInInterval(final long earliestRevision, final long oldestRevision, final int desirableSize,
|
||||
final boolean includeYoungest, final boolean includeOldest) throws SVNException;
|
||||
final boolean includeYoungest, final boolean includeOldest) throws VcsException;
|
||||
boolean isEmpty();
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.committed.ChangesBunch;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -86,7 +86,7 @@ public abstract class CachedProvider implements BunchProvider {
|
||||
|
||||
@Nullable
|
||||
public Fragment getEarliestBunchInInterval(final long earliestRevision, final long oldestRevision, final int desirableSize,
|
||||
final boolean includeYoungest, final boolean includeOldest) throws SVNException {
|
||||
final boolean includeYoungest, final boolean includeOldest) throws VcsException {
|
||||
if ((earliestRevision > getEarliestRevision()) || (earliestRevision == -1)) {
|
||||
if (myAlreadyReaded == null) {
|
||||
return null;
|
||||
|
||||
@@ -7,11 +7,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.commandLine.CommandExecutor;
|
||||
import org.jetbrains.idea.svn.commandLine.CommandUtil;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
|
||||
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
@@ -52,7 +50,7 @@ public class CmdHistoryClient extends BaseSvnClient implements HistoryClient {
|
||||
parseOutput(command, handler);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -54,7 +55,7 @@ public class LiveProvider implements BunchProvider {
|
||||
}
|
||||
|
||||
public Fragment getEarliestBunchInInterval(final long earliestRevision, final long oldestRevision, final int desirableSize,
|
||||
final boolean includeYoungest, final boolean includeOldest) throws SVNException {
|
||||
final boolean includeYoungest, final boolean includeOldest) throws VcsException {
|
||||
return getEarliestBunchInIntervalImpl(earliestRevision, oldestRevision, desirableSize, includeYoungest, includeOldest, earliestRevision);
|
||||
}
|
||||
|
||||
@@ -62,14 +63,14 @@ public class LiveProvider implements BunchProvider {
|
||||
final long oldestRevision,
|
||||
final int desirableSize,
|
||||
final boolean includeYoungest,
|
||||
final boolean includeOldest, final long earliestToTake) throws SVNException {
|
||||
final boolean includeOldest, final long earliestToTake) throws VcsException {
|
||||
if ((myEarliestRevisionWasAccessed) || ((oldestRevision == myYoungestRevision) && ((! includeYoungest) || (! includeOldest)))) {
|
||||
return null;
|
||||
}
|
||||
final SVNRevision youngRevision = (earliestRevision == -1) ? SVNRevision.HEAD : SVNRevision.create(earliestRevision);
|
||||
|
||||
final Ref<List<CommittedChangeList>> refToList = new Ref<List<CommittedChangeList>>();
|
||||
final Ref<SVNException> exceptionRef = new Ref<SVNException>();
|
||||
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
|
||||
|
||||
final Runnable loader = new Runnable() {
|
||||
public void run() {
|
||||
@@ -77,7 +78,7 @@ public class LiveProvider implements BunchProvider {
|
||||
refToList.set(
|
||||
myLoader.loadInterval(youngRevision, SVNRevision.create(oldestRevision), desirableSize, includeYoungest, includeOldest));
|
||||
}
|
||||
catch (SVNException e) {
|
||||
catch (VcsException e) {
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
}
|
||||
@@ -98,13 +99,13 @@ public class LiveProvider implements BunchProvider {
|
||||
}, SvnBundle.message("progress.live.provider.loading.revisions.text"), false, myVcs.getProject());
|
||||
}
|
||||
|
||||
if (exceptionRef.get() != null) {
|
||||
final SVNException e = exceptionRef.get();
|
||||
if (SVNErrorCode.FS_NOT_FOUND.equals(e.getErrorMessage().getErrorCode())) {
|
||||
if (!exceptionRef.isNull()) {
|
||||
final VcsException e = exceptionRef.get();
|
||||
if (isElementNotFound(e)) {
|
||||
// occurs when target URL is deleted in repository
|
||||
// try to find latest existent revision. expensive ...
|
||||
final LatestExistentSearcher searcher = new LatestExistentSearcher(oldestRevision, myYoungestRevision, (oldestRevision != 0),
|
||||
myVcs, SVNURL.parseURIEncoded(myLocation.getURL()));
|
||||
myVcs, myLocation.toSvnUrl());
|
||||
final long existent = searcher.getLatestExistent();
|
||||
if ((existent == -1) || (existent == earliestRevision)) {
|
||||
myEarliestRevisionWasAccessed = true;
|
||||
@@ -132,6 +133,10 @@ public class LiveProvider implements BunchProvider {
|
||||
return new Fragment(Origin.LIVE, list, true, true, null);
|
||||
}
|
||||
|
||||
private static boolean isElementNotFound(@NotNull VcsException e) {
|
||||
return e instanceof SvnBindException && ((SvnBindException)e).contains(SVNErrorCode.FS_NOT_FOUND);
|
||||
}
|
||||
|
||||
public boolean isEarliestRevisionWasAccessed() {
|
||||
return myEarliestRevisionWasAccessed;
|
||||
}
|
||||
|
||||
@@ -1,64 +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.history;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.actions.VcsContextFactory;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LocationDetector {
|
||||
private final Map<String, File> myMap;
|
||||
|
||||
public LocationDetector(final SvnVcs vcs) {
|
||||
myMap = new HashMap<String, File>();
|
||||
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
final VirtualFile[] roots = ProjectLevelVcsManager.getInstance(vcs.getProject()).getRootsUnderVcs(vcs);
|
||||
|
||||
for (VirtualFile root : roots) {
|
||||
myMap.putAll(SvnUtil.getLocationInfoForModule(vcs, new File(root.getPath()), progress));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FilePath crawlForPath(final String fullPath, final NotNullFunction<File, Boolean> detector) {
|
||||
for (Map.Entry<String, File> entry : myMap.entrySet()) {
|
||||
final String url = entry.getKey();
|
||||
if (SVNPathUtil.isAncestor(url, fullPath)) {
|
||||
return filePathByUrlAndPath(fullPath, url, entry.getValue().getAbsolutePath(), detector);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static FilePath filePathByUrlAndPath(final String longPath, final String parentUrl, final String parentPath, final NotNullFunction<File, Boolean> detector) {
|
||||
final String relPath = longPath.substring(parentUrl.length());
|
||||
final File localFile = new File(parentPath, relPath);
|
||||
return VcsContextFactory.SERVICE.getInstance().createFilePathOn(localFile, detector);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class MergeSourceHierarchyBuilder implements ThrowableConsumer<Pair<SVNLogEntry, Integer>, SVNException> {
|
||||
|
||||
private TreeStructureNode<SVNLogEntry> myCurrentHierarchy;
|
||||
@NotNull private final Consumer<TreeStructureNode<SVNLogEntry>> myConsumer;
|
||||
|
||||
public MergeSourceHierarchyBuilder(@NotNull Consumer<TreeStructureNode<SVNLogEntry>> consumer) {
|
||||
myConsumer = consumer;
|
||||
}
|
||||
|
||||
public void consume(Pair<SVNLogEntry, Integer> svnLogEntryIntegerPair) throws SVNException {
|
||||
final SVNLogEntry logEntry = svnLogEntryIntegerPair.getFirst();
|
||||
final Integer mergeLevel = svnLogEntryIntegerPair.getSecond();
|
||||
|
||||
if (mergeLevel < 0) {
|
||||
if (myCurrentHierarchy != null) {
|
||||
myConsumer.consume(myCurrentHierarchy);
|
||||
}
|
||||
if (logEntry.hasChildren()) {
|
||||
myCurrentHierarchy = new TreeStructureNode<SVNLogEntry>(logEntry);
|
||||
} else {
|
||||
// just pass
|
||||
myCurrentHierarchy = null;
|
||||
myConsumer.consume(new TreeStructureNode<SVNLogEntry>(logEntry));
|
||||
}
|
||||
} else {
|
||||
addToLevel(myCurrentHierarchy, logEntry, mergeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
if (myCurrentHierarchy != null) {
|
||||
myConsumer.consume(myCurrentHierarchy);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToLevel(final TreeStructureNode<SVNLogEntry> tree, final SVNLogEntry entry, final int left) {
|
||||
assert tree != null;
|
||||
if (left == 0) {
|
||||
tree.add(entry);
|
||||
} else {
|
||||
final List<TreeStructureNode<SVNLogEntry>> children = tree.getChildren();
|
||||
assert ! children.isEmpty();
|
||||
addToLevel(children.get(children.size() - 1), entry, left - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.vcs.changes.committed.ChangeListFilteringStrategy;
|
||||
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
|
||||
import icons.SvnIcons;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class ShowHideMergePanelAction extends ToggleAction {
|
||||
|
||||
private final DecoratorManager myManager;
|
||||
private final ChangeListFilteringStrategy myStrategy;
|
||||
private boolean myIsSelected;
|
||||
|
||||
public ShowHideMergePanelAction(final DecoratorManager manager, final ChangeListFilteringStrategy strategy) {
|
||||
myManager = manager;
|
||||
myStrategy = strategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
presentation.setIcon(SvnIcons.ShowIntegratedFrom);
|
||||
presentation.setText(SvnBundle.message("committed.changes.action.enable.merge.highlighting"));
|
||||
presentation.setDescription(SvnBundle.message("committed.changes.action.enable.merge.highlighting.description.text"));
|
||||
}
|
||||
|
||||
public boolean isSelected(final AnActionEvent e) {
|
||||
return myIsSelected;
|
||||
}
|
||||
|
||||
public void setSelected(final AnActionEvent e, final boolean state) {
|
||||
myIsSelected = state;
|
||||
if (state) {
|
||||
myManager.setFilteringStrategy(myStrategy);
|
||||
} else {
|
||||
myManager.removeFilteringStrategy(myStrategy.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
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.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SingleCommittedListProvider {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(SingleCommittedListProvider.class);
|
||||
|
||||
@NotNull private final SvnVcs myVcs;
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final VirtualFile file;
|
||||
@NotNull private final VcsRevisionNumber number;
|
||||
private SvnChangeList[] changeList;
|
||||
private SVNRevision revisionBefore;
|
||||
private SVNURL repositoryUrl;
|
||||
private SVNURL svnRootUrl;
|
||||
private SvnRepositoryLocation svnRootLocation;
|
||||
private String repositoryRelativeUrl;
|
||||
private FilePath filePath;
|
||||
|
||||
public SingleCommittedListProvider(@NotNull SvnVcs vcs, @NotNull VirtualFile file, @NotNull VcsRevisionNumber number) {
|
||||
myVcs = vcs;
|
||||
myProject = vcs.getProject();
|
||||
this.file = file;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Pair<SvnChangeList, FilePath> run() throws VcsException {
|
||||
Pair<SvnChangeList, FilePath> result = null;
|
||||
|
||||
if (setup()) {
|
||||
calculate();
|
||||
result = Pair.create(changeList[0], filePath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean setup() {
|
||||
boolean result = false;
|
||||
|
||||
RootUrlInfo rootUrlInfo = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(new File(file.getPath()));
|
||||
if (rootUrlInfo != null) {
|
||||
changeList = new SvnChangeList[1];
|
||||
revisionBefore = ((SvnRevisionNumber)number).getRevision();
|
||||
repositoryUrl = rootUrlInfo.getRepositoryUrlUrl();
|
||||
svnRootUrl = rootUrlInfo.getAbsoluteUrlAsUrl();
|
||||
svnRootLocation = new SvnRepositoryLocation(rootUrlInfo.getAbsoluteUrl());
|
||||
repositoryRelativeUrl = SvnUtil.ensureStartSlash(SvnUtil.join(
|
||||
SvnUtil.getRelativeUrl(repositoryUrl.toDecodedString(), svnRootUrl.toDecodedString()),
|
||||
SvnUtil.getRelativePath(rootUrlInfo.getPath(), file.getPath())));
|
||||
|
||||
filePath = VcsUtil.getFilePath(file);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void calculate() throws VcsException {
|
||||
// TODO: Seems that filePath detection could be replaced with "svn info -r <revisionBefore>" - and not call
|
||||
// TODO: "svn log -r HEAD:<revisionBefore>" and track copies manually (which also is not correct for all cases).
|
||||
if (!searchForUrl(svnRootUrl) && !(hasAccess(repositoryUrl) && searchForUrl(repositoryUrl))) {
|
||||
filePath = searchFromHead(svnRootUrl);
|
||||
}
|
||||
else {
|
||||
if (changeList[0].getChanges().size() == 1) {
|
||||
final ContentRevision afterRevision = changeList[0].getChanges().iterator().next().getAfterRevision();
|
||||
|
||||
filePath = afterRevision != null ? afterRevision.getFile() : filePath;
|
||||
}
|
||||
else {
|
||||
final Change targetChange = changeList[0].getByPath(repositoryRelativeUrl);
|
||||
|
||||
filePath = targetChange == null ? searchFromHead(svnRootUrl) : filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasAccess(@NotNull SVNURL url) {
|
||||
return SvnAuthenticationNotifier.passiveValidation(myProject, url);
|
||||
}
|
||||
|
||||
// return changed path, if any
|
||||
private FilePath searchFromHead(@NotNull SVNURL url) throws VcsException {
|
||||
final SvnCopyPathTracker pathTracker = new SvnCopyPathTracker(repositoryUrl.toDecodedString(), repositoryRelativeUrl);
|
||||
SvnTarget target = SvnTarget.fromURL(url);
|
||||
|
||||
myVcs.getFactory(target).createHistoryClient().doLog(target, SVNRevision.HEAD, revisionBefore, false, true, false, 0, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
checkDisposed();
|
||||
// date could be null for lists where there are paths that user has no rights to observe
|
||||
if (logEntry.getDate() != null) {
|
||||
pathTracker.accept(logEntry);
|
||||
if (logEntry.getRevision() == revisionBefore.getNumber()) {
|
||||
changeList[0] = createChangeList(logEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
FilePath path = pathTracker.getFilePath(myVcs);
|
||||
return path == null ? filePath : path;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SvnChangeList createChangeList(@NotNull SVNLogEntry logEntry) {
|
||||
return new SvnChangeList(myVcs, svnRootLocation, logEntry, repositoryUrl.toDecodedString());
|
||||
}
|
||||
|
||||
private void checkDisposed() {
|
||||
if (myProject.isDisposed()) {
|
||||
throw new ProcessCanceledException();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean searchForUrl(@NotNull SVNURL url) throws VcsException {
|
||||
ISVNLogEntryHandler handler = new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
checkDisposed();
|
||||
// date could be null for lists where there are paths that user has no rights to observe
|
||||
if (logEntry.getDate() != null) {
|
||||
changeList[0] = createChangeList(logEntry);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SvnTarget target = SvnTarget.fromURL(url);
|
||||
try {
|
||||
myVcs.getFactory(target).createHistoryClient().doLog(target, revisionBefore, revisionBefore, false, true, false, 1, null, handler);
|
||||
}
|
||||
catch (SvnBindException e) {
|
||||
LOG.info(e);
|
||||
if (!e.containsCategory(SVNErrorCode.FS_CATEGORY)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return changeList[0] != null;
|
||||
}
|
||||
}
|
||||
+148
-459
@@ -16,19 +16,20 @@
|
||||
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.committed.*;
|
||||
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsConfigurationChangeListener;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
|
||||
@@ -38,23 +39,19 @@ import com.intellij.util.AsynchConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import icons.SvnIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.actions.ConfigureBranchesAction;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNLogClient;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@@ -66,17 +63,15 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
private final SvnVcs myVcs;
|
||||
private final MessageBusConnection myConnection;
|
||||
private MergeInfoUpdatesListener myMergeInfoUpdatesListener;
|
||||
private final MyZipper myZipper;
|
||||
private final SvnCommittedListsZipper myZipper;
|
||||
|
||||
public final static int VERSION_WITH_COPY_PATHS_ADDED = 2;
|
||||
public final static int VERSION_WITH_REPLACED_PATHS = 3;
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.SvnCommittedChangesProvider");
|
||||
|
||||
public SvnCommittedChangesProvider(final Project project) {
|
||||
myProject = project;
|
||||
myVcs = SvnVcs.getInstance(myProject);
|
||||
myZipper = new MyZipper();
|
||||
myZipper = new SvnCommittedListsZipper(myVcs);
|
||||
|
||||
myConnection = myProject.getMessageBus().connect();
|
||||
|
||||
@@ -110,17 +105,12 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
|
||||
@Nullable
|
||||
public RepositoryLocation getLocationFor(final FilePath root) {
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
final String url = SvnUtil.getExactLocation(myVcs, root.getIOFile());
|
||||
return url == null ? null : new SvnRepositoryLocation(url);
|
||||
}
|
||||
|
||||
public RepositoryLocation getLocationFor(final FilePath root, final String repositoryPath) {
|
||||
if (repositoryPath == null) {
|
||||
return getLocationFor(root);
|
||||
}
|
||||
|
||||
return new SvnLoadingRepositoryLocation(repositoryPath, myVcs);
|
||||
return repositoryPath == null ? getLocationFor(root) : new SvnRepositoryLocation(repositoryPath);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -128,49 +118,6 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
return myZipper;
|
||||
}
|
||||
|
||||
private class MyZipper implements VcsCommittedListsZipper {
|
||||
public Pair<List<RepositoryLocationGroup>, List<RepositoryLocation>> groupLocations(final List<RepositoryLocation> in) {
|
||||
final List<RepositoryLocationGroup> groups = new ArrayList<RepositoryLocationGroup>();
|
||||
final List<RepositoryLocation> singles = new ArrayList<RepositoryLocation>();
|
||||
|
||||
final MultiMap<SVNURL, RepositoryLocation> map = new MultiMap<SVNURL, RepositoryLocation>();
|
||||
|
||||
for (RepositoryLocation location : in) {
|
||||
final SvnRepositoryLocation svnLocation = (SvnRepositoryLocation) location;
|
||||
final String url = svnLocation.getURL();
|
||||
|
||||
final SVNURL root = SvnUtil.getRepositoryRoot(myVcs, url);
|
||||
if (root == null) {
|
||||
// should not occur
|
||||
LOG.info("repository root not found for location:"+ location.toPresentableString());
|
||||
singles.add(location);
|
||||
} else {
|
||||
map.putValue(root, svnLocation);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<SVNURL> keys = map.keySet();
|
||||
for (SVNURL key : keys) {
|
||||
final Collection<RepositoryLocation> repositoryLocations = map.get(key);
|
||||
if (repositoryLocations.size() == 1) {
|
||||
singles.add(repositoryLocations.iterator().next());
|
||||
} else {
|
||||
final SvnRepositoryLocationGroup group = new SvnRepositoryLocationGroup(key, repositoryLocations);
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
return new Pair<List<RepositoryLocationGroup>, List<RepositoryLocation>>(groups, singles);
|
||||
}
|
||||
|
||||
public CommittedChangeList zip(final RepositoryLocationGroup group, final List<CommittedChangeList> lists) {
|
||||
return new SvnChangeList(lists, new SvnRepositoryLocation(group.toPresentableString()));
|
||||
}
|
||||
|
||||
public long getNumber(final CommittedChangeList list) {
|
||||
return list.getNumber();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCommittedChanges(ChangeBrowserSettings settings,
|
||||
RepositoryLocation location,
|
||||
int maxCount,
|
||||
@@ -178,30 +125,10 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
throws VcsException {
|
||||
try {
|
||||
final SvnRepositoryLocation svnLocation = (SvnRepositoryLocation) location;
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText(SvnBundle.message("progress.text.changes.collecting.changes"));
|
||||
progress.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", location));
|
||||
}
|
||||
|
||||
// TODO: Implement this with command line
|
||||
final String repositoryRoot;
|
||||
SVNRepository repository = null;
|
||||
try {
|
||||
repository = myVcs.createRepository(svnLocation.getURL());
|
||||
repositoryRoot = repository.getRepositoryRoot(true).toString();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
} finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
final String repositoryRoot = getRepositoryRoot(svnLocation);
|
||||
final ChangeBrowserSettings.Filter filter = settings.createFilter();
|
||||
|
||||
getCommittedChangesImpl(settings, svnLocation.getURL(), new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
getCommittedChangesImpl(settings, svnLocation, new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
public void consume(final SVNLogEntry svnLogEntry) {
|
||||
final SvnChangeList cl = new SvnChangeList(myVcs, svnLocation, svnLogEntry, repositoryRoot);
|
||||
if (filter.accepts(cl)) {
|
||||
@@ -218,29 +145,9 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
public List<SvnChangeList> getCommittedChanges(ChangeBrowserSettings settings, final RepositoryLocation location, final int maxCount) throws VcsException {
|
||||
final SvnRepositoryLocation svnLocation = (SvnRepositoryLocation) location;
|
||||
final ArrayList<SvnChangeList> result = new ArrayList<SvnChangeList>();
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText(SvnBundle.message("progress.text.changes.collecting.changes"));
|
||||
progress.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", location));
|
||||
}
|
||||
final String repositoryRoot = getRepositoryRoot(svnLocation);
|
||||
|
||||
final String repositoryRoot;
|
||||
// TODO: Implement this with command line
|
||||
SVNRepository repository = null;
|
||||
try {
|
||||
repository = myVcs.createRepository(svnLocation.getURL());
|
||||
repositoryRoot = repository.getRepositoryRoot(true).toString();
|
||||
repository.closeSession();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
} finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
getCommittedChangesImpl(settings, svnLocation.getURL(), new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
getCommittedChangesImpl(settings, svnLocation, new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
public void consume(final SVNLogEntry svnLogEntry) {
|
||||
result.add(new SvnChangeList(myVcs, svnLocation, svnLogEntry, repositoryRoot));
|
||||
}
|
||||
@@ -254,14 +161,40 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
final PairConsumer<SvnChangeList, TreeStructureNode<SVNLogEntry>> finalConsumer)
|
||||
throws VcsException {
|
||||
final SvnRepositoryLocation svnLocation = (SvnRepositoryLocation) location;
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText(SvnBundle.message("progress.text.changes.collecting.changes"));
|
||||
progress.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", location));
|
||||
}
|
||||
// TODO: Rewrite this without using SVNKit
|
||||
final String repositoryRoot = getRepositoryRoot(svnLocation);
|
||||
|
||||
final MergeSourceHierarchyBuilder builder = new MergeSourceHierarchyBuilder(new Consumer<TreeStructureNode<SVNLogEntry>>() {
|
||||
public void consume(TreeStructureNode<SVNLogEntry> node) {
|
||||
finalConsumer.consume(new SvnChangeList(myVcs, svnLocation, node.getMe(), repositoryRoot), node);
|
||||
}
|
||||
});
|
||||
final SvnMergeSourceTracker mergeSourceTracker = new SvnMergeSourceTracker(new ThrowableConsumer<Pair<SVNLogEntry, Integer>, SVNException>() {
|
||||
public void consume(Pair<SVNLogEntry, Integer> svnLogEntryIntegerPair) throws SVNException {
|
||||
builder.consume(svnLogEntryIntegerPair);
|
||||
}
|
||||
});
|
||||
|
||||
getCommittedChangesImpl(settings, svnLocation, new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
public void consume(final SVNLogEntry svnLogEntry) {
|
||||
try {
|
||||
mergeSourceTracker.consume(svnLogEntry);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new RuntimeException(e);
|
||||
// will not occur actually but anyway never eat them
|
||||
}
|
||||
}
|
||||
}, true, false);
|
||||
|
||||
builder.finish();
|
||||
}
|
||||
|
||||
private String getRepositoryRoot(@NotNull SvnRepositoryLocation svnLocation) throws VcsException {
|
||||
// TODO: Implement this with command line
|
||||
|
||||
final String repositoryRoot;
|
||||
SVNRepository repository = null;
|
||||
|
||||
try {
|
||||
repository = myVcs.createRepository(svnLocation.getURL());
|
||||
repositoryRoot = repository.getRepositoryRoot(true).toString();
|
||||
@@ -273,154 +206,124 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
final MergeTrackerProxy proxy = new MergeTrackerProxy(new Consumer<TreeStructureNode<SVNLogEntry>>() {
|
||||
public void consume(TreeStructureNode<SVNLogEntry> node) {
|
||||
finalConsumer.consume(new SvnChangeList(myVcs, svnLocation, node.getMe(), repositoryRoot), node);
|
||||
}
|
||||
});
|
||||
final SvnMergeSourceTracker mergeSourceTracker = new SvnMergeSourceTracker(new ThrowableConsumer<Pair<SVNLogEntry, Integer>, SVNException>() {
|
||||
public void consume(Pair<SVNLogEntry, Integer> svnLogEntryIntegerPair) throws SVNException {
|
||||
proxy.consume(svnLogEntryIntegerPair);
|
||||
}
|
||||
});
|
||||
|
||||
getCommittedChangesImpl(settings, svnLocation.getURL(), new String[]{""}, maxCount, new Consumer<SVNLogEntry>() {
|
||||
public void consume(final SVNLogEntry svnLogEntry) {
|
||||
try {
|
||||
mergeSourceTracker.consume(svnLogEntry);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new RuntimeException(e);
|
||||
// will not occur actually but anyway never eat them
|
||||
}
|
||||
}
|
||||
}, true, false);
|
||||
|
||||
proxy.finish();
|
||||
return repositoryRoot;
|
||||
}
|
||||
|
||||
|
||||
private static class MergeTrackerProxy implements ThrowableConsumer<Pair<SVNLogEntry, Integer>, SVNException> {
|
||||
private TreeStructureNode<SVNLogEntry> myCurrentHierarchy;
|
||||
private final Consumer<TreeStructureNode<SVNLogEntry>> myConsumer;
|
||||
|
||||
private MergeTrackerProxy(Consumer<TreeStructureNode<SVNLogEntry>> consumer) {
|
||||
myConsumer = consumer;
|
||||
}
|
||||
|
||||
public void consume(Pair<SVNLogEntry, Integer> svnLogEntryIntegerPair) throws SVNException {
|
||||
final SVNLogEntry logEntry = svnLogEntryIntegerPair.getFirst();
|
||||
final Integer mergeLevel = svnLogEntryIntegerPair.getSecond();
|
||||
|
||||
if (mergeLevel < 0) {
|
||||
if (myCurrentHierarchy != null) {
|
||||
myConsumer.consume(myCurrentHierarchy);
|
||||
}
|
||||
if (logEntry.hasChildren()) {
|
||||
myCurrentHierarchy = new TreeStructureNode<SVNLogEntry>(logEntry);
|
||||
} else {
|
||||
// just pass
|
||||
myCurrentHierarchy = null;
|
||||
myConsumer.consume(new TreeStructureNode<SVNLogEntry>(logEntry));
|
||||
}
|
||||
} else {
|
||||
addToLevel(myCurrentHierarchy, logEntry, mergeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
if (myCurrentHierarchy != null) {
|
||||
myConsumer.consume(myCurrentHierarchy);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToLevel(final TreeStructureNode<SVNLogEntry> tree, final SVNLogEntry entry, final int left) {
|
||||
assert tree != null;
|
||||
if (left == 0) {
|
||||
tree.add(entry);
|
||||
} else {
|
||||
final List<TreeStructureNode<SVNLogEntry>> children = tree.getChildren();
|
||||
assert ! children.isEmpty();
|
||||
addToLevel(children.get(children.size() - 1), entry, left - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getCommittedChangesImpl(ChangeBrowserSettings settings, final String url, final String[] filterUrls,
|
||||
private void getCommittedChangesImpl(ChangeBrowserSettings settings, final SvnRepositoryLocation location, final String[] filterUrls,
|
||||
final int maxCount, final Consumer<SVNLogEntry> resultConsumer, final boolean includeMergedRevisions,
|
||||
final boolean filterOutByDate) throws VcsException {
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText(SvnBundle.message("progress.text.changes.collecting.changes"));
|
||||
progress.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", url));
|
||||
}
|
||||
try {
|
||||
SVNLogClient logger = myVcs.createLogClient();
|
||||
setCollectingChangesProgress(location);
|
||||
|
||||
try {
|
||||
final String author = settings.getUserFilter();
|
||||
final Date dateFrom = settings.getDateAfterFilter();
|
||||
final Long changeFrom = settings.getChangeAfterFilter();
|
||||
final Date dateTo = settings.getDateBeforeFilter();
|
||||
final Long changeTo = settings.getChangeBeforeFilter();
|
||||
|
||||
final SVNRevision revisionBefore;
|
||||
if (dateTo != null) {
|
||||
revisionBefore = SVNRevision.create(dateTo);
|
||||
}
|
||||
else if (changeTo != null) {
|
||||
revisionBefore = SVNRevision.create(changeTo.longValue());
|
||||
}
|
||||
else {
|
||||
// TODO: Implement this with command line
|
||||
SVNRepository repository = null;
|
||||
final long revision;
|
||||
try {
|
||||
repository = myVcs.createRepository(url);
|
||||
revision = repository.getLatestRevision();
|
||||
} finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
revisionBefore = SVNRevision.create(revision);
|
||||
}
|
||||
final SVNRevision revisionAfter;
|
||||
if (dateFrom != null) {
|
||||
revisionAfter = SVNRevision.create(dateFrom);
|
||||
}
|
||||
else if (changeFrom != null) {
|
||||
revisionAfter = SVNRevision.create(changeFrom.longValue());
|
||||
}
|
||||
else {
|
||||
revisionAfter = SVNRevision.create(1);
|
||||
}
|
||||
final SVNRevision revisionBefore = createRevisionBefore(location, dateTo, changeTo);
|
||||
final SVNRevision revisionAfter = createRevisionAfter(dateFrom, changeFrom);
|
||||
|
||||
// TODO: Implement this with command line
|
||||
logger.doLog(SVNURL.parseURIEncoded(url), filterUrls, revisionBefore, revisionBefore, revisionAfter,
|
||||
settings.STOP_ON_COPY, true, includeMergedRevisions, maxCount, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
if (progress != null) {
|
||||
progress.setText2(SvnBundle.message("progress.text2.processing.revision", logEntry.getRevision()));
|
||||
progress.checkCanceled();
|
||||
}
|
||||
if (filterOutByDate && logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
if (author == null || author.equalsIgnoreCase(logEntry.getAuthor())) {
|
||||
resultConsumer.consume(logEntry);
|
||||
}
|
||||
}
|
||||
});
|
||||
SVNLogClient logger = myVcs.createLogClient();
|
||||
logger.doLog(location.toSvnUrl(), filterUrls, revisionBefore, revisionBefore, revisionAfter, settings.STOP_ON_COPY, true,
|
||||
includeMergedRevisions, maxCount, null, createLogHandler(resultConsumer, filterOutByDate, author));
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SVNRevision createRevisionAfter(@Nullable Date date, @Nullable Long change) throws VcsException {
|
||||
return createRevision(date, change, new ThrowableComputable<SVNRevision, VcsException>() {
|
||||
@Override
|
||||
public SVNRevision compute() throws VcsException {
|
||||
return SVNRevision.create(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SVNRevision createRevisionBefore(@NotNull final SvnRepositoryLocation location, @Nullable Date date, @Nullable Long change)
|
||||
throws VcsException {
|
||||
return createRevision(date, change, new ThrowableComputable<SVNRevision, VcsException>() {
|
||||
@Override
|
||||
public SVNRevision compute() throws VcsException {
|
||||
return getLatestRevision(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SVNRevision getLatestRevision(@NotNull SvnRepositoryLocation location) throws VcsException {
|
||||
// TODO: Implement this with command line - issue is that if url does not exist, SVNRepository will be created and asked correctly
|
||||
// TODO: But "svn info -r HEAD" will fail - check if non-existing location could be passed or inteface should be expanded to use
|
||||
// TODO: peg revisions.
|
||||
SVNRepository repository = null;
|
||||
long revision;
|
||||
|
||||
try {
|
||||
repository = myVcs.createRepository(location.getURL());
|
||||
revision = repository.getLatestRevision();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
return SVNRevision.create(revision);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SVNRevision createRevision(@Nullable Date date,
|
||||
@Nullable Long change,
|
||||
@NotNull ThrowableComputable<SVNRevision, VcsException> defaultValue)
|
||||
throws VcsException {
|
||||
final SVNRevision result;
|
||||
|
||||
if (date != null) {
|
||||
result = SVNRevision.create(date);
|
||||
}
|
||||
else if (change != null) {
|
||||
result = SVNRevision.create(change.longValue());
|
||||
}
|
||||
else {
|
||||
result = defaultValue.compute();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ISVNLogEntryHandler createLogHandler(final Consumer<SVNLogEntry> resultConsumer,
|
||||
final boolean filterOutByDate,
|
||||
final String author) {
|
||||
return new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
|
||||
ProgressManager.progress2(SvnBundle.message("progress.text2.processing.revision", logEntry.getRevision()));
|
||||
if (filterOutByDate && logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
if (author == null || author.equalsIgnoreCase(logEntry.getAuthor())) {
|
||||
resultConsumer.consume(logEntry);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void setCollectingChangesProgress(@Nullable Object location) {
|
||||
ProgressManager.progress(SvnBundle.message("progress.text.changes.collecting.changes"),
|
||||
SvnBundle.message("progress.text2.changes.establishing.connection", location));
|
||||
}
|
||||
|
||||
public ChangeListColumn[] getColumns() {
|
||||
return new ChangeListColumn[] {
|
||||
new ChangeListColumn.ChangeListNumberColumn(SvnBundle.message("revision.title")),
|
||||
@@ -435,39 +338,6 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
myMergeInfoUpdatesListener.addPanel(action);
|
||||
}
|
||||
|
||||
private static class ShowHideMergePanel extends ToggleAction {
|
||||
private final DecoratorManager myManager;
|
||||
private final ChangeListFilteringStrategy myStrategy;
|
||||
private boolean myIsSelected;
|
||||
|
||||
public ShowHideMergePanel(final DecoratorManager manager, final ChangeListFilteringStrategy strategy) {
|
||||
myManager = manager;
|
||||
myStrategy = strategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
presentation.setIcon(SvnIcons.ShowIntegratedFrom);
|
||||
presentation.setText(SvnBundle.message("committed.changes.action.enable.merge.highlighting"));
|
||||
presentation.setDescription(SvnBundle.message("committed.changes.action.enable.merge.highlighting.description.text"));
|
||||
}
|
||||
|
||||
public boolean isSelected(final AnActionEvent e) {
|
||||
return myIsSelected;
|
||||
}
|
||||
|
||||
public void setSelected(final AnActionEvent e, final boolean state) {
|
||||
myIsSelected = state;
|
||||
if (state) {
|
||||
myManager.setFilteringStrategy(myStrategy);
|
||||
} else {
|
||||
myManager.removeFilteringStrategy(myStrategy.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VcsCommittedViewAuxiliary createActions(final DecoratorManager manager, @Nullable final RepositoryLocation location) {
|
||||
final RootsAndBranches rootsAndBranches = new RootsAndBranches(myProject, manager, location);
|
||||
@@ -478,7 +348,7 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
popup.add(rootsAndBranches.getUndoIntegrateAction());
|
||||
popup.add(new ConfigureBranchesAction());
|
||||
|
||||
final ShowHideMergePanel action = new ShowHideMergePanel(manager, rootsAndBranches.getStrategy());
|
||||
final ShowHideMergePanelAction action = new ShowHideMergePanelAction(manager, rootsAndBranches.getStrategy());
|
||||
|
||||
return new VcsCommittedViewAuxiliary(Collections.<AnAction>singletonList(popup), new Runnable() {
|
||||
public void run() {
|
||||
@@ -496,73 +366,7 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
|
||||
@Override
|
||||
public Pair<SvnChangeList, FilePath> getOneList(final VirtualFile file, VcsRevisionNumber number) throws VcsException {
|
||||
final RootUrlInfo rootUrlInfo = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(new File(file.getPath()));
|
||||
if (rootUrlInfo == null) return null;
|
||||
final VirtualFile root = rootUrlInfo.getVirtualFile();
|
||||
if (root == null) return null;
|
||||
final SvnRepositoryLocation svnRootLocation = (SvnRepositoryLocation)getLocationFor(new FilePathImpl(root));
|
||||
if (svnRootLocation == null) return null;
|
||||
final String url = svnRootLocation.getURL();
|
||||
final long revision;
|
||||
try {
|
||||
revision = Long.parseLong(number.asString());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
|
||||
final SvnChangeList[] result = new SvnChangeList[1];
|
||||
final SVNLogClient logger;
|
||||
final SVNRevision revisionBefore;
|
||||
final SVNURL repositoryUrl;
|
||||
final SVNURL svnurl;
|
||||
final SVNInfo targetInfo;
|
||||
try {
|
||||
logger = myVcs.createLogClient();
|
||||
revisionBefore = SVNRevision.create(revision);
|
||||
|
||||
svnurl = SVNURL.parseURIEncoded(url);
|
||||
final SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
|
||||
targetInfo = myVcs.getInfo(new File(file.getPath()));
|
||||
if (info == null) {
|
||||
throw new VcsException("Can not get repository URL");
|
||||
}
|
||||
repositoryUrl = info.getRepositoryRootURL();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
LOG.info(e);
|
||||
throw new VcsException(e);
|
||||
}
|
||||
|
||||
tryExactHit(svnRootLocation, result, logger, revisionBefore, repositoryUrl, svnurl);
|
||||
if (result[0] == null) {
|
||||
tryByRoot(result, logger, revisionBefore, repositoryUrl);
|
||||
if (result[0] == null) {
|
||||
FilePath path = tryStepByStep(svnRootLocation, result, logger, revisionBefore, targetInfo, svnurl);
|
||||
path = path == null ? new FilePathImpl(file) : path;
|
||||
// and pass & take rename context there
|
||||
return new Pair<SvnChangeList, FilePath>(result[0], path);
|
||||
}
|
||||
}
|
||||
if (result[0].getChanges().size() == 1) {
|
||||
final Collection<Change> changes = result[0].getChanges();
|
||||
final Change change = changes.iterator().next();
|
||||
final ContentRevision afterRevision = change.getAfterRevision();
|
||||
if (afterRevision != null) {
|
||||
return new Pair<SvnChangeList, FilePath>(result[0], afterRevision.getFile());
|
||||
} else {
|
||||
return new Pair<SvnChangeList, FilePath>(result[0], new FilePathImpl(file));
|
||||
}
|
||||
}
|
||||
String relativePath = SVNPathUtil.getRelativePath(targetInfo.getRepositoryRootURL().toString(), targetInfo.getURL().toString());
|
||||
relativePath = relativePath.startsWith("/") ? relativePath : "/" + relativePath;
|
||||
final Change targetChange = result[0].getByPath(relativePath);
|
||||
if (targetChange == null) {
|
||||
FilePath path = tryStepByStep(svnRootLocation, result, logger, revisionBefore, targetInfo, svnurl);
|
||||
path = path == null ? new FilePathImpl(file) : path;
|
||||
// and pass & take rename context there
|
||||
return new Pair<SvnChangeList, FilePath>(result[0], path);
|
||||
}
|
||||
return new Pair<SvnChangeList, FilePath>(result[0], new FilePathImpl(file));
|
||||
return new SingleCommittedListProvider(myVcs, file, number).run();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -576,121 +380,6 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class RenameContext {
|
||||
@NotNull
|
||||
private String myCurrentPath;
|
||||
private String myRepositoryRoot;
|
||||
private boolean myHadChanged;
|
||||
|
||||
private RenameContext(final SVNInfo info) {
|
||||
myRepositoryRoot = info.getRepositoryRootURL().toString();
|
||||
myCurrentPath = SVNPathUtil.getRelativePath(myRepositoryRoot, info.getURL().toString());
|
||||
myCurrentPath = myCurrentPath.startsWith("/") ? myCurrentPath : ("/" + myCurrentPath);
|
||||
}
|
||||
|
||||
public void accept(final SVNLogEntry entry) {
|
||||
final Map changedPaths = entry.getChangedPaths();
|
||||
if (changedPaths == null) return;
|
||||
|
||||
for (Object o : changedPaths.values()) {
|
||||
final SVNLogEntryPath entryPath = (SVNLogEntryPath) o;
|
||||
if (entryPath != null && 'A' == entryPath.getType() && entryPath.getCopyPath() != null) {
|
||||
if (myCurrentPath.equals(entryPath.getPath())) {
|
||||
myHadChanged = true;
|
||||
myCurrentPath = entryPath.getCopyPath();
|
||||
return;
|
||||
} else if (SVNPathUtil.isAncestor(entryPath.getPath(), myCurrentPath)) {
|
||||
final String relativePath = SVNPathUtil.getRelativePath(entryPath.getPath(), myCurrentPath);
|
||||
myCurrentPath = SVNPathUtil.append(entryPath.getCopyPath(), relativePath);
|
||||
myHadChanged = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FilePath getFilePath(final SvnVcs vcs) {
|
||||
if (! myHadChanged) return null;
|
||||
final SvnFileUrlMapping svnFileUrlMapping = vcs.getSvnFileUrlMapping();
|
||||
final String absolutePath = SVNPathUtil.append(myRepositoryRoot, myCurrentPath);
|
||||
final String localPath = svnFileUrlMapping.getLocalPath(absolutePath);
|
||||
if (localPath == null) {
|
||||
LOG.info("Cannot find local path for url: " + absolutePath);
|
||||
return null;
|
||||
}
|
||||
return new FilePathImpl(new File(localPath), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryByRoot(SvnChangeList[] result, SVNLogClient logger, SVNRevision revisionBefore, SVNURL repositoryUrl) throws VcsException {
|
||||
final boolean authorized = SvnAuthenticationNotifier.passiveValidation(myProject, repositoryUrl);
|
||||
if (! authorized) return;
|
||||
tryExactHit(new SvnRepositoryLocation(repositoryUrl.toString()), result, logger, revisionBefore, repositoryUrl, repositoryUrl);
|
||||
}
|
||||
|
||||
// return changed path, if any
|
||||
private FilePath tryStepByStep(final SvnRepositoryLocation svnRepositoryLocation,
|
||||
final SvnChangeList[] result,
|
||||
SVNLogClient logger,
|
||||
final SVNRevision revisionBefore, final SVNInfo info, SVNURL svnurl) throws VcsException {
|
||||
final String repositoryRoot = info.getRepositoryRootURL().toString();
|
||||
try {
|
||||
final RenameContext renameContext = new RenameContext(info);
|
||||
// TODO: Implement this with command line
|
||||
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, revisionBefore,
|
||||
false, true, false, 0, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
if (logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
renameContext.accept(logEntry);
|
||||
if (logEntry.getRevision() == revisionBefore.getNumber()) {
|
||||
result[0] = new SvnChangeList(myVcs, svnRepositoryLocation, logEntry, repositoryRoot);
|
||||
}
|
||||
}
|
||||
});
|
||||
return renameContext.getFilePath(myVcs);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
LOG.info(e);
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryExactHit(final SvnRepositoryLocation location,
|
||||
final SvnChangeList[] result,
|
||||
SVNLogClient logger,
|
||||
SVNRevision revisionBefore,
|
||||
final SVNURL repositoryUrl, SVNURL svnurl) throws VcsException {
|
||||
try {
|
||||
// TODO: Implement this with command line
|
||||
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, revisionBefore, revisionBefore,
|
||||
false, true, false, 1, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
if (logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
result[0] = new SvnChangeList(myVcs, location, logEntry, repositoryUrl.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (SVNException e) {
|
||||
LOG.info(e);
|
||||
if (SVNErrorCode.FS_CATEGORY == e.getErrorMessage().getErrorCode().getCategory()) {
|
||||
// pass to step by step looking for revision
|
||||
return;
|
||||
}
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getFormatVersion() {
|
||||
return VERSION_WITH_REPLACED_PATHS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vcs.RepositoryLocation;
|
||||
import com.intellij.openapi.vcs.changes.committed.RepositoryLocationGroup;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SvnCommittedListsZipper implements VcsCommittedListsZipper {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(SvnCommittedListsZipper.class);
|
||||
|
||||
@NotNull private final SvnVcs myVcs;
|
||||
|
||||
public SvnCommittedListsZipper(@NotNull SvnVcs vcs) {
|
||||
myVcs = vcs;
|
||||
}
|
||||
|
||||
public Pair<List<RepositoryLocationGroup>, List<RepositoryLocation>> groupLocations(final List<RepositoryLocation> in) {
|
||||
final List<RepositoryLocationGroup> groups = new ArrayList<RepositoryLocationGroup>();
|
||||
final List<RepositoryLocation> singles = new ArrayList<RepositoryLocation>();
|
||||
|
||||
final MultiMap<SVNURL, RepositoryLocation> map = new MultiMap<SVNURL, RepositoryLocation>();
|
||||
|
||||
for (RepositoryLocation location : in) {
|
||||
final SvnRepositoryLocation svnLocation = (SvnRepositoryLocation) location;
|
||||
final String url = svnLocation.getURL();
|
||||
|
||||
final SVNURL root = SvnUtil.getRepositoryRoot(myVcs, url);
|
||||
if (root == null) {
|
||||
// should not occur
|
||||
LOG.info("repository root not found for location:"+ location.toPresentableString());
|
||||
singles.add(location);
|
||||
} else {
|
||||
map.putValue(root, svnLocation);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<SVNURL> keys = map.keySet();
|
||||
for (SVNURL key : keys) {
|
||||
final Collection<RepositoryLocation> repositoryLocations = map.get(key);
|
||||
if (repositoryLocations.size() == 1) {
|
||||
singles.add(repositoryLocations.iterator().next());
|
||||
} else {
|
||||
final SvnRepositoryLocationGroup group = new SvnRepositoryLocationGroup(key, repositoryLocations);
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
return new Pair<List<RepositoryLocationGroup>, List<RepositoryLocation>>(groups, singles);
|
||||
}
|
||||
|
||||
public CommittedChangeList zip(final RepositoryLocationGroup group, final List<CommittedChangeList> lists) {
|
||||
return new SvnChangeList(lists, new SvnRepositoryLocation(group.toPresentableString()));
|
||||
}
|
||||
|
||||
public long getNumber(final CommittedChangeList list) {
|
||||
return list.getNumber();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnFileUrlMapping;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SvnCopyPathTracker {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(SvnCopyPathTracker.class);
|
||||
|
||||
@NotNull private String myCurrentPath;
|
||||
private String myRepositoryRoot;
|
||||
private boolean myHadChanged;
|
||||
|
||||
public SvnCopyPathTracker(@NotNull String repositoryUrl, @NotNull String relativeUrl) {
|
||||
myRepositoryRoot = repositoryUrl;
|
||||
myCurrentPath = relativeUrl;
|
||||
}
|
||||
|
||||
public void accept(@NotNull final SVNLogEntry entry) {
|
||||
final Map changedPaths = entry.getChangedPaths();
|
||||
if (changedPaths == null) return;
|
||||
|
||||
for (Object o : changedPaths.values()) {
|
||||
final SVNLogEntryPath entryPath = (SVNLogEntryPath) o;
|
||||
if (entryPath != null && 'A' == entryPath.getType() && entryPath.getCopyPath() != null) {
|
||||
if (myCurrentPath.equals(entryPath.getPath())) {
|
||||
myHadChanged = true;
|
||||
myCurrentPath = entryPath.getCopyPath();
|
||||
return;
|
||||
} else if (SVNPathUtil.isAncestor(entryPath.getPath(), myCurrentPath)) {
|
||||
final String relativePath = SVNPathUtil.getRelativePath(entryPath.getPath(), myCurrentPath);
|
||||
myCurrentPath = SVNPathUtil.append(entryPath.getCopyPath(), relativePath);
|
||||
myHadChanged = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FilePath getFilePath(final SvnVcs vcs) {
|
||||
if (! myHadChanged) return null;
|
||||
final SvnFileUrlMapping svnFileUrlMapping = vcs.getSvnFileUrlMapping();
|
||||
final String absolutePath = SVNPathUtil.append(myRepositoryRoot, myCurrentPath);
|
||||
final String localPath = svnFileUrlMapping.getLocalPath(absolutePath);
|
||||
if (localPath == null) {
|
||||
LOG.info("Cannot find local path for url: " + absolutePath);
|
||||
return null;
|
||||
}
|
||||
return new FilePathImpl(new File(localPath), false);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,6 @@ import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNLogClient;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
import org.tmatesoft.svn.util.SVNLogType;
|
||||
@@ -386,7 +385,10 @@ public class SvnHistoryProvider
|
||||
|
||||
final SVNURL svnurl = SVNURL.parseURIEncoded(myUrl);
|
||||
SVNRevision operationalFrom = myFrom == null ? SVNRevision.HEAD : myFrom;
|
||||
final SVNURL rootURL = getRepositoryRoot(svnurl, myFrom);
|
||||
// TODO: try to rewrite without separately retrieving repository url by item url - as this command could require authentication
|
||||
// TODO: and it is not "clear enough/easy to implement" with current design (for some cases) how to cache credentials (if in
|
||||
// TODO: non-interactive mode)
|
||||
final SVNURL rootURL = SvnUtil.getRepositoryRoot(myVcs, svnurl);
|
||||
if (rootURL == null) {
|
||||
throw new VcsException("Could not find repository root for URL: " + myUrl);
|
||||
}
|
||||
@@ -415,37 +417,30 @@ public class SvnHistoryProvider
|
||||
}
|
||||
|
||||
private void loadBackwards(SVNURL svnurl) throws SVNException, VcsException {
|
||||
final SVNURL rootURL = getRepositoryRoot(svnurl, myFrom);
|
||||
final String root = rootURL.toString();
|
||||
String relativeUrl = myUrl;
|
||||
if (myUrl.startsWith(root)) {
|
||||
relativeUrl = myUrl.substring(root.length());
|
||||
}
|
||||
// this method is called when svnurl does not exist in latest repository revision - thus concrete old revision is used for "info"
|
||||
// command to get repository url
|
||||
SVNInfo info = myVcs.getInfo(svnurl, myPeg, myPeg);
|
||||
final SVNURL rootURL = info != null ? info.getRepositoryRootURL() : null;
|
||||
final String root = rootURL != null ? rootURL.toString() : "";
|
||||
String relativeUrl = myUrl;
|
||||
if (myUrl.startsWith(root)) {
|
||||
relativeUrl = myUrl.substring(root.length());
|
||||
}
|
||||
|
||||
// TODO: Update this call to myVcs.getFactory.createHistoryClient
|
||||
SVNLogClient client = myVcs.createLogClient();
|
||||
|
||||
final RepositoryLogEntryHandler repositoryLogEntryHandler =
|
||||
final RepositoryLogEntryHandler repositoryLogEntryHandler =
|
||||
new RepositoryLogEntryHandler(myVcs, myUrl, SVNRevision.UNDEFINED, relativeUrl,
|
||||
new ThrowableConsumer<VcsFileRevision, SVNException>() {
|
||||
@Override
|
||||
public void consume(VcsFileRevision revision) throws SVNException {
|
||||
myConsumer.consume(revision);
|
||||
throw new SVNCancelException(); // load only one revision
|
||||
}
|
||||
}, rootURL);
|
||||
repositoryLogEntryHandler.setThrowCancelOnMeetPathCreation(true);
|
||||
repositoryLogEntryHandler.setThrowCancelOnMeetPathCreation(true);
|
||||
|
||||
client.doLog(rootURL, new String[]{}, myFrom, myFrom, myTo == null ? SVNRevision.create(1) : myTo, false, true, myShowMergeSources && mySupport15, 0, null, repositoryLogEntryHandler);
|
||||
}
|
||||
|
||||
// TODO: try to rewrite without separately retrieving repository url by item url - as this command could require authentication
|
||||
// TODO: and it is not "clear enough/easy to implement" with current design (for some cases) how to cache credentials (if in
|
||||
// TODO: non-interactive mode)
|
||||
private SVNURL getRepositoryRoot(SVNURL svnurl, SVNRevision operationalFrom) throws SVNException {
|
||||
SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
|
||||
|
||||
return info != null ? info.getRepositoryRootURL() : null;
|
||||
SvnTarget target = SvnTarget.fromURL(rootURL, myFrom);
|
||||
myVcs.getFactory(target).createHistoryClient()
|
||||
.doLog(target, myFrom, myTo == null ? SVNRevision.create(1) : myTo, false, true, myShowMergeSources && mySupport15, 1, null,
|
||||
repositoryLogEntryHandler);
|
||||
}
|
||||
|
||||
private boolean existsNow(SVNURL svnurl) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.SVNLogClient;
|
||||
@@ -42,7 +43,7 @@ public class SvnKitHistoryClient extends BaseSvnClient implements HistoryClient
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +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.history;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
|
||||
public class SvnLoadingRepositoryLocation extends SvnRepositoryLocation {
|
||||
private final LocationDetector locationDetector;
|
||||
|
||||
public SvnLoadingRepositoryLocation(final FilePath rootFile, @NotNull final String URL, @NotNull final SvnVcs vcs) {
|
||||
super(URL);
|
||||
locationDetector = new LocationDetector(vcs);
|
||||
}
|
||||
|
||||
public SvnLoadingRepositoryLocation(@NotNull final String URL, @NotNull final SvnVcs vcs) {
|
||||
super(URL);
|
||||
locationDetector = new LocationDetector(vcs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SvnLogLoader {
|
||||
List<CommittedChangeList> loadInterval(final SVNRevision fromIncluding, final SVNRevision toIncluding,
|
||||
final int maxCount, final boolean includingYoungest, final boolean includeOldest) throws SVNException;
|
||||
final int maxCount, final boolean includingYoungest, final boolean includeOldest)
|
||||
throws VcsException;
|
||||
}
|
||||
|
||||
@@ -19,15 +19,16 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.SVNLogClient;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -37,48 +38,47 @@ public class SvnLogUtil implements SvnLogLoader {
|
||||
private final SvnVcs myVcs;
|
||||
private final SvnRepositoryLocation myLocation;
|
||||
private final SVNURL myRepositoryRoot;
|
||||
private final String myRelative;
|
||||
|
||||
public SvnLogUtil(final Project project, final SvnVcs vcs, final SvnRepositoryLocation location, final SVNURL repositoryRoot) {
|
||||
myProject = project;
|
||||
myVcs = vcs;
|
||||
myLocation = location;
|
||||
myRepositoryRoot = repositoryRoot;
|
||||
|
||||
final String repositoryRootPath = repositoryRoot.toString();
|
||||
myRelative = myLocation.getURL().substring(repositoryRootPath.length());
|
||||
}
|
||||
|
||||
public List<CommittedChangeList> loadInterval(final SVNRevision fromIncluding, final SVNRevision toIncluding,
|
||||
final int maxCount, final boolean includingYoungest, final boolean includeOldest) throws SVNException {
|
||||
final int maxCount, final boolean includingYoungest, final boolean includeOldest)
|
||||
throws VcsException {
|
||||
final List<CommittedChangeList> result = new ArrayList<CommittedChangeList>();
|
||||
loadRevisions(fromIncluding, toIncluding, null, maxCount, result, includingYoungest, includeOldest);
|
||||
ISVNLogEntryHandler handler = createLogHandler(fromIncluding, toIncluding, includingYoungest, includeOldest, result);
|
||||
SvnTarget target = SvnTarget.fromURL(myLocation.toSvnUrl());
|
||||
|
||||
myVcs.getFactory(target).createHistoryClient().doLog(target, fromIncluding, toIncluding, true, true, false, maxCount, null, handler);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void loadRevisions(final SVNRevision fromIncluding, final SVNRevision toIncluding, final String author, final int maxCount,
|
||||
final List<CommittedChangeList> result,
|
||||
final boolean includingYoungest, final boolean includeOldest) throws SVNException {
|
||||
SVNLogClient logger = myVcs.createLogClient();
|
||||
logger.doLog(myRepositoryRoot, new String[]{myRelative}, SVNRevision.UNDEFINED, fromIncluding, toIncluding, true, true, maxCount,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText2(SvnBundle.message("progress.text2.processing.revision", logEntry.getRevision()));
|
||||
progress.checkCanceled();
|
||||
}
|
||||
if ((! includingYoungest) && (logEntry.getRevision() == fromIncluding.getNumber())) {
|
||||
return;
|
||||
}
|
||||
if ((! includeOldest) && (logEntry.getRevision() == toIncluding.getNumber())) {
|
||||
return;
|
||||
}
|
||||
if (author == null || author.equalsIgnoreCase(logEntry.getAuthor())) {
|
||||
result.add(new SvnChangeList(myVcs, myLocation, logEntry, myRepositoryRoot.toString()));
|
||||
}
|
||||
}
|
||||
});
|
||||
@NotNull
|
||||
private ISVNLogEntryHandler createLogHandler(final SVNRevision fromIncluding,
|
||||
final SVNRevision toIncluding,
|
||||
final boolean includingYoungest,
|
||||
final boolean includeOldest, final List<CommittedChangeList> result) {
|
||||
return new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.setText2(SvnBundle.message("progress.text2.processing.revision", logEntry.getRevision()));
|
||||
progress.checkCanceled();
|
||||
}
|
||||
if ((!includingYoungest) && (logEntry.getRevision() == fromIncluding.getNumber())) {
|
||||
return;
|
||||
}
|
||||
if ((!includeOldest) && (logEntry.getRevision() == toIncluding.getNumber())) {
|
||||
return;
|
||||
}
|
||||
result.add(new SvnChangeList(myVcs, myLocation, logEntry, myRepositoryRoot.toString()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,15 @@ package org.jetbrains.idea.svn.history;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.RepositoryLocation;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.actions.VcsContextFactory;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.RootUrlInfo;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -63,10 +68,24 @@ public class SvnRepositoryLocation implements RepositoryLocation {
|
||||
public static FilePath getLocalPath(final String fullPath, final NotNullFunction<File, Boolean> detector, final SvnVcs vcs) {
|
||||
if (vcs.getProject().isDefault()) return null;
|
||||
final RootUrlInfo rootForUrl = vcs.getSvnFileUrlMapping().getWcRootForUrl(fullPath);
|
||||
FilePath result = null;
|
||||
|
||||
if (rootForUrl != null) {
|
||||
return LocationDetector.filePathByUrlAndPath(fullPath, rootForUrl.getUrl().toString(), rootForUrl.getIoFile().getAbsolutePath(), detector);
|
||||
String relativePath = SvnUtil.getRelativeUrl(rootForUrl.getUrl(), fullPath);
|
||||
File file = new File(rootForUrl.getPath(), relativePath);
|
||||
|
||||
result = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file, detector);
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public SVNURL toSvnUrl() throws VcsException {
|
||||
try {
|
||||
return SvnUtil.createUrl(myURL);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-22
@@ -29,8 +29,8 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
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.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -55,31 +55,30 @@ public class SvnRevisionsNavigationMediator implements CommittedChangesNavigatio
|
||||
|
||||
myChunks = new LinkedList<List<Fragment>>();
|
||||
|
||||
final SVNURL[] repositoryRoot = new SVNURL[1];
|
||||
final long[] youngRevision = new long[1];
|
||||
final VcsException[] exception = new VcsException[1];
|
||||
final Ref<SVNInfo> infoRef = new Ref<SVNInfo>();
|
||||
|
||||
Runnable process = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SVNRepository repository = null;
|
||||
try {
|
||||
repository = vcs.createRepository(location.getURL());
|
||||
youngRevision[0] = repository.getLatestRevision();
|
||||
repositoryRoot[0] = repository.getRepositoryRoot(false);
|
||||
infoRef.set(vcs.getInfo(location.toSvnUrl(), SVNRevision.HEAD));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
exception[0] = e;
|
||||
}
|
||||
catch (SVNException e) {
|
||||
exception[0] = new VcsException(e);
|
||||
}
|
||||
finally {
|
||||
if (repository != null) {
|
||||
repository.closeSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
underProgress(exception, process);
|
||||
|
||||
SVNInfo info = infoRef.get();
|
||||
if (info == null || info.getRevision() == null || info.getRepositoryRootURL() == null) {
|
||||
throw new VcsException("Could not get head info for " + location);
|
||||
}
|
||||
|
||||
final Iterator<ChangesBunch> visualIterator = project.isDefault() ? null :
|
||||
CommittedChangesCache.getInstance(project).getBackBunchedIterator(vcs, vcsRoot, location, CHUNK_SIZE);
|
||||
final Iterator<ChangesBunch> internalIterator = project.isDefault() ? null : LoadedRevisionsCache.getInstance(project).iterator(location.getURL());
|
||||
@@ -87,8 +86,9 @@ public class SvnRevisionsNavigationMediator implements CommittedChangesNavigatio
|
||||
myInternallyCached = (internalIterator == null) ? null : new InternallyCachedProvider(internalIterator, myProject);
|
||||
myVisuallyCached = (visualIterator == null) ? null : new VisuallyCachedProvider(visualIterator, myProject, location);
|
||||
|
||||
myChunkFactory = new BunchFactory(myInternallyCached, myVisuallyCached,
|
||||
new LiveProvider(vcs, location, youngRevision[0], new SvnLogUtil(myProject, vcs, location, repositoryRoot[0])));
|
||||
myChunkFactory = new BunchFactory(myInternallyCached, myVisuallyCached, new LiveProvider(vcs, location, info.getRevision().getNumber(),
|
||||
new SvnLogUtil(myProject, vcs, location,
|
||||
info.getRepositoryRootURL())));
|
||||
|
||||
myCurrentIdx = -1;
|
||||
|
||||
@@ -133,13 +133,7 @@ public class SvnRevisionsNavigationMediator implements CommittedChangesNavigatio
|
||||
}
|
||||
|
||||
final Ref<Boolean> canNotGoBackRef = new Ref<Boolean>();
|
||||
final List<Fragment> fragments;
|
||||
try {
|
||||
fragments = myChunkFactory.goBack(CHUNK_SIZE, canNotGoBackRef);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
final List<Fragment> fragments = myChunkFactory.goBack(CHUNK_SIZE, canNotGoBackRef);
|
||||
myCanNotGoBack = canNotGoBackRef.get().booleanValue();
|
||||
|
||||
if (! fragments.isEmpty()) {
|
||||
|
||||
@@ -8,14 +8,8 @@ import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.commandLine.CommandExecutor;
|
||||
import org.jetbrains.idea.svn.commandLine.CommandUtil;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNPropertyValue;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNPropertyData;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
@@ -98,6 +92,39 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
|
||||
runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException {
|
||||
SVNProperties currentProperties = collectPropertiesToDelete(file);
|
||||
currentProperties.putAll(properties);
|
||||
|
||||
for (String propertyName : currentProperties.nameSet()) {
|
||||
setProperty(file, propertyName, currentProperties.getSVNPropertyValue(propertyName), SVNDepth.EMPTY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SVNProperties collectPropertiesToDelete(@NotNull File file) throws VcsException {
|
||||
final SVNProperties result = new SVNProperties();
|
||||
|
||||
list(SvnTarget.fromFile(file), null, SVNDepth.EMPTY, new ISVNPropertyHandler() {
|
||||
@Override
|
||||
public void handleProperty(File path, SVNPropertyData property) throws SVNException {
|
||||
// null indicates property will be deleted
|
||||
result.put(property.getName(), (SVNPropertyValue)null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRevisionProperty(@NotNull SvnTarget target,
|
||||
@NotNull String property,
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.api.SvnClient;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNProperties;
|
||||
import org.tmatesoft.svn.core.SVNPropertyValue;
|
||||
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
|
||||
import org.tmatesoft.svn.core.wc.ISVNOptions;
|
||||
@@ -51,6 +52,8 @@ public interface PropertyClient extends SvnClient {
|
||||
@Nullable SVNDepth depth,
|
||||
boolean force) throws VcsException;
|
||||
|
||||
void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException;
|
||||
|
||||
void setRevisionProperty(@NotNull SvnTarget target,
|
||||
@NotNull String property,
|
||||
@NotNull SVNRevision revision,
|
||||
|
||||
@@ -5,14 +5,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNPropertyValue;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNPropertyData;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
@@ -83,6 +77,21 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException {
|
||||
try {
|
||||
createClient().doSetProperty(file, new ISVNPropertyValueProvider() {
|
||||
@Override
|
||||
public SVNProperties providePropertyValues(File path, SVNProperties properties) throws SVNException {
|
||||
return properties;
|
||||
}
|
||||
}, true, SVNDepth.EMPTY, null, null);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRevisionProperty(@NotNull SvnTarget target,
|
||||
@NotNull String property,
|
||||
|
||||
@@ -39,7 +39,8 @@ public class CmdRevertClient extends BaseSvnClient implements RevertClient {
|
||||
// TODO: handler should be called in parallel with command execution, but this will be in other thread
|
||||
// TODO: check if that is ok for current handler implementation
|
||||
// TODO: add possibility to invoke "handler.checkCancelled" - process should be killed
|
||||
CommandExecutor command = CommandUtil.execute(myVcs, SvnTarget.fromFile(paths[0]), SvnCommandName.revert, parameters, null);
|
||||
CommandExecutor command =
|
||||
CommandUtil.execute(myVcs, SvnTarget.fromFile(paths[0]), CommandUtil.getHomeDirectory(), SvnCommandName.revert, parameters, null);
|
||||
FileStatusResultParser parser = new FileStatusResultParser(CHANGED_PATH, handler, new RevertStatusConvertor());
|
||||
parser.parse(command.getOutput());
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ import com.intellij.openapi.vcs.rollback.RollbackProgressListener;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.*;
|
||||
import org.jetbrains.idea.svn.revert.RevertClient;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -94,12 +94,12 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
};
|
||||
|
||||
final List<CopiedAsideInfo> fromToModified = new ArrayList<CopiedAsideInfo>();
|
||||
final MultiMap<File, SVNPropertyData> properties = new MultiMap<File, SVNPropertyData>();
|
||||
final Map<File, SVNProperties> properties = ContainerUtil.newHashMap();
|
||||
moveRenamesToTmp(exceptions, fromToModified, properties, collector);
|
||||
// adds (deletes)
|
||||
// deletes (adds)
|
||||
// modifications
|
||||
final Reverter reverter = new Reverter(mySvnVcs.getFactory().createRevertClient(), revertHandler, exceptions);
|
||||
final Reverter reverter = new Reverter(mySvnVcs, revertHandler, exceptions);
|
||||
reverter.revert(checker.getForAdds(), true);
|
||||
reverter.revert(checker.getForDeletes(), true);
|
||||
final List<File> edits = checker.getForEdits();
|
||||
@@ -117,18 +117,20 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
|
||||
private void moveRenamesToTmp(List<VcsException> exceptions,
|
||||
List<CopiedAsideInfo> fromToModified,
|
||||
final MultiMap<File, SVNPropertyData> properties,
|
||||
final Map<File, SVNProperties> properties,
|
||||
final UnversionedAndNotTouchedFilesGroupCollector collector) {
|
||||
final Map<File, ThroughRenameInfo> fromTo = collector.getFromTo();
|
||||
try {
|
||||
final File tmp = FileUtil.createTempDirectory("forRename", "");
|
||||
final SVNWCClient client = mySvnVcs.createWCClient();
|
||||
final ISVNPropertyHandler handler = new ISVNPropertyHandler() {
|
||||
@Override
|
||||
public void handleProperty(File path, SVNPropertyData property) throws SVNException {
|
||||
final ThroughRenameInfo info = collector.findToFile(new FilePathImpl(path, path.isDirectory()), null);
|
||||
if (info != null) {
|
||||
properties.putValue(info.getTo(), property);
|
||||
if (!properties.containsKey(info.getTo())) {
|
||||
properties.put(info.getTo(), new SVNProperties());
|
||||
}
|
||||
properties.get(info.getTo()).put(property.getName(), property.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +150,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
final File source = entry.getKey();
|
||||
final ThroughRenameInfo info = entry.getValue();
|
||||
if (info.isVersioned()) {
|
||||
client.doGetProperty(source, null, SVNRevision.UNDEFINED, SVNRevision.WORKING, SVNDepth.EMPTY, handler, null);
|
||||
mySvnVcs.getFactory(source).createPropertyClient().list(SvnTarget.fromFile(source), SVNRevision.WORKING, SVNDepth.EMPTY, handler);
|
||||
}
|
||||
if (source.isDirectory()) {
|
||||
if (! FileUtil.filesEqual(info.getTo(), info.getFirstTo())) {
|
||||
@@ -166,14 +168,14 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
catch (IOException e) {
|
||||
exceptions.add(new VcsException(e));
|
||||
}
|
||||
catch (SVNException e) {
|
||||
exceptions.add(new VcsException(e));
|
||||
catch(VcsException e) {
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveGroup(final List<VcsException> exceptions,
|
||||
List<CopiedAsideInfo> fromTo,
|
||||
MultiMap<File, SVNPropertyData> properties) {
|
||||
Map<File, SVNProperties> properties) {
|
||||
Collections.sort(fromTo, new Comparator<CopiedAsideInfo>() {
|
||||
@Override
|
||||
public int compare(CopiedAsideInfo o1, CopiedAsideInfo o2) {
|
||||
@@ -232,36 +234,25 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
applyProperties(properties, exceptions);
|
||||
}
|
||||
|
||||
private void applyProperties(MultiMap<File, SVNPropertyData> propertiesMap, final List<VcsException> exceptions) {
|
||||
final SVNWCClient client = mySvnVcs.createWCClient();
|
||||
for (Map.Entry<File, Collection<SVNPropertyData>> entry : propertiesMap.entrySet()) {
|
||||
final File file = entry.getKey();
|
||||
final Collection<SVNPropertyData> propertyDatas = entry.getValue();
|
||||
try {
|
||||
client.doSetProperty(file, new ISVNPropertyValueProvider() {
|
||||
@Override
|
||||
public SVNProperties providePropertyValues(File path, SVNProperties properties) throws SVNException {
|
||||
final SVNProperties result = new SVNProperties();
|
||||
for (SVNPropertyData data : propertyDatas) {
|
||||
result.put(data.getName(), data.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}, true, SVNDepth.EMPTY, null, null);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
exceptions.add(new VcsException(e));
|
||||
}
|
||||
private void applyProperties(Map<File, SVNProperties> propertiesMap, final List<VcsException> exceptions) {
|
||||
for (Map.Entry<File, SVNProperties> entry : propertiesMap.entrySet()) {
|
||||
File file = entry.getKey();
|
||||
try {
|
||||
mySvnVcs.getFactory(file).createPropertyClient().setProperties(file, entry.getValue());
|
||||
}
|
||||
catch (VcsException e) {
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Reverter {
|
||||
private final RevertClient myClient;
|
||||
@NotNull private final SvnVcs myVcs;
|
||||
private ISVNEventHandler myHandler;
|
||||
private final List<VcsException> myExceptions;
|
||||
|
||||
private Reverter(RevertClient client, ISVNEventHandler handler, List<VcsException> exceptions) {
|
||||
myClient = client;
|
||||
private Reverter(@NotNull SvnVcs vcs, ISVNEventHandler handler, List<VcsException> exceptions) {
|
||||
myVcs = vcs;
|
||||
myHandler = handler;
|
||||
myExceptions = exceptions;
|
||||
}
|
||||
@@ -269,7 +260,8 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
|
||||
public void revert(final File[] files, final boolean recursive) {
|
||||
if (files.length == 0) return;
|
||||
try {
|
||||
myClient.revert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, myHandler);
|
||||
// Files passed here are split into groups by root and working copy format - thus we could determine factory based on first file
|
||||
myVcs.getFactory(files[0]).createRevertClient().revert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, myHandler);
|
||||
}
|
||||
catch (VcsException e) {
|
||||
processRevertError(e);
|
||||
|
||||
+3
-41
@@ -193,12 +193,6 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
return EmptyConflictSide.getInstance();
|
||||
}
|
||||
}
|
||||
// todo temporally
|
||||
/*if (SVNNodeKind.DIR.equals(version.getKind())) {
|
||||
return new HistoryAsBrowseChangesConflictSide(myVcs.getProject(), version);
|
||||
} else {
|
||||
return new HistoryConflictSide(myVcs, version);
|
||||
}*/
|
||||
HistoryConflictSide side = new HistoryConflictSide(myVcs, version, untilThisOther);
|
||||
if (untilThisOther != null && ! isLeft) {
|
||||
side.setListToReportLoaded(myRightRevisionsList);
|
||||
@@ -314,11 +308,7 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
additionalPath = myChange.getAfterRevision().getFile();
|
||||
}
|
||||
} else {
|
||||
if (myChange.getBeforeRevision() != null) {
|
||||
mainPath = myChange.getBeforeRevision().getFile();
|
||||
} else {
|
||||
mainPath = myChange.getAfterRevision().getFile();
|
||||
}
|
||||
mainPath = myChange.getBeforeRevision() != null ? myChange.getBeforeRevision().getFile() : myChange.getAfterRevision().getFile();
|
||||
}
|
||||
return new Paths(mainPath, additionalPath);
|
||||
}
|
||||
@@ -368,15 +358,6 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
return null;
|
||||
}
|
||||
// my edit, theirs move or delete
|
||||
/*if (SVNConflictAction.DELETE.equals(description.getConflictAction()) && description.getSourceLeftVersion() != null) {
|
||||
//todo
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mergeMyEditTheirsDelete();
|
||||
}
|
||||
};
|
||||
} */
|
||||
if (SVNConflictAction.EDIT.equals(description.getConflictAction()) && description.getSourceLeftVersion() != null &&
|
||||
SVNConflictReason.DELETED.equals(description.getConflictReason()) && (myChange.isMoved() || myChange.isRenamed()) &&
|
||||
myCommittedRevision != null) {
|
||||
@@ -397,10 +378,7 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
}
|
||||
|
||||
public static String filePath(FilePath newFilePath) {
|
||||
return newFilePath.getName() +
|
||||
" (" +
|
||||
newFilePath.getParentPath().getPath() +
|
||||
")";
|
||||
return newFilePath.getName() + " (" + newFilePath.getParentPath().getPath() + ")";
|
||||
}
|
||||
|
||||
private static ActionListener createBoth(SVNTreeConflictDescription description) {
|
||||
@@ -524,12 +502,7 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
@Override
|
||||
public void load() throws SVNException, VcsException {
|
||||
SVNRevision from = SVNRevision.create(myVersion.getPegRevision());
|
||||
if (myPeg == null) {
|
||||
// just a portion of history
|
||||
myProvider.reportAppendableHistory(myPath, mySessionAdapter, from, myPeg, LIMIT, myPeg, true);
|
||||
} else {
|
||||
myProvider.reportAppendableHistory(myPath, mySessionAdapter, from, myPeg, 0, myPeg, true);
|
||||
}
|
||||
myProvider.reportAppendableHistory(myPath, mySessionAdapter, from, myPeg, myPeg == null ? LIMIT : 0, myPeg, true);
|
||||
VcsAbstractHistorySession session = mySessionAdapter.getSession();
|
||||
if (myListToReportLoaded != null && session != null) {
|
||||
List<VcsFileRevision> list = session.getRevisionList();
|
||||
@@ -576,15 +549,4 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
|
||||
return myFileHistoryPanel;
|
||||
}
|
||||
}
|
||||
|
||||
/*private static class HistoryAsBrowseChangesConflictSide implements AbstractConflictSide<Object> {
|
||||
public HistoryAsBrowseChangesConflictSide(Project project, SVNConflictVersion version) {
|
||||
//To change body of created methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel createPanel() {
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -96,13 +96,7 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
|
||||
}
|
||||
|
||||
private UpdateClient createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
|
||||
boolean is17 = WorkingCopyFormat.ONE_DOT_SEVEN.equals(myVcs.getWorkingCopyFormat(root));
|
||||
boolean isSupportedProtocol =
|
||||
SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol());
|
||||
|
||||
// TODO: Update this with just myVcs.getFactory(root) when switch and authentication protocols are implemented for command line
|
||||
ClientFactory factory = is17 && (isSwitch || !isSupportedProtocol) ? myVcs.getSvnKitFactory() : myVcs.getFactory(root);
|
||||
final UpdateClient updateClient = factory.createUpdateClient();
|
||||
final UpdateClient updateClient = myVcs.getFactory(root).createUpdateClient();
|
||||
|
||||
if (! isSwitch) {
|
||||
updateClient.setIgnoreExternals(configuration.isIgnoreExternals());
|
||||
|
||||
@@ -3,11 +3,11 @@ package org.jetbrains.idea.svn;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.committed.ChangesBunch;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
||||
import org.jetbrains.idea.svn.history.*;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
@@ -48,7 +48,8 @@ public class SvnCachingRevisionsTest extends CodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
public List<CommittedChangeList> loadInterval(final SVNRevision fromIncluding, final SVNRevision toIncluding, final int maxCount,
|
||||
final boolean includingYoungest, final boolean includeOldest) throws SVNException {
|
||||
final boolean includingYoungest, final boolean includeOldest)
|
||||
throws VcsException {
|
||||
long young = fromIncluding.getNumber();
|
||||
young = (young == -1) ? myRevisions.get(myRevisions.size() - 1) : young;
|
||||
final long old = toIncluding.getNumber();
|
||||
|
||||
@@ -3,12 +3,12 @@ package org.jetbrains.idea.svn16;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.committed.ChangesBunch;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
||||
import org.jetbrains.idea.svn.SvnApplicationSettings;
|
||||
import org.jetbrains.idea.svn.history.*;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
@@ -49,7 +49,8 @@ public class SvnCachingRevisionsTest extends CodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
public List<CommittedChangeList> loadInterval(final SVNRevision fromIncluding, final SVNRevision toIncluding, final int maxCount,
|
||||
final boolean includingYoungest, final boolean includeOldest) throws SVNException {
|
||||
final boolean includingYoungest, final boolean includeOldest)
|
||||
throws VcsException {
|
||||
long young = fromIncluding.getNumber();
|
||||
young = (young == -1) ? myRevisions.get(myRevisions.size() - 1) : young;
|
||||
final long old = toIncluding.getNumber();
|
||||
|
||||
Reference in New Issue
Block a user