}
@NotNull
- protected List<TaskDescriptor> getMergeAllTasks() {
+ protected List<TaskDescriptor> getMergeAllTasks(boolean supportsMergeInfo) {
+ // merge info is not supported - branch copy point is used to make first sync merge successful (without unnecessary tree conflicts)
+ // merge info is supported - branch copy point is used to determine if sync or reintegrate merge should be performed
return newArrayList(
new LocalChangesPromptTask(myMergeProcess),
new LookForBranchOriginTask(myMergeProcess, true, copyPoint ->
- next(new MergeAllWithBranchCopyPointTask(myMergeProcess, copyPoint)))
+ next(new MergeAllWithBranchCopyPointTask(myMergeProcess, copyPoint, supportsMergeInfo)))
);
}
import org.jetbrains.idea.svn.update.UpdateEventHandler;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNRevisionRange;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
private final long mySourceCopyRevision;
private boolean myAtStart;
private SVNRevision mySourceLatestRevision;
+ private final boolean mySupportsMergeInfo;
public BranchMerger(final SvnVcs vcs,
final SVNURL sourceUrl,
final String targetPath,
final UpdateEventHandler handler,
- final boolean isReintegrate, final String branchName, final long sourceCopyRevision) {
+ final boolean isReintegrate,
+ final String branchName,
+ long sourceCopyRevision,
+ boolean supportsMergeInfo) {
myVcs = vcs;
myTargetPath = targetPath;
mySourceUrl = sourceUrl;
myBranchName = branchName;
mySourceCopyRevision = sourceCopyRevision;
myAtStart = true;
- mySourceLatestRevision = resolveSourceLatestRevision();
+ mySupportsMergeInfo = supportsMergeInfo;
}
public String getComment() {
- return "Merge all from " + myBranchName + " at " + mySourceLatestRevision +(myReintegrate ? " (reintegration)" : "");
+ return "Merge all from " + myBranchName +
+ (!mySupportsMergeInfo ? " at " + mySourceLatestRevision : "") +
+ (myReintegrate ? " (reintegration)" : "");
}
public boolean hasNext() {
File destination = new File(myTargetPath);
MergeClient client = myVcs.getFactory(destination).createMergeClient();
+ SvnTarget source = SvnTarget.fromURL(mySourceUrl);
- if (myReintegrate) {
- client.merge(SvnTarget.fromURL(mySourceUrl), destination, false, createDiffOptions(), myHandler);
+ if (mySupportsMergeInfo) {
+ client.merge(source, destination, false, myReintegrate, createDiffOptions(), myHandler);
} else {
- client.merge(SvnTarget.fromURL(mySourceUrl, SVNRevision.create(mySourceCopyRevision)),
- SvnTarget.fromURL(mySourceUrl, mySourceLatestRevision), destination, Depth.INFINITY, true, false, false, true,
- createDiffOptions(), myHandler);
+ mySourceLatestRevision = resolveSourceLatestRevision();
+ SVNRevisionRange range = new SVNRevisionRange(SVNRevision.create(mySourceCopyRevision), mySourceLatestRevision);
+
+ client.merge(source, range, destination, Depth.UNKNOWN, false, false, true, createDiffOptions(), myHandler);
}
}
@Override
public void run() {
- next(supportsMergeInfo() ? getChooseMergeTypeTasks() : getMergeAllTasks());
+ next(supportsMergeInfo() ? getChooseMergeTypeTasks() : getMergeAllTasks(false));
}
private boolean supportsMergeInfo() {
public void merge(@NotNull SvnTarget source,
@NotNull File destination,
boolean dryRun,
+ boolean reintegrate,
@Nullable DiffOptions diffOptions,
- @Nullable final ProgressTracker handler) throws VcsException {
+ @Nullable ProgressTracker handler) throws VcsException {
assertUrl(source);
List<String> parameters = new ArrayList<>();
CommandUtil.put(parameters, source);
- fillParameters(parameters, destination, null, dryRun, false, false, true, diffOptions);
+ fillParameters(parameters, destination, null, dryRun, false, false, reintegrate, diffOptions);
run(destination, handler, parameters);
}
//noinspection EnumSwitchStatementWhichMissesCases
switch (myInteraction.selectMergeVariant()) {
case all:
- next(getMergeAllTasks());
+ next(getMergeAllTasks(true));
break;
case showLatest:
LoadRecentBranchRevisions loader = new LoadRecentBranchRevisions(myMergeProcess, -1);
public class MergeAllWithBranchCopyPointTask extends BaseMergeTask {
@NotNull private final SvnBranchPointsCalculator.WrapperInvertor myCopyPoint;
+ private final boolean mySupportsMergeInfo;
- public MergeAllWithBranchCopyPointTask(@NotNull QuickMerge mergeProcess, @NotNull SvnBranchPointsCalculator.WrapperInvertor copyPoint) {
+ public MergeAllWithBranchCopyPointTask(@NotNull QuickMerge mergeProcess,
+ @NotNull SvnBranchPointsCalculator.WrapperInvertor copyPoint,
+ boolean supportsMergeInfo) {
super(mergeProcess, "merge all", Where.AWT);
myCopyPoint = copyPoint;
+ mySupportsMergeInfo = supportsMergeInfo;
}
@Override
@NotNull
private MergerFactory createBranchMergerFactory(boolean reintegrate) {
- return (vcs, target, handler, currentBranchUrl, branchName) ->
- new BranchMerger(vcs, currentBranchUrl, myMergeContext.getWcInfo().getPath(), handler, reintegrate, myMergeContext.getBranchName(),
- reintegrate ? myCopyPoint.getWrapped().getTargetRevision() : myCopyPoint.getWrapped().getSourceRevision());
+ return (vcs, target, handler, currentBranchUrl, branchName) -> {
+ long revision = reintegrate ? myCopyPoint.getWrapped().getTargetRevision() : myCopyPoint.getWrapped().getSourceRevision();
+
+ return new BranchMerger(vcs, currentBranchUrl, myMergeContext.getWcInfo().getPath(), handler, reintegrate,
+ myMergeContext.getBranchName(), revision, mySupportsMergeInfo);
+ };
}
}
end();
break;
case all:
- next(getMergeAllTasks());
+ next(getMergeAllTasks(true));
break;
default:
List<CommittedChangeList> lists = result.getSelectedLists();
void merge(@NotNull SvnTarget source,
@NotNull File destination,
boolean dryRun,
+ boolean reintegrate,
@Nullable DiffOptions diffOptions,
@Nullable ProgressTracker handler) throws VcsException;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.ProgressTracker;
import org.jetbrains.idea.svn.diff.DiffOptions;
+import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNDiffClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNRevisionRange;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
-import java.util.Collections;
+import java.util.List;
+
+import static java.util.Collections.singletonList;
/**
* @author Konstantin Kolosovsky.
*/
public class SvnKitMergeClient extends BaseSvnClient implements MergeClient {
+ private static final List<SVNRevisionRange> ALL_REVISIONS_RANGE =
+ singletonList(new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD));
+
public void merge(@NotNull SvnTarget source,
@NotNull File destination,
boolean dryRun,
+ boolean reintegrate,
@Nullable DiffOptions diffOptions,
@Nullable ProgressTracker handler) throws VcsException {
assertUrl(source);
+ SVNDiffClient client = createClient(diffOptions, handler);
try {
- createClient(diffOptions, handler).doMergeReIntegrate(source.getURL(), source.getPegRevision(), destination, dryRun);
+ if (reintegrate) {
+ client.doMergeReIntegrate(source.getURL(), source.getPegRevision(), destination, dryRun);
+ }
+ else {
+ client.doMerge(source.getURL(), source.getPegRevision(), ALL_REVISIONS_RANGE, destination, SVNDepth.UNKNOWN, true, false, dryRun,
+ false);
+ }
}
catch (SVNException e) {
throw new VcsException(e);
assertUrl(source);
try {
- createClient(diffOptions, handler).doMerge(source.getURL(), source.getPegRevision(), Collections.singletonList(range), destination,
+ createClient(diffOptions, handler).doMerge(source.getURL(), source.getPegRevision(), singletonList(range), destination,
toDepth(depth), true, force, dryRun, recordOnly);
}
catch (SVNException e) {