svn: Extracted "LookForBranchOriginTask", utilized it in quick merge

"LookForBranchOriginTask" is extracted from previously used
"SvnBranchPointsCalculator.getFirstCopyPointTask()" logic
This commit is contained in:
Konstantin Kolosovsky
2016-10-11 04:28:23 +03:00
parent e900069b85
commit b82854e3c6
6 changed files with 93 additions and 181 deletions
@@ -18,7 +18,6 @@ package org.jetbrains.idea.svn.integrate;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.SeparatePiecesRunner;
import com.intellij.util.continuation.TaskDescriptor;
@@ -33,6 +32,7 @@ import org.tmatesoft.svn.core.SVNURL;
import java.util.List;
import static com.intellij.openapi.application.ApplicationManager.getApplication;
import static com.intellij.util.containers.ContainerUtil.newArrayList;
import static java.util.Collections.singletonList;
public abstract class BaseMergeTask extends TaskDescriptor {
@@ -86,16 +86,11 @@ public abstract class BaseMergeTask extends TaskDescriptor {
@NotNull
protected List<TaskDescriptor> getMergeAllTasks() {
List<TaskDescriptor> result = ContainerUtil.newArrayList();
result.add(new LocalChangesPromptTask(myMergeProcess, true, null, null));
MergeAllWithBranchCopyPointTask mergeAllExecutor = new MergeAllWithBranchCopyPointTask(myMergeProcess);
result.add(myMergeContext.getVcs().getSvnBranchPointsCalculator()
.getFirstCopyPointTask(myMergeContext.getWcInfo().getRepositoryRoot(), myMergeContext.getSourceUrl(),
myMergeContext.getWcInfo().getRootUrl(), mergeAllExecutor));
result.add(mergeAllExecutor);
return result;
return newArrayList(
new LocalChangesPromptTask(myMergeProcess, true, null, null),
new LookForBranchOriginTask(myMergeProcess, true, copyPoint ->
next(new MergeAllWithBranchCopyPointTask(myMergeProcess, copyPoint)))
);
}
protected void runChangeListsMerge(@NotNull List<CommittedChangeList> lists,
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2016 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.integrate;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.Consumer;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
public class LookForBranchOriginTask extends BaseMergeTask {
private final boolean myFromSource;
@NotNull private final Consumer<SvnBranchPointsCalculator.WrapperInvertor> myCallback;
public LookForBranchOriginTask(@NotNull QuickMerge mergeProcess,
boolean fromSource,
@NotNull Consumer<SvnBranchPointsCalculator.WrapperInvertor> callback) {
super(mergeProcess, "Looking for branch origin", Where.POOLED);
myFromSource = fromSource;
myCallback = callback;
}
@Override
public void run() {
String repoUrl = myMergeContext.getWcInfo().getRepoUrl();
String sourceUrl = myFromSource ? myMergeContext.getSourceUrl() : myMergeContext.getWcInfo().getRootUrl();
String targetUrl = myFromSource ? myMergeContext.getWcInfo().getRootUrl() : myMergeContext.getSourceUrl();
try {
SvnBranchPointsCalculator.WrapperInvertor copyPoint =
myMergeContext.getVcs().getSvnBranchPointsCalculator().calculateCopyPoint(repoUrl, sourceUrl, targetUrl);
if (copyPoint != null) {
myCallback.consume(copyPoint);
}
else {
end("Merge start wasn't found", true);
}
}
catch (VcsException e) {
end("Merge start wasn't found", e);
}
}
}
@@ -15,7 +15,6 @@
*/
package org.jetbrains.idea.svn.integrate;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
@@ -39,16 +38,9 @@ public class MergeAllOrSelectedChooserTask extends BaseMergeTask {
next(loader, dialog);
break;
case select:
MergeCalculatorTask calculator = new MergeCalculatorTask(myMergeProcess);
next(getCalculateFirstCopyPointTask(calculator), calculator);
next(new LookForBranchOriginTask(myMergeProcess, false, copyPoint ->
next(new MergeCalculatorTask(myMergeProcess, copyPoint))));
break;
}
}
@NotNull
private TaskDescriptor getCalculateFirstCopyPointTask(@NotNull MergeCalculatorTask mergeCalculator) {
return myMergeContext.getVcs().getSvnBranchPointsCalculator()
.getFirstCopyPointTask(myMergeContext.getWcInfo().getRepositoryRoot(), myMergeContext.getWcInfo().getRootUrl(),
myMergeContext.getSourceUrl(), mergeCalculator);
}
}
@@ -15,66 +15,27 @@
*/
package org.jetbrains.idea.svn.integrate;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI;
import com.intellij.util.Consumer;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicReference;
public class MergeAllWithBranchCopyPointTask extends BaseMergeTask {
public class MergeAllWithBranchCopyPointTask extends BaseMergeTask
implements Consumer<TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException>> {
@NotNull private final SvnBranchPointsCalculator.WrapperInvertor myCopyPoint;
@NotNull private final AtomicReference<TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException>> myData;
public MergeAllWithBranchCopyPointTask(@NotNull QuickMerge mergeProcess) {
public MergeAllWithBranchCopyPointTask(@NotNull QuickMerge mergeProcess, @NotNull SvnBranchPointsCalculator.WrapperInvertor copyPoint) {
super(mergeProcess, "merge all", Where.AWT);
myData = new AtomicReference<>();
}
@Override
public void consume(TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException> value) {
myData.set(value);
myCopyPoint = copyPoint;
}
@Override
public void run() {
TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException> inverterValue = myData.get();
boolean reintegrate = myCopyPoint.isInvertedSense();
if (inverterValue != null) {
runMerge(inverterValue);
}
else {
end("Merge start wasn't found", true);
}
}
private void runMerge(@NotNull TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException> inverterValue) {
try {
SvnBranchPointsCalculator.WrapperInvertor inverter = inverterValue.get();
if (inverter != null) {
runMerge(inverter);
}
else {
end("Merge start wasn't found", true);
}
}
catch (VcsException e) {
end("Merge start wasn't found", e);
}
}
private void runMerge(@NotNull SvnBranchPointsCalculator.WrapperInvertor inverter) {
boolean reintegrate = inverter.isInvertedSense();
if (reintegrate && !myInteraction.shouldReintegrate(inverter.inverted().getTarget())) {
if (reintegrate && !myInteraction.shouldReintegrate(myCopyPoint.inverted().getTarget())) {
end();
}
else {
MergerFactory mergerFactory = createBranchMergerFactory(reintegrate, inverter);
MergerFactory mergerFactory = createBranchMergerFactory(reintegrate);
String title = "Merging all from " + myMergeContext.getBranchName() + (reintegrate ? " (reintegrate)" : "");
next(new MergeTask(myMergeProcess, mergerFactory, title));
@@ -82,9 +43,9 @@ public class MergeAllWithBranchCopyPointTask extends BaseMergeTask
}
@NotNull
private MergerFactory createBranchMergerFactory(boolean reintegrate, @NotNull SvnBranchPointsCalculator.WrapperInvertor inverter) {
private MergerFactory createBranchMergerFactory(boolean reintegrate) {
return (vcs, target, handler, currentBranchUrl, branchName) ->
new BranchMerger(vcs, currentBranchUrl, myMergeContext.getWcInfo().getPath(), handler, reintegrate, myMergeContext.getBranchName(),
reintegrate ? inverter.getWrapped().getTargetRevision() : inverter.getWrapped().getSourceRevision());
reintegrate ? myCopyPoint.getWrapped().getTargetRevision() : myCopyPoint.getWrapped().getSourceRevision());
}
}
@@ -19,14 +19,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.history.*;
import org.jetbrains.idea.svn.mergeinfo.MergeChecker;
import org.jetbrains.idea.svn.mergeinfo.OneShotMergeInfoHelper;
@@ -34,48 +31,37 @@ import org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import static com.intellij.util.containers.ContainerUtil.newArrayList;
import static org.jetbrains.idea.svn.SvnUtil.ensureStartSlash;
import static org.tmatesoft.svn.core.internal.util.SVNPathUtil.getRelativePath;
import static org.tmatesoft.svn.core.internal.util.SVNPathUtil.isAncestor;
public class MergeCalculatorTask extends BaseMergeTask
implements Consumer<TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException>> {
@NotNull private final AtomicReference<TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException>> myCopyData;
public class MergeCalculatorTask extends BaseMergeTask {
@NotNull private final SvnBranchPointsCalculator.WrapperInvertor myCopyPoint;
@NotNull private final MergeChecker myMergeChecker;
@Override
public void consume(TransparentlyFailedValueI<SvnBranchPointsCalculator.WrapperInvertor, VcsException> value) {
myCopyData.set(value);
}
public MergeCalculatorTask(@NotNull QuickMerge mergeProcess) {
public MergeCalculatorTask(@NotNull QuickMerge mergeProcess, @NotNull SvnBranchPointsCalculator.WrapperInvertor copyPoint) {
super(mergeProcess, "Calculating not merged revisions", Where.POOLED);
myCopyPoint = copyPoint;
// TODO: Previously it was configurable - either to use OneShotMergeInfoHelper or BranchInfo as merge checker, but later that logic
// TODO: was commented (in 80ebdbfea5210f6c998e67ddf28ca9c670fa4efe on 5/28/2010).
// TODO: Still check if we need to preserve such configuration or it is sufficient to always use OneShotMergeInfoHelper.
myMergeChecker = new OneShotMergeInfoHelper(myMergeContext);
myCopyData = new AtomicReference<>();
}
@Override
public void run() throws VcsException {
SvnBranchPointsCalculator.WrapperInvertor copyPoint = getCopyPoint();
if (copyPoint != null && myMergeContext.getWcInfo().getFormat().supportsMergeInfo()) {
if (myMergeContext.getWcInfo().getFormat().supportsMergeInfo()) {
myMergeChecker.prepare();
List<Pair<SvnChangeList, LogHierarchyNode>> afterCopyPointChangeLists =
getChangeListsAfter(copyPoint.getTrue().getTargetRevision());
getChangeListsAfter(myCopyPoint.getTrue().getTargetRevision());
List<CommittedChangeList> notMergedChangeLists = getNotMergedChangeLists(afterCopyPointChangeLists);
if (!notMergedChangeLists.isEmpty()) {
next(new ShowRevisionSelector(myMergeProcess, copyPoint, notMergedChangeLists, myMergeChecker));
next(new ShowRevisionSelector(myMergeProcess, myCopyPoint, notMergedChangeLists, myMergeChecker));
}
else {
end("Everything is up-to-date", false);
@@ -83,24 +69,6 @@ public class MergeCalculatorTask extends BaseMergeTask
}
}
@Nullable
private SvnBranchPointsCalculator.WrapperInvertor getCopyPoint() {
SvnBranchPointsCalculator.WrapperInvertor result = null;
try {
result = myCopyData.get().get();
if (result == null) {
end("Merge start wasn't found", true);
}
}
catch (VcsException e) {
end("Merge start wasn't found", e);
}
return result;
}
@NotNull
private List<Pair<SvnChangeList, LogHierarchyNode>> getChangeListsAfter(final long revision) {
ChangeBrowserSettings settings = new ChangeBrowserSettings();
@@ -18,13 +18,7 @@ package org.jetbrains.idea.svn.integrate;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ThreadSafeTransparentlyFailedValue;
import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI;
import com.intellij.openapi.vcs.persistent.SmallMapSerializer;
import com.intellij.util.Consumer;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import org.jetbrains.annotations.NotNull;
@@ -81,8 +75,6 @@ public class SvnBranchPointsCalculator {
}
}
logCopyData(repoUrl, sourceUrl, targetUrl, result);
return result;
}
}
@@ -185,16 +177,20 @@ public class SvnBranchPointsCalculator {
@Nullable
public WrapperInvertor calculateCopyPoint(@NotNull String repoUrl, @NotNull String sourceUrl, @NotNull String targetUrl)
throws VcsException {
WrapperInvertor result = null;
CopyData copyData = new FirstInBranch(myVcs, repoUrl, targetUrl, sourceUrl).run();
WrapperInvertor result = getBestHit(repoUrl, sourceUrl, targetUrl);
if (copyData != null) {
BranchCopyData branchCopyData =
copyData.isTrunkSupposedCorrect()
? new BranchCopyData(sourceUrl, copyData.getCopySourceRevision(), targetUrl, copyData.getCopyTargetRevision())
: new BranchCopyData(targetUrl, copyData.getCopySourceRevision(), sourceUrl, copyData.getCopyTargetRevision());
if (result == null) {
CopyData copyData = new FirstInBranch(myVcs, repoUrl, targetUrl, sourceUrl).run();
result = new WrapperInvertor(!copyData.isTrunkSupposedCorrect(), branchCopyData);
if (copyData != null) {
BranchCopyData branchCopyData =
copyData.isTrunkSupposedCorrect()
? new BranchCopyData(sourceUrl, copyData.getCopySourceRevision(), targetUrl, copyData.getCopyTargetRevision())
: new BranchCopyData(targetUrl, copyData.getCopySourceRevision(), sourceUrl, copyData.getCopyTargetRevision());
persist(repoUrl, branchCopyData);
result = new WrapperInvertor(!copyData.isTrunkSupposedCorrect(), branchCopyData);
}
}
logCopyData(repoUrl, sourceUrl, targetUrl, result);
@@ -249,61 +245,4 @@ public class SvnBranchPointsCalculator {
return new BranchCopyData(myTarget, myTargetRevision, mySource, mySourceRevision);
}
}
@NotNull
public TaskDescriptor getFirstCopyPointTask(@NotNull String repoUrl,
@NotNull String sourceUrl,
@NotNull String targetUrl,
@NotNull Consumer<TransparentlyFailedValueI<WrapperInvertor, VcsException>> consumer) {
TransparentlyFailedValueI<WrapperInvertor, VcsException> value = new ThreadSafeTransparentlyFailedValue<>();
TaskDescriptor pooled = new TaskDescriptor("Looking for branch origin", Where.POOLED) {
@Override
public void run(ContinuationContext context) {
try {
WrapperInvertor calculatedValue = calculateCopyPoint(repoUrl, sourceUrl, targetUrl);
if (calculatedValue != null) {
persist(repoUrl, calculatedValue.getWrapped());
}
value.set(calculatedValue);
}
catch (Exception e) {
setException(value, e);
}
context.next(new TaskDescriptor("final part", Where.AWT) {
@Override
public void run(ContinuationContext context) {
consumer.consume(value);
}
});
}
};
return new TaskDescriptor("short part", Where.AWT) {
@Override
public void run(ContinuationContext context) {
try {
value.set(getBestHit(repoUrl, sourceUrl, targetUrl));
}
catch (Exception e) {
setException(value, e);
}
if (value.haveSomething()) {
consumer.consume(value);
return;
}
context.next(pooled);
}
};
}
private static void setException(@NotNull TransparentlyFailedValueI<WrapperInvertor, VcsException> value, @NotNull Exception e) {
if (e instanceof VcsException) {
value.fail((VcsException)e);
}
else {
LOG.info(e);
value.failRuntime(e instanceof RuntimeException ? (RuntimeException)e : new RuntimeException(e));
}
}
}