IDEA-75800 SVN "Merge from..." not working

This commit is contained in:
irengrig
2011-11-15 14:40:47 +04:00
parent a675493f61
commit 834c4bc763
4 changed files with 222 additions and 85 deletions
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.history.CopyData;
import org.jetbrains.idea.svn.history.FirstInBranch;
import org.jetbrains.idea.svn.history.FirstInBranchAccurate;
import java.io.DataInput;
import java.io.DataOutput;
@@ -248,7 +249,7 @@ public class SvnBranchPointsCalculator {
public WrapperInvertor<BranchCopyData> convert(final KeyData keyData) {
final Ref<WrapperInvertor<BranchCopyData>> result = new Ref<WrapperInvertor<BranchCopyData>>();
new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), new Consumer<CopyData>() {
final Consumer<CopyData> consumer = new Consumer<CopyData>() {
public void consume(CopyData copyData) {
if (copyData != null) {
final boolean correct = copyData.isTrunkSupposedCorrect();
@@ -256,19 +257,29 @@ public class SvnBranchPointsCalculator {
if (correct) {
branchCopyData = new BranchCopyData(keyData.getSourceUrl(), copyData.getCopySourceRevision(), keyData.getTargetUrl(),
copyData.getCopyTargetRevision());
} else {
}
else {
branchCopyData = new BranchCopyData(keyData.getTargetUrl(), copyData.getCopySourceRevision(), keyData.getSourceUrl(),
copyData.getCopyTargetRevision());
}
result.set(new WrapperInvertor<BranchCopyData>(! correct, branchCopyData));
result.set(new WrapperInvertor<BranchCopyData>(!correct, branchCopyData));
}
}
}).run();
};
new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), consumer).run();
final WrapperInvertor<BranchCopyData> invertor = result.get();
WrapperInvertor<BranchCopyData> invertor = result.get();
if (LOG.isDebugEnabled()) {
LOG.debug("Loader returned: for key: " + keyData.toString() + " result: " + (invertor == null ? null : invertor.toString()));
}
if (invertor == null) {
new FirstInBranchAccurate(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), consumer).run();
invertor = result.get();
if (LOG.isDebugEnabled()) {
LOG.debug("Accurate Loader returned: for key: " + keyData.toString() + " result: " + (invertor == null ? null : invertor.toString()));
}
}
return invertor;
}
}
@@ -15,73 +15,32 @@
*/
package org.jetbrains.idea.svn.history;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.ConcurrentTasks;
import com.intellij.util.Consumer;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
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 java.util.Map;
public class FirstInBranch implements Runnable {
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.FirstInBranch");
private final SvnVcs myVcs;
private final String myFullBranchUrl;
private final String myFullTrunkUrl;
private final String myBranchUrl;
private final String myTrunkUrl;
private final Consumer<CopyData> myConsumer;
public FirstInBranch(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl, final Consumer<CopyData> consumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch created with: repoRoot: " + repositoryRoot + " branchUrl: " + branchUrl +
" trunkUrl: " + trunkUrl);
}
myVcs = vcs;
myConsumer = consumer;
myFullBranchUrl = branchUrl;
myFullTrunkUrl = trunkUrl;
myBranchUrl = relativePath(repositoryRoot, branchUrl);
myTrunkUrl = relativePath(repositoryRoot, trunkUrl);
public class FirstInBranch extends FirstInBranchAbstractBase {
public FirstInBranch(SvnVcs vcs,
String repositoryRoot,
String branchUrl,
String trunkUrl,
Consumer<CopyData> consumer) {
super(vcs, repositoryRoot, branchUrl, trunkUrl, consumer);
}
private String relativePath(final String parent, final String child) {
String path = SVNPathUtil.getRelativePath(parent, child);
return path.startsWith("/") ? path : "/" + path;
}
public void run() {
final SVNURL branchURL;
final SVNURL trunkURL;
try {
branchURL = SVNURL.parseURIEncoded(myFullBranchUrl);
trunkURL = SVNURL.parseURIEncoded(myFullTrunkUrl);
}
catch (SVNException e) {
LOG.info(e);
myConsumer.consume(null);
return;
}
final ConcurrentTasks<CopyData> tasks =
new ConcurrentTasks<CopyData>(ProgressManager.getInstance().getProgressIndicator(), createTask(branchURL), createTask(trunkURL));
tasks.compute();
if (tasks.isResultKnown()) {
myConsumer.consume(tasks.getResult());
} else {
myConsumer.consume(null);
}
}
private Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
protected Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
return new Consumer<Consumer<CopyData>>() {
public void consume(final Consumer<CopyData> copyDataConsumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch started for: " + branchURL.toString());
}
final SVNLogClient logClient = myVcs.createLogClient();
final long start1 = getStart(logClient, branchURL);
if (start1 > 0) {
@@ -96,11 +55,17 @@ public class FirstInBranch implements Runnable {
LOG.info(e);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch finished for: " + branchURL.toString());
}
}
};
}
private static long getStart(final SVNLogClient logClient, final SVNURL url) {
if (LOG.isDebugEnabled()) {
LOG.debug("getting start revision for: " + url);
}
final Ref<Long> myRevisionCandidate = new Ref<Long>(0L);
try {
logClient.doLog(url, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0),
@@ -109,36 +74,18 @@ public class FirstInBranch implements Runnable {
ProgressManager.checkCanceled();
myRevisionCandidate.set(logEntry.getRevision());
if (LOG.isDebugEnabled()) {
LOG.debug("setting in cycle start revision for: " + url + " as: " + myRevisionCandidate.get());
}
}
});
}
catch (SVNException e) {
LOG.info(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("start revision for: " + url + " is: " + myRevisionCandidate.get());
}
return myRevisionCandidate.get();
}
private void checkForCopy(final SVNLogEntry logEntry, final Consumer<CopyData> result) {
final Map map = logEntry.getChangedPaths();
for (Object o : map.values()) {
final SVNLogEntryPath path = (SVNLogEntryPath) o;
final String localPath = path.getPath();
final String copyPath = path.getCopyPath();
if (LOG.isDebugEnabled()) {
LOG.debug("localPath: " + localPath + " copy path: " + copyPath);
}
if ('A' == path.getType()) {
if ((myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
((myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), true));
} else {
if ((myBranchUrl.equals(copyPath) || SVNPathUtil.isAncestor(copyPath, myBranchUrl)) &&
((myTrunkUrl.equals(localPath)) || SVNPathUtil.isAncestor(localPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), false));
}
}
}
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.history;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.vcs.ConcurrentTasks;
import com.intellij.util.Consumer;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 11/15/11
* Time: 1:30 PM
*/
public abstract class FirstInBranchAbstractBase implements Runnable {
protected final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.FirstInBranch");
protected final SvnVcs myVcs;
protected final String myFullBranchUrl;
protected final String myFullTrunkUrl;
protected final String myBranchUrl;
protected final String myTrunkUrl;
protected final Consumer<CopyData> myConsumer;
public FirstInBranchAbstractBase(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl,
final Consumer<CopyData> consumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAbstractBase created with: repoRoot: " + repositoryRoot + " branchUrl: " + branchUrl +
" trunkUrl: " + trunkUrl);
}
myVcs = vcs;
myConsumer = consumer;
myFullBranchUrl = branchUrl;
myFullTrunkUrl = trunkUrl;
myBranchUrl = relativePath(repositoryRoot, branchUrl);
myTrunkUrl = relativePath(repositoryRoot, trunkUrl);
}
private String relativePath(final String parent, final String child) {
String path = SVNPathUtil.getRelativePath(parent, child);
return path.startsWith("/") ? path : "/" + path;
}
public void run() {
final SVNURL branchURL;
final SVNURL trunkURL;
try {
branchURL = SVNURL.parseURIEncoded(myFullBranchUrl);
trunkURL = SVNURL.parseURIEncoded(myFullTrunkUrl);
}
catch (SVNException e) {
LOG.info(e);
myConsumer.consume(null);
return;
}
final ConcurrentTasks<CopyData> tasks =
new ConcurrentTasks<CopyData>(ProgressManager.getInstance().getProgressIndicator(), createTask(branchURL), createTask(trunkURL));
tasks.compute();
if (tasks.isResultKnown()) {
myConsumer.consume(tasks.getResult());
} else {
myConsumer.consume(null);
}
}
protected abstract Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL);
protected void checkForCopy(final SVNLogEntry logEntry, final Consumer<CopyData> result) {
final Map map = logEntry.getChangedPaths();
for (Object o : map.values()) {
final SVNLogEntryPath path = (SVNLogEntryPath) o;
final String localPath = path.getPath();
final String copyPath = path.getCopyPath();
if (LOG.isDebugEnabled()) {
LOG.debug("localPath: " + localPath + " copy path: " + copyPath + " revision: " + logEntry.getRevision());
}
if ('A' == path.getType()) {
if ((myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
((myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), true));
} else {
if ((myBranchUrl.equals(copyPath) || SVNPathUtil.isAncestor(copyPath, myBranchUrl)) &&
((myTrunkUrl.equals(localPath)) || SVNPathUtil.isAncestor(localPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), false));
}
}
}
}
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.history;
import com.intellij.util.Consumer;
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;
/**
* Created by IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 11/15/11
* Time: 1:23 PM
*/
public class FirstInBranchAccurate extends FirstInBranchAbstractBase {
public FirstInBranchAccurate(SvnVcs vcs,
String repositoryRoot,
String branchUrl,
String trunkUrl,
Consumer<CopyData> consumer) {
super(vcs, repositoryRoot, branchUrl, trunkUrl, consumer);
}
@Override
protected Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
return new Consumer<Consumer<CopyData>>() {
public void consume(final Consumer<CopyData> copyDataConsumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAccurate started for: " + branchURL.toString());
}
final SVNLogClient logClient = myVcs.createLogClient();
try {
logClient.doLog(branchURL, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0), true, true, 1, new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
checkForCopy(logEntry, copyDataConsumer);
}
});
} catch (SVNException e) {
LOG.info(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAccurate finished for: " + branchURL.toString());
}
}
};
}
}