[Mercurial] More methods in HgWorkingCopyRevisionsCommand, code style.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 6 Aug 2010 11:27:01 +0000 (15:27 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 6 Aug 2010 11:27:01 +0000 (15:27 +0400)
plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java

index 08e31fb3c0f97def2ef4ebeb002c6328d5b8b3f4..48df53bf286c9a1b84556a2d271c30d43e020a89 100644 (file)
@@ -13,6 +13,7 @@
 package org.zmlx.hg4idea.command;
 
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.apache.commons.lang.StringUtils;
 import org.jetbrains.annotations.NotNull;
@@ -21,19 +22,60 @@ import org.zmlx.hg4idea.HgRevisionNumber;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 
+/**
+ * Commands to get revision numbers. These are: parents, id, tip.
+ */
 public class HgWorkingCopyRevisionsCommand {
 
-  private final Project project;
+  private final Project myProject;
 
   public HgWorkingCopyRevisionsCommand(Project project) {
-    this.project = project;
+    myProject = project;
   }
 
+  /**
+   * Current repository revision(s).
+   * @param repo repository to work on.
+   * @return List of parent's revision numbers.
+   * @see #parents(com.intellij.openapi.vfs.VirtualFile, com.intellij.openapi.vfs.VirtualFile, org.zmlx.hg4idea.HgRevisionNumber)
+   * TODO: return Pair
+   */
   @NotNull
   public List<HgRevisionNumber> parents(@NotNull VirtualFile repo) {
-    return getRevisions(repo, "parents");
+    final Pair<HgRevisionNumber, HgRevisionNumber> parents = parents(repo, null);
+    final List<HgRevisionNumber> result = new ArrayList<HgRevisionNumber>(2);
+    result.add(parents.first);
+    result.add(parents.second);
+    return result;
+  }
+
+  /**
+   * @see #parents(com.intellij.openapi.vfs.VirtualFile, com.intellij.openapi.vfs.VirtualFile, org.zmlx.hg4idea.HgRevisionNumber)
+   */
+  @NotNull
+  public Pair<HgRevisionNumber, HgRevisionNumber> parents(@NotNull VirtualFile repo, @Nullable VirtualFile file) {
+    return parents(repo, file, null);
+  }
+
+  /**
+   * Parent(s) of the given revision of the given file.
+   * @param repo     repository to work on.
+   * @param file     file which revision's parents we are interested in. If null, the history of the whole repository is considered.
+   * @param revision revision number which parent is wanted. If null, the last revision is taken. 
+   * @return One or two (in case of a merge commit) parents of the given revision. Or even zero in case of a fresh repository.
+   *         So one should check pair elements for null.
+   */
+  @NotNull
+  public Pair<HgRevisionNumber, HgRevisionNumber> parents(@NotNull VirtualFile repo, @Nullable VirtualFile file, @Nullable HgRevisionNumber revision) {
+    final List<HgRevisionNumber> revisions = getRevisions(repo, "parents", file, revision);
+    switch (revisions.size()) {
+      case 1: return Pair.create(revisions.get(0), null);
+      case 2: return Pair.create(revisions.get(1), null);
+      default: return Pair.create(null, null);
+    }
   }
 
   @Nullable
@@ -50,7 +92,7 @@ public class HgWorkingCopyRevisionsCommand {
 
   @Nullable
   public HgRevisionNumber tip(@NotNull VirtualFile repo) {
-    List<HgRevisionNumber> tips = getRevisions(repo, "tip");
+    List<HgRevisionNumber> tips = getRevisions(repo, "tip", null, null);
     if (tips.size() > 1) {
       throw new IllegalStateException("There cannot be multiple tips");
     }
@@ -62,7 +104,7 @@ public class HgWorkingCopyRevisionsCommand {
 
   @Nullable
   public HgRevisionNumber identify(@NotNull VirtualFile repo) {
-    HgCommandService commandService = HgCommandService.getInstance(project);
+    HgCommandService commandService = HgCommandService.getInstance(myProject);
     HgCommandResult result = commandService.execute(
       repo, "identify", Arrays.asList("--num", "--id")
     );
@@ -79,21 +121,36 @@ public class HgWorkingCopyRevisionsCommand {
     return null;
   }
 
+  /**
+   * Returns the list of revisions returned by one mercurial commands (parents, identify, tip).
+   * Executed a command on the whole repository or on the given file.
+   * @param repo     repository to execute on.
+   * @param command  command to execute.
+   * @param file     file which revisions are wanted. If <code><b>null</b></code> then repository revisions are considered.
+   * @param revision revision to execute on. If <code><b>null</b></code> then executed without the '-r' parameter, i.e. on the latest revision.
+   * @return List of revisions.
+   */
   @NotNull
-  private List<HgRevisionNumber> getRevisions(VirtualFile repo, String command) {
-    HgCommandService commandService = HgCommandService.getInstance(project);
-    HgCommandResult result = commandService.execute(
-      repo, command, Arrays.asList("--template", "{rev}|{node|short}\\n")
-    );
+  private List<HgRevisionNumber> getRevisions(@NotNull VirtualFile repo, @NotNull String command, @Nullable VirtualFile file, @Nullable HgRevisionNumber revision) {
+    final List<String> args = new LinkedList<String>();
+    args.add("--template");
+    args.add("{rev}|{node|short}\\n");
+    if (revision != null) {
+      args.add("-r");
+      args.add(revision.getChangeset());
+    }
+    if (file != null) { // NB: this must be the last argument
+      args.add(file.getPath());
+    }
+    final HgCommandResult result = HgCommandService.getInstance(myProject).execute(repo, command, args);
 
     if (result == null) {
       return new ArrayList<HgRevisionNumber>(0);
     }
-    List<String> lines = result.getOutputLines();
-    List<HgRevisionNumber> revisions = new ArrayList<HgRevisionNumber>(lines.size());
-    
+    final List<String> lines = result.getOutputLines();
+    final List<HgRevisionNumber> revisions = new ArrayList<HgRevisionNumber>(lines.size());
     for(String line: lines) {
-      String[] parts = StringUtils.split(line, '|');
+      final String[] parts = StringUtils.split(line, '|');
       revisions.add(HgRevisionNumber.getInstance(parts[0], parts[1]));
     }