IDEA-68087 hg: correctly parse "hg id" in case of 2 heads.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Wed, 4 May 2011 13:44:23 +0000 (17:44 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Wed, 4 May 2011 13:56:21 +0000 (17:56 +0400)
* HgWorkingCopyRevisionsCommand#identify returns 2 heads in the case of uncommitted merge.
* In all places we take the first id.
* HgIntegrateDialog removes current head accurate within "+".
* HgIntegrateDialog modifies UI components in UI thread.

[reviewed by irengrig]

plugins/hg4idea/src/org/zmlx/hg4idea/HgRevisionNumber.java
plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java
plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgDiffProvider.java
plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgIntegrateDialog.java
plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgUpdateTest.java

index 781aa96a8e3f69031ece6c7e849d25596e47b78b..639e858e2ae1161a160b7df07399d00cabdea14a 100644 (file)
@@ -127,7 +127,7 @@ public class HgRevisionNumber implements VcsRevisionNumber {
   /**
    * Returns the numeric part of the revision, i. e. the revision without trailing '+' if one exists. 
    */
-  private String getRevisionNumber() {
+  public String getRevisionNumber() {
     if (isWorkingVersion) {
       return revision.substring(0, revision.length()-1);
     }
index f6b19f46b8c75559011e450e4779c53079800cf0..a672d9f8d85a86988c85c15553f9d9f7c20d1beb 100644 (file)
@@ -127,22 +127,37 @@ public class HgWorkingCopyRevisionsCommand {
     else return HgRevisionNumber.NULL_REVISION_NUMBER;
   }
 
-  @Nullable
-  public HgRevisionNumber identify(@NotNull VirtualFile repo) {
+  /**
+   * Returns the result of 'hg id' execution, i.e. current state of the repository.
+   * @return one or two revision numbers. Two revisions is the case of unresolved merge. In other cases there are only one revision.
+   */
+  @NotNull
+  public Pair<HgRevisionNumber, HgRevisionNumber> identify(@NotNull VirtualFile repo) {
     HgCommandExecutor commandExecutor = new HgCommandExecutor(myProject);
     commandExecutor.setSilent(true);
     HgCommandResult result = commandExecutor.executeInCurrentThread(repo, "identify", Arrays.asList("--num", "--id"));
     if (result == null) {
-      return HgRevisionNumber.NULL_REVISION_NUMBER;
+      return Pair.create(HgRevisionNumber.NULL_REVISION_NUMBER, null);
     }
+
     final List<String> lines = result.getOutputLines();
     if (lines != null && !lines.isEmpty()) {
       String[] parts = StringUtils.split(lines.get(0), ' ');
+      String changesets = parts[0];
+      String revisions = parts[1];
       if (parts.length >= 2) {
-        return HgRevisionNumber.getInstance(parts[1], parts[0]);
+        if (changesets.indexOf('+') != changesets.lastIndexOf('+')) {
+          // in the case of unresolved merge we have 2 revisions at once, both current, so with "+"
+          // 9f2e6c02913c+b311eb4eb004+ 186+183+
+          String[] chsets = StringUtils.split(changesets, "+");
+          String[] revs = StringUtils.split(revisions, "+");
+          return Pair.create(HgRevisionNumber.getInstance(revs[0] + "+", chsets[0] + "+"), HgRevisionNumber.getInstance(revs[1] + "+", chsets[1] + "+"));
+        } else {
+          return Pair.create(HgRevisionNumber.getInstance(revisions, changesets), null);
+        }
       }
     }
-    return HgRevisionNumber.NULL_REVISION_NUMBER;
+    return Pair.create(HgRevisionNumber.NULL_REVISION_NUMBER, null);
   }
 
   /**
index b63b812ba89ed5c4b93a5284155c1139c2e67084..16b6a83801b254d0f676a9b071d797ab9af54338 100644 (file)
@@ -80,7 +80,7 @@ public class HgChangeProvider implements ChangeProvider {
     for (Map.Entry<VirtualFile, Collection<FilePath>> entry : HgUtil.groupFilePathsByHgRoots(myProject, files).entrySet()) {
       VirtualFile repo = entry.getKey();
 
-      final HgRevisionNumber workingRevision = new HgWorkingCopyRevisionsCommand(myProject).identify(repo);
+      final HgRevisionNumber workingRevision = new HgWorkingCopyRevisionsCommand(myProject).identify(repo).getFirst();
       final HgRevisionNumber parentRevision = new HgWorkingCopyRevisionsCommand(myProject).firstParent(repo);
       final Map<HgFile, HgResolveStatusEnum> list = new HgResolveCommand(myProject).getListSynchronously(repo);
 
index ef70094a8d4f0ec841c22988eed1fb7e10445c9e..786e1b6b501725ec2f72875cecd2a2723036aec9 100644 (file)
@@ -64,7 +64,7 @@ public class HgDiffProvider implements DiffProvider {
     }
 
     HgWorkingCopyRevisionsCommand command = new HgWorkingCopyRevisionsCommand(project);
-    HgRevisionNumber currentRevision = command.identify(vcsRoot);
+    HgRevisionNumber currentRevision = command.identify(vcsRoot).getFirst();
     if (currentRevision == null) {
       return null;
     }
index 3684a310fb9c735578e7d16e774cca6a1cd257ca..1af47c08ef8da6c474226a81b028174388446621 100644 (file)
@@ -34,6 +34,7 @@ import javax.swing.event.ChangeListener;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -175,15 +176,24 @@ public class HgIntegrateDialog implements Configurable {
           return;
         }
 
-        otherHeadRadioButton.setVisible(true);
-        otherHeadLabel.setVisible(true);
-
-        HgRevisionNumber currentParent = new HgWorkingCopyRevisionsCommand(project).identify(root);
-        heads.remove(currentParent);
+        HgRevisionNumber currentParent = new HgWorkingCopyRevisionsCommand(project).identify(root).getFirst();
+        for (Iterator<HgRevisionNumber> it = heads.iterator() ; it.hasNext(); ) {
+          final HgRevisionNumber rev = it.next();
+          if (rev.getRevisionNumber().equals(currentParent.getRevisionNumber())) {
+            it.remove();
+          }
+        }
 
         if (heads.size() == 1) {
-          otherHead = heads.get(0);
-          otherHeadLabel.setText(HgVcsMessages.message("hg4idea.integrate.other.head", otherHead.asString()));
+          UIUtil.invokeLaterIfNeeded(new Runnable() {
+            @Override
+            public void run() {
+              otherHeadRadioButton.setVisible(true);
+              otherHeadLabel.setVisible(true);
+              otherHead = heads.get(0);
+              otherHeadLabel.setText(HgVcsMessages.message("hg4idea.integrate.other.head", otherHead.asString()));
+            }
+          });
         } else {
           //apparently we are not at one of the heads
           disableOtherHeadsChoice();
@@ -193,8 +203,13 @@ public class HgIntegrateDialog implements Configurable {
   }
 
   private void disableOtherHeadsChoice() {
-    otherHeadLabel.setVisible(false);
-    otherHeadRadioButton.setVisible(false);
+    UIUtil.invokeLaterIfNeeded(new Runnable() {
+      @Override
+      public void run() {
+        otherHeadLabel.setVisible(false);
+        otherHeadRadioButton.setVisible(false);
+      }
+    });
   }
 
   private List<VirtualFile> pathsToFiles(Collection<FilePath> paths) {
index 94e5ab1de4ba8b1e2c8635ef4267d0e90b6923d6..ccf62f252c914b7010432892d3826e9af39d9ef0 100644 (file)
@@ -120,9 +120,9 @@ public class HgUpdateTest extends HgCollaborativeTest {
     List<HgRevisionNumber> branchHeads = new HgHeadsCommand(myProject, projectRepoVirtualFile).execute();
     assertEquals(branchHeads.size(), 2);
 
-    HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(myProject).identify(projectRepoVirtualFile);
+    HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(myProject).identify(projectRepoVirtualFile).getFirst();
     assertUpdateThroughPluginFails();
-    HgRevisionNumber parentAfterUpdate = new HgWorkingCopyRevisionsCommand(myProject).identify(projectRepoVirtualFile);
+    HgRevisionNumber parentAfterUpdate = new HgWorkingCopyRevisionsCommand(myProject).identify(projectRepoVirtualFile).getFirst();
     List<HgRevisionNumber> branchHeadsAfterUpdate = new HgHeadsCommand(myProject, projectRepoVirtualFile).execute();
 
     assertEquals(branchHeadsAfterUpdate.size(), 3);