[git] Compare with Branch for directories
authorKirill Likhodedov <Kirill.Likhodedov@jetbrains.com>
Thu, 26 Jul 2012 16:06:25 +0000 (20:06 +0400)
committerKirill Likhodedov <Kirill.Likhodedov@jetbrains.com>
Thu, 26 Jul 2012 16:07:16 +0000 (20:07 +0400)
Reuse GitDiffFromHistoryHandler to display diff for file or directory.
Make hacky revision numbers with human readable revisions (branch names) for file diff.

plugins/git4idea/src/git4idea/actions/GitCompareWithBranchAction.java
plugins/git4idea/src/git4idea/history/GitDiffFromHistoryHandler.java

index 9a6cb5ee090f6bc97f6fda7531455380a874c3e0..d6a347fe9f42b386efd2c968879bdb00f7f39e27 100644 (file)
@@ -20,8 +20,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -30,21 +28,19 @@ import com.intellij.openapi.vcs.FilePathImpl;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.history.CurrentRevision;
 import com.intellij.openapi.vcs.history.VcsFileRevision;
-import com.intellij.openapi.vcs.history.VcsHistoryUtil;
-import com.intellij.openapi.vcs.history.VcsRevisionNumber;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.components.JBList;
 import git4idea.GitBranch;
 import git4idea.GitFileRevision;
 import git4idea.GitRevisionNumber;
 import git4idea.GitUtil;
+import git4idea.history.GitDiffFromHistoryHandler;
 import git4idea.history.GitHistoryUtils;
 import git4idea.repo.GitRepository;
 import git4idea.repo.GitRepositoryManager;
 import git4idea.util.GitUIUtil;
 import org.jetbrains.annotations.NotNull;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -132,7 +128,7 @@ public class GitCompareWithBranchAction extends DumbAwareAction {
     }
 
     VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
-    if (vFiles == null || vFiles.length != 1 || vFiles[0] == null || vFiles[0].isDirectory()) { // only 1 file for now, not for dirs
+    if (vFiles == null || vFiles.length != 1 || vFiles[0] == null) { // only 1 file for now
       presentation.setEnabled(false);
       presentation.setVisible(true);
       return;
@@ -175,43 +171,42 @@ public class GitCompareWithBranchAction extends DumbAwareAction {
 
     @Override
     public void run() {
-      new Task.Backgroundable(myProject, "Comparing...") {
-        @Override public void run(@NotNull ProgressIndicator indicator) {
-          String branchToCompare = myList.getSelectedValue().toString();
-          try {
-            showDiffWithBranch(myProject, myFile, myHead, branchToCompare);
-          }
-          catch (VcsException e) {
-            if (e.getMessage().contains("exists on disk, but not in")) {
-              fileDoesntExistInBranchError(myProject, myFile, branchToCompare);
-            } else {
-              GitUIUtil.notifyError(myProject, "Couldn't compare with branch",
-                                    "Couldn't compare file [" + myFile + "] with selected branch [" + myList.getSelectedValue() + "]",
-                                    false, e);
-            }
-          }
+      String branchToCompare = myList.getSelectedValue().toString();
+      try {
+        showDiffWithBranch(myProject, myFile, myHead, branchToCompare);
+      }
+      catch (VcsException e) {
+        if (e.getMessage().contains("exists on disk, but not in")) {
+          fileDoesntExistInBranchError(myProject, myFile, branchToCompare);
+        } else {
+          GitUIUtil.notifyError(myProject, "Couldn't compare with branch",
+                                String.format("Couldn't compare file [%s] with selected branch [%s]", myFile, myList.getSelectedValue()),
+                                false, e);
         }
-      }.queue();
+      }
     }
 
-    private static void showDiffWithBranch(@NotNull Project project, @NotNull VirtualFile file, @NotNull String head, @NotNull String branchToCompare) throws VcsException {
+    private static void showDiffWithBranch(@NotNull Project project, @NotNull VirtualFile file, @NotNull String head,
+                                           @NotNull String branchToCompare) throws VcsException {
       final FilePath filePath = new FilePathImpl(file);
-      final VcsRevisionNumber currentRevisionNumber = GitHistoryUtils.getCurrentRevision(project, filePath, head);
-      final VcsRevisionNumber compareRevisionNumber = GitHistoryUtils.getCurrentRevision(project, filePath, branchToCompare);
+      // we could use something like GitRepository#getCurrentRevision here,
+      // but this way we can easily identify if the file is available in the branch
+      final GitRevisionNumber currentRevisionNumber = (GitRevisionNumber)GitHistoryUtils.getCurrentRevision(project, filePath, head);
+      final GitRevisionNumber compareRevisionNumber =
+        (GitRevisionNumber)GitHistoryUtils.getCurrentRevision(project, filePath, branchToCompare);
+
       if (compareRevisionNumber == null) {
         fileDoesntExistInBranchError(project, file, branchToCompare);
         return;
       }
-      final VcsFileRevision compareRevision = new GitFileRevision(project, filePath, (GitRevisionNumber)compareRevisionNumber, false);
-      final String currentTitle = currentRevisionNumber != null ? ((GitRevisionNumber)currentRevisionNumber).getShortRev() + " on " + head : "Local changes on " + head;
-      final String compareTitle = ((GitRevisionNumber)compareRevisionNumber).getShortRev() + " on " + branchToCompare;
-
-      try {
-        VcsHistoryUtil.showDiff(project, filePath, new CurrentRevision(file, currentRevisionNumber), compareRevision, currentTitle, compareTitle);
-      }
-      catch (IOException e) {
-        throw new VcsException(String.format("Couldn't show diff for file [%s], head [%s] and branch [%s]", file.getPresentableUrl(), head, branchToCompare), e);
-      }
+      LOG.assertTrue(currentRevisionNumber != null,
+                     String.format("Current revision number is null for file [%s] and branch [%s]", filePath, head));
+
+      // constructing the revision with human readable name (will work for files comparison however).
+      final VcsFileRevision compareRevision =
+        new GitFileRevision(project, filePath, new GitRevisionNumber(branchToCompare, compareRevisionNumber.getTimestamp()), false);
+      CurrentRevision currentRevision = new CurrentRevision(file, new GitRevisionNumber(head, currentRevisionNumber.getTimestamp()));
+      new GitDiffFromHistoryHandler(project).showDiff(new FilePathImpl(file), compareRevision, currentRevision);
     }
 
     private static void fileDoesntExistInBranchError(Project project, VirtualFile file, String branchToCompare) {
index 41be21de42ea43e803475139a402fe0953fbb38f..fe44b1cdd4b5d527ccd25d322d913e9a43c0e21b 100644 (file)
@@ -64,7 +64,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
  *
  * @author Kirill Likhodedov
  */
-class GitDiffFromHistoryHandler implements DiffFromHistoryHandler {
+public class GitDiffFromHistoryHandler implements DiffFromHistoryHandler {
   
   private static final Logger LOG = Logger.getInstance(GitDiffFromHistoryHandler.class);
 
@@ -72,7 +72,7 @@ class GitDiffFromHistoryHandler implements DiffFromHistoryHandler {
   @NotNull private final Git myGit;
   @NotNull private final GitRepositoryManager myRepositoryManager;
 
-  GitDiffFromHistoryHandler(@NotNull Project project) {
+  public GitDiffFromHistoryHandler(@NotNull Project project) {
     myProject = project;
     myGit = ServiceManager.getService(project, Git.class);
     myRepositoryManager = GitUtil.getRepositoryManager(project);