[Mercurial] Moved Mercurial's MergeProvider to a separate class: HgMergeProvider.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Thu, 5 Aug 2010 14:30:38 +0000 (18:30 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Thu, 5 Aug 2010 14:30:38 +0000 (18:30 +0400)
plugins/hg4idea/src/org/zmlx/hg4idea/HgUtil.java
plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java
plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java [new file with mode: 0644]
plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgConflictResolver.java

index d08fbbb75f1dd011585ad94681a60a6bd6372548..0536b9fa0bbc5fbad11e9039a063045dc680436f 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.vcsUtil.VcsUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.zmlx.hg4idea.command.HgRemoveCommand;
+import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
 
 import java.io.*;
 import java.lang.reflect.InvocationTargetException;
@@ -224,4 +225,26 @@ public abstract class HgUtil {
     return vf;
   }
 
+  /**
+   * Gets the Mercurial root for the given file or throws a VcsException if non exists:
+   * the root should not only be in directory mappings, but also the .hg repository folder should exist.
+   * @see #getHgRootOrNull(com.intellij.openapi.project.Project, com.intellij.openapi.vcs.FilePath)
+   */
+  @NotNull
+  public static VirtualFile getHgRootOrThrow(Project project, VirtualFile vf) throws VcsException {
+    return getHgRootOrThrow(project, VcsUtil.getFilePath(vf.getPath()));
+  }
+
+  /**
+   * Checks is a merge operation is in progress on the given repository.
+   * Actually gets the number of parents of the current revision. If there are 2 parents, then a merge is going on. Otherwise there is
+   * only one parent. 
+   * @param project    project to work on.
+   * @param repository repository which is checked on merge.
+   * @return True if merge operation is in progress, false if there is no merge operation.
+   */
+  public static boolean isMergeInProgress(@NotNull Project project, VirtualFile repository) {
+    return new HgWorkingCopyRevisionsCommand(project).parents(repository).size() > 1;
+  }
+
 }
index 3ba9416d5d671b38794850d629b5bc193171e516..a88fb88251c22e41856b3a87c52820e9c5db834a 100644 (file)
@@ -34,6 +34,7 @@ import com.intellij.openapi.vcs.changes.ChangeProvider;
 import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
 import com.intellij.openapi.vcs.diff.DiffProvider;
 import com.intellij.openapi.vcs.history.VcsHistoryProvider;
+import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
 import com.intellij.openapi.vcs.update.UpdateEnvironment;
 import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
@@ -107,6 +108,7 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
   private boolean started = false;
   private HgVFSListener myVFSListener;
   private VirtualFileListener myDirStateChangeListener;
+  private final HgMergeProvider myMergeProvider;
 
   public HgVcs(Project project,
     HgGlobalSettings globalSettings, HgProjectSettings projectSettings,
@@ -126,6 +128,7 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
     integrateEnvironment = new HgIntegrateEnvironment(project);
     commitedChangesProvider = new HgCachingCommitedChangesProvider(project);
     myDirStateChangeListener = new HgDirStateChangeListener(myProject);
+    myMergeProvider = new HgMergeProvider(myProject);
   }
 
   public String getDisplayName() {
@@ -195,6 +198,11 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
     return annotationProvider;
   }
 
