svn: Use automatic sync/reintegrate merges if merge info is supported
authorKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Mon, 10 Oct 2016 12:06:39 +0000 (15:06 +0300)
committerKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Tue, 11 Oct 2016 01:28:23 +0000 (04:28 +0300)
Do not specify certain revisions for "Merge All" operation if merge info
is supported - svn detects necessary revisions and performs
corresponding merge operation automatically.

plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/BaseMergeTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/BranchMerger.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/CheckRepositorySupportsMergeInfoTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/CmdMergeClient.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/MergeAllOrSelectedChooserTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/MergeAllWithBranchCopyPointTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/MergeCalculatorTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/MergeClient.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnKitMergeClient.java

index 89261b92936cddbc8fd6d426fd5ca6a807611ce7..0d07f3e881dbab6349aff01c5d4ad41abe4a6d57 100644 (file)
@@ -85,11 +85,13 @@ public abstract class BaseMergeTask extends TaskDescriptor {
   }
 
   @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)))
     );
   }
 
index 9f99c896bd674b5eb1aa35b9cbb61f8788189c05..e086f751e18d32fa2cf92a549c9a0046f0fba3c9 100644 (file)
@@ -27,6 +27,7 @@ import org.jetbrains.idea.svn.diff.DiffOptions;
 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;
@@ -44,12 +45,16 @@ public class BranchMerger implements IMerger {
   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;
@@ -58,11 +63,13 @@ public class BranchMerger implements IMerger {
     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() {
@@ -74,13 +81,15 @@ public class BranchMerger implements IMerger {
 
     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);
     }
   }
 
index d83f1fcbbce63037fa75e07aae30d7bac9ae0dae..0a851711695a515f7324ccd1bb08d88ceb93f6bc 100644 (file)
@@ -32,7 +32,7 @@ public class CheckRepositorySupportsMergeInfoTask extends BaseMergeTask {
 
   @Override
   public void run() {
-    next(supportsMergeInfo() ? getChooseMergeTypeTasks() : getMergeAllTasks());
+    next(supportsMergeInfo() ? getChooseMergeTypeTasks() : getMergeAllTasks(false));
   }
 
   private boolean supportsMergeInfo() {
index 9236f277b0b288703b2dbe72bda83deca0d9711b..87fa1abe844f24c7f0847e5d9b870d1a175b0118 100644 (file)
@@ -25,13 +25,14 @@ public class CmdMergeClient extends BaseSvnClient implements MergeClient {
   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);
   }
index 45e81196e3d645a29b8914ee2e1a351d137ebfc8..57af2f6c48207cf5335c5f32149440777fa592dd 100644 (file)
@@ -29,7 +29,7 @@ public class MergeAllOrSelectedChooserTask extends BaseMergeTask {
     //noinspection EnumSwitchStatementWhichMissesCases
     switch (myInteraction.selectMergeVariant()) {
       case all:
-        next(getMergeAllTasks());
+        next(getMergeAllTasks(true));
         break;
       case showLatest:
         LoadRecentBranchRevisions loader = new LoadRecentBranchRevisions(myMergeProcess, -1);
index e2af3b26cf02bd020e7dc61d4284f41273bb17c4..1adc39a31948b942bf9abe587e830ea619f4f22d 100644 (file)
@@ -21,10 +21,14 @@ import org.jetbrains.annotations.NotNull;
 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
@@ -44,8 +48,11 @@ public class MergeAllWithBranchCopyPointTask extends BaseMergeTask {
 
   @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);
+    };
   }
 }
index 5c2adca9be65d30c38efccfe19b76f1f82e45c59..a48a6931e978d3688e98f47ffd3e814b736ebc69 100644 (file)
@@ -148,7 +148,7 @@ public class MergeCalculatorTask extends BaseMergeTask {
           end();
           break;
         case all:
-          next(getMergeAllTasks());
+          next(getMergeAllTasks(true));
           break;
         default:
           List<CommittedChangeList> lists = result.getSelectedLists();
index d32ea2951cd0ea76c275e8732ea470ffa42b8007..b7f5597550fd74cd8e18fde0d138b84996c37f37 100644 (file)
@@ -20,6 +20,7 @@ public interface MergeClient extends SvnClient {
   void merge(@NotNull SvnTarget source,
              @NotNull File destination,
              boolean dryRun,
+             boolean reintegrate,
              @Nullable DiffOptions diffOptions,
              @Nullable ProgressTracker handler) throws VcsException;
 
index 51cbc7c10409e042d04e0aff9d34207fcf32e70f..e4fcf1c5db00935468c83e482248ce1ef83210a0 100644 (file)
@@ -7,28 +7,43 @@ import org.jetbrains.idea.svn.api.BaseSvnClient;
 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);
@@ -48,7 +63,7 @@ public class SvnKitMergeClient extends BaseSvnClient implements MergeClient {
     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) {