+  @Override
+  public MergeProvider getMergeProvider() {
+    return myMergeProvider;
+  }
+
   @Override
   public UpdateEnvironment getUpdateEnvironment() {
     if (!started) {
@@ -397,5 +405,4 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
     myVcsManager.addMessageToConsoleWindow(message, style);
   }
 
-
 }
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java
new file mode 100644 (file)
index 0000000..4074cf4
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2010 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.zmlx.hg4idea.provider;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.VcsBundle;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.merge.MergeData;
+import com.intellij.openapi.vcs.merge.MergeProvider;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcsUtil.VcsRunnable;
+import com.intellij.vcsUtil.VcsUtil;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.HgUtil;
+import org.zmlx.hg4idea.command.HgResolveCommand;
+
+/**
+ * @author Kirill Likhodedov
+ */
+public class HgMergeProvider implements MergeProvider {
+  private static final Logger LOG = Logger.getInstance(HgMergeProvider.class.getName());
+  private final Project myProject;
+
+  public HgMergeProvider(Project project) {
+    myProject = project;
+  }
+
+  @NotNull
+  @Override
+  public MergeData loadRevisions(final VirtualFile file) throws VcsException {
+    final MergeData mergeData = new MergeData();
+    final VcsRunnable runnable = new VcsRunnable() {
+      public void run() throws VcsException {
+        final HgResolveCommand.MergeData resolveData = new HgResolveCommand(myProject).getResolveData(HgUtil.getHgRootOrThrow(myProject, file), file);
+        mergeData.ORIGINAL = resolveData.getBase();
+        mergeData.CURRENT = resolveData.getLocal();
+        mergeData.LAST = resolveData.getOther();
+      }
+    };
+    VcsUtil.runVcsProcessWithProgress(runnable, VcsBundle.message("multiple.file.merge.loading.progress.title"), false, myProject);
+    return mergeData;
+  }
+
+  @Override
+  public void conflictResolvedForFile(VirtualFile file) {
+    try {
+      new HgResolveCommand(myProject).markResolved(HgUtil.getHgRootOrThrow(myProject, file), file);
+    } catch (VcsException e) {
+      LOG.error("Couldn't mark file resolved, because it is not under Mercurial root.");
+    }
+  }
+
+  @Override
+  public boolean isBinary(VirtualFile file) {
+    return file.getFileType().isBinary();
+  }
+
+}
index ef87157937ad530e3e3745f0bbefb6087f5b7f38..04fa375b1feb6ee9ac7cfed929ad39a4dd1f11ca 100644 (file)
@@ -15,9 +15,6 @@ package org.zmlx.hg4idea.provider.update;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.AbstractVcsHelper;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.merge.MergeData;
-import com.intellij.openapi.vcs.merge.MergeProvider;
 import com.intellij.openapi.vcs.update.FileGroup;
 import com.intellij.openapi.vcs.update.UpdatedFiles;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -35,7 +32,7 @@ import java.util.Map;
 
 public final class HgConflictResolver {
 
-  @NotNull private final Project project;
+  @NotNull private final Project myProject;
   private final UpdatedFiles updatedFiles;
 
   public HgConflictResolver(@NotNull Project project) {
@@ -43,12 +40,12 @@ public final class HgConflictResolver {
   }
 
   public HgConflictResolver(Project project, UpdatedFiles updatedFiles) {
-    this.project = project;
+    this.myProject = project;
     this.updatedFiles = updatedFiles;
   }
 
   public void resolve(final VirtualFile repo) {
-    Map<HgFile, HgResolveStatusEnum> resolves = new HgResolveCommand(project).list(repo);
+    Map<HgFile, HgResolveStatusEnum> resolves = new HgResolveCommand(myProject).list(repo);
     final List<VirtualFile> conflicts = new ArrayList<VirtualFile>();
     for (Map.Entry<HgFile, HgResolveStatusEnum> entry : resolves.entrySet()) {
       File file = entry.getKey().getFile();
@@ -76,33 +73,8 @@ public final class HgConflictResolver {
     }
 
     if (!ApplicationManager.getApplication().isUnitTestMode()) {
-      AbstractVcsHelper.getInstance(project).showMergeDialog(conflicts, buildMergeProvider(repo));
+      AbstractVcsHelper.getInstance(myProject).showMergeDialog(conflicts, HgVcs.getInstance(myProject).getMergeProvider());
     }
   }
 
-  private MergeProvider buildMergeProvider(final VirtualFile repo) {
-    return new MergeProvider() {
-      @NotNull
-      public MergeData loadRevisions(VirtualFile file) throws VcsException {
-
-        HgResolveCommand.MergeData resolveData = new HgResolveCommand(project).getResolveData(repo, file);
-
-        MergeData mergeData = new MergeData();
-        mergeData.ORIGINAL = resolveData.getBase();
-        mergeData.CURRENT = resolveData.getLocal();
-        mergeData.LAST = resolveData.getOther();
-        return mergeData;
-      }
-
-      public void conflictResolvedForFile(VirtualFile file) {
-        new HgResolveCommand(project).markResolved(repo, file);
-      }
-
-      public boolean isBinary(VirtualFile file) {
-        return false;
-      }
-    };
-  }
-
-
 }