git4idea: IDEADEV-33099: non-git files are now handled more gracefully
authorConstantine Plotnikov <Constantine.Plotnikov@jetbrains.com>
Mon, 18 May 2009 11:59:52 +0000 (15:59 +0400)
committerConstantine Plotnikov <Constantine.Plotnikov@jetbrains.com>
Mon, 18 May 2009 11:59:52 +0000 (15:59 +0400)
plugins/git4idea/src/git4idea/GitUtil.java
plugins/git4idea/src/git4idea/GitVcs.java
plugins/git4idea/src/git4idea/actions/GitShowAllSubmittedFilesAction.java
plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
plugins/git4idea/src/git4idea/merge/GitMergeProvider.java
plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java
plugins/git4idea/src/git4idea/vfs/GitVFSListener.java

index d50fb315e0c3d87a45e5215e526d550463385912..1f4cf2c35aa79bcff02b642d86233025d9654c11 100644 (file)
@@ -55,10 +55,10 @@ public class GitUtil {
    *
    * @param virtualFiles files to sort
    * @return sorted files
-   * @throws IllegalArgumentException if non git files are passed
+   * @throws VcsException if non git files are passed
    */
   @NotNull
-  public static Map<VirtualFile, List<VirtualFile>> sortFilesByGitRoot(@NotNull Collection<VirtualFile> virtualFiles) {
+  public static Map<VirtualFile, List<VirtualFile>> sortFilesByGitRoot(@NotNull Collection<VirtualFile> virtualFiles) throws VcsException {
     return sortFilesByGitRoot(virtualFiles, false);
   }
 
@@ -68,9 +68,10 @@ public class GitUtil {
    * @param virtualFiles files to sort
    * @param ignoreNonGit if true, non-git files are ignored
    * @return sorted files
-   * @throws IllegalArgumentException if non git files are passed when {@code ignoreNonGit} is false
+   * @throws VcsException if non git files are passed when {@code ignoreNonGit} is false
    */
-  public static Map<VirtualFile, List<VirtualFile>> sortFilesByGitRoot(Collection<VirtualFile> virtualFiles, boolean ignoreNonGit) {
+  public static Map<VirtualFile, List<VirtualFile>> sortFilesByGitRoot(Collection<VirtualFile> virtualFiles, boolean ignoreNonGit)
+    throws VcsException {
     Map<VirtualFile, List<VirtualFile>> result = new HashMap<VirtualFile, List<VirtualFile>>();
     for (VirtualFile file : virtualFiles) {
       final VirtualFile vcsRoot = gitRootOrNull(file);
@@ -79,7 +80,7 @@ public class GitUtil {
           continue;
         }
         else {
-          throw new IllegalArgumentException("The file " + file.getPath() + " is not under Git");
+          throw new VcsException("The file " + file.getPath() + " is not under Git");
         }
       }
       List<VirtualFile> files = result.get(vcsRoot);
@@ -117,9 +118,9 @@ public class GitUtil {
    *
    * @param files files to sort.
    * @return the map from root to the files under the root
-   * @throws IllegalArgumentException if non git files are passed
+   * @throws VcsException if non git files are passed
    */
-  public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot(final Collection<FilePath> files) {
+  public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot(final Collection<FilePath> files) throws VcsException {
     return sortFilePathsByGitRoot(files, false);
   }
 
@@ -129,9 +130,10 @@ public class GitUtil {
    * @param files        files to sort.
    * @param ignoreNonGit if true, non-git files are ignored
    * @return the map from root to the files under the root
-   * @throws IllegalArgumentException if non git files are passed when {@code ignoreNonGit} is false
+   * @throws VcsException if non git files are passed when {@code ignoreNonGit} is false
    */
-  public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot(Collection<FilePath> files, boolean ignoreNonGit) {
+  public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot(Collection<FilePath> files, boolean ignoreNonGit)
+    throws VcsException {
     Map<VirtualFile, List<FilePath>> rc = new HashMap<VirtualFile, List<FilePath>>();
     for (FilePath p : files) {
       VirtualFile root = getGitRootOrNull(p);
@@ -140,7 +142,7 @@ public class GitUtil {
           continue;
         }
         else {
-          throw new IllegalArgumentException("The file " + p.getPath() + " is not under Git");
+          throw new VcsException("The file " + p.getPath() + " is not under Git");
         }
       }
       List<FilePath> l = rc.get(root);
@@ -290,13 +292,14 @@ public class GitUtil {
    * @param filePath a file path
    * @return git root for the file
    * @throws IllegalArgumentException if the file is not under git
+   * @throws VcsException             if the file is not under git
    */
-  public static VirtualFile getGitRoot(final FilePath filePath) {
+  public static VirtualFile getGitRoot(final FilePath filePath) throws VcsException {
     VirtualFile root = getGitRootOrNull(filePath);
     if (root != null) {
       return root;
     }
-    throw new IllegalArgumentException("The file " + filePath + " is not under git.");
+    throw new VcsException("The file " + filePath + " is not under git.");
   }
 
   /**
@@ -322,15 +325,15 @@ public class GitUtil {
    *
    * @param file the file to check
    * @return git root for the file
-   * @throws IllegalArgumentException if the file is not under git
+   * @throws VcsException if the file is not under git
    */
-  public static VirtualFile getGitRoot(@NotNull final VirtualFile file) {
+  public static VirtualFile getGitRoot(@NotNull final VirtualFile file) throws VcsException {
     final VirtualFile root = gitRootOrNull(file);
     if (root != null) {
       return root;
     }
     else {
-      throw new IllegalArgumentException("The file " + file.getPath() + " is not under git.");
+      throw new VcsException("The file " + file.getPath() + " is not under git.");
     }
   }
 
index 55ada685413dd7fa55f5a55971f1e40b1129914e..b065787575d83832d9ebb2e0a5a7f0f5f83632c7 100644 (file)
@@ -295,8 +295,8 @@ public class GitVcs extends AbstractVcs {
       return new GitRevisionNumber(rev, d);
     }
     if (path != null) {
-      VirtualFile root = GitUtil.getGitRoot(path);
       try {
+        VirtualFile root = GitUtil.getGitRoot(path);
         return GitRevisionNumber.resolve(myProject, root, revision);
       }
       catch (VcsException e) {
@@ -503,7 +503,11 @@ public class GitVcs extends AbstractVcs {
 
     for (int i = 1; i < in.size(); i++) {
       final VirtualFile child = in.get(i);
-      final VirtualFile childRoot = GitUtil.getGitRoot(child);
+      final VirtualFile childRoot = GitUtil.gitRootOrNull(child);
+      if (childRoot == null) {
+        // non-git file actually, skip it
+        continue;
+      }
       for (int j = i - 1; j >= 0; --j) {
         final VirtualFile parent = in.get(j);
         // the method check both that parent is an ancestor of the child and that they share common git root
index 56d735ceede1aeeb7ff4b99d9a783fcdb6a3ff6c..5c5e78a0ac992eb74482af97ebb513920c59b5e6 100644 (file)
@@ -92,9 +92,8 @@ public class GitShowAllSubmittedFilesAction extends AnAction {
    * @param file     file affected by the revision
    */
   public static void showSubmittedFiles(final Project project, final String revision, final VirtualFile file) {
-    VirtualFile vcsRoot = GitUtil.getGitRoot(file);
-    assert vcsRoot != null;
     try {
+      VirtualFile vcsRoot = GitUtil.getGitRoot(file);
       final CommittedChangeList changeList = GitChangeUtils.getRevisionChanges(project, vcsRoot, revision);
       if (changeList != null) {
         AbstractVcsHelper.getInstance(project).showChangesListBrowser(changeList, getTitle(revision));
index 757f181b0a348767a0411a2171f4839e7a1ccb66..0cfabdc087838da5a9c939c3234a587234681d0e 100644 (file)
@@ -148,7 +148,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
   @SuppressWarnings({"ConstantConditions"})
   public List<VcsException> commit(@NotNull List<Change> changes, @NotNull String message) {
     List<VcsException> exceptions = new ArrayList<VcsException>();
-    Map<VirtualFile, List<Change>> sortedChanges = sortChangesByGitRoot(changes);
+    Map<VirtualFile, List<Change>> sortedChanges = sortChangesByGitRoot(changes, exceptions);
     for (Map.Entry<VirtualFile, List<Change>> entry : sortedChanges.entrySet()) {
       Set<FilePath> files = new HashSet<FilePath>();
       final VirtualFile root = entry.getKey();
@@ -442,7 +442,14 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
    */
   public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> files) {
     ArrayList<VcsException> rc = new ArrayList<VcsException>();
-    Map<VirtualFile, List<FilePath>> sortedFiles = GitUtil.sortFilePathsByGitRoot(files);
+    Map<VirtualFile, List<FilePath>> sortedFiles;
+    try {
+      sortedFiles = GitUtil.sortFilePathsByGitRoot(files);
+    }
+    catch (VcsException e) {
+      rc.add(e);
+      return rc;
+    }
     for (Map.Entry<VirtualFile, List<FilePath>> e : sortedFiles.entrySet()) {
       try {
         final VirtualFile root = e.getKey();
@@ -488,7 +495,14 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
    */
   public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
     ArrayList<VcsException> rc = new ArrayList<VcsException>();
-    Map<VirtualFile, List<VirtualFile>> sortedFiles = GitUtil.sortFilesByGitRoot(files);
+    Map<VirtualFile, List<VirtualFile>> sortedFiles;
+    try {
+      sortedFiles = GitUtil.sortFilesByGitRoot(files);
+    }
+    catch (VcsException e) {
+      rc.add(e);
+      return rc;
+    }
     for (Map.Entry<VirtualFile, List<VirtualFile>> e : sortedFiles.entrySet()) {
       try {
         final VirtualFile root = e.getKey();
@@ -505,10 +519,11 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
   /**
    * Sort changes by roots
    *
-   * @param changes a change list
+   * @param changes    a change list
+   * @param exceptions exceptions to collect
    * @return sorted changes
    */
-  private Map<VirtualFile, List<Change>> sortChangesByGitRoot(@NotNull List<Change> changes) {
+  private static Map<VirtualFile, List<Change>> sortChangesByGitRoot(@NotNull List<Change> changes, List<VcsException> exceptions) {
     Map<VirtualFile, List<Change>> result = new HashMap<VirtualFile, List<Change>>();
     for (Change change : changes) {
       final ContentRevision afterRevision = change.getAfterRevision();
@@ -517,7 +532,14 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
       assert beforeRevision != null || afterRevision != null;
       // note that any path will work, because changes could happen within single vcs root
       final FilePath filePath = afterRevision != null ? afterRevision.getFile() : beforeRevision.getFile();
-      final VirtualFile vcsRoot = GitUtil.getGitRoot(filePath);
+      final VirtualFile vcsRoot;
+      try {
+        vcsRoot = GitUtil.getGitRoot(filePath);
+      }
+      catch (VcsException e) {
+        exceptions.add(e);
+        continue;
+      }
       List<Change> changeList = result.get(vcsRoot);
       if (changeList == null) {
         changeList = new ArrayList<Change>();
index 80033e1ab824d8e62f8f5ad2fbc5ed3c5428337d..3bbdb1163129c14771be2436f1f15b8566f93a72 100644 (file)
@@ -202,16 +202,16 @@ public class GitMergeProvider implements MergeProvider2 {
      */
     MyMergeSession(List<VirtualFile> filesToMerge) {
       // get conflict type by the file
-      for (Map.Entry<VirtualFile, List<VirtualFile>> e : GitUtil.sortFilesByGitRoot(filesToMerge).entrySet()) {
-        Map<String, Conflict> cs = new HashMap<String, Conflict>();
-        VirtualFile root = e.getKey();
-        List<VirtualFile> files = e.getValue();
-        GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitHandler.LS_FILES);
-        h.setNoSSH(true);
-        h.setStdoutSuppressed(true);
-        h.addParameters("--exclude-standard", "--unmerged", "-t", "-z");
-        h.endOptions();
-        try {
+      try {
+        for (Map.Entry<VirtualFile, List<VirtualFile>> e : GitUtil.sortFilesByGitRoot(filesToMerge).entrySet()) {
+          Map<String, Conflict> cs = new HashMap<String, Conflict>();
+          VirtualFile root = e.getKey();
+          List<VirtualFile> files = e.getValue();
+          GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitHandler.LS_FILES);
+          h.setNoSSH(true);
+          h.setStdoutSuppressed(true);
+          h.addParameters("--exclude-standard", "--unmerged", "-t", "-z");
+          h.endOptions();
           String output = h.run();
           StringScanner s = new StringScanner(output);
           while (s.hasMoreData()) {
@@ -256,10 +256,9 @@ public class GitMergeProvider implements MergeProvider2 {
             myConflicts.put(f, c);
           }
         }
-        catch (VcsException ex) {
-          throw new IllegalStateException("The git operation should fail in this context", ex);
-        }
-
+      }
+      catch (VcsException ex) {
+        throw new IllegalStateException("The git operation should not fail in this context", ex);
       }
     }
 
index 7a938725d2a0ce2c3d710cd602b438d59a5759d1..d915e89711e11bb200efd901a939f7e8fabbd0f5 100644 (file)
@@ -103,20 +103,20 @@ public class GitRollbackEnvironment implements RollbackEnvironment {
         case NEW:
           // note that this the only change that could happen
           // for HEAD-less working directories.
-          registerFile(myProject, toUnindex, c.getAfterRevision().getFile());
+          registerFile(toUnindex, c.getAfterRevision().getFile(), exceptions);
           break;
         case MOVED:
-          registerFile(myProject, toRevert, c.getBeforeRevision().getFile());
-          registerFile(myProject, toUnindex, c.getAfterRevision().getFile());
+          registerFile(toRevert, c.getBeforeRevision().getFile(), exceptions);
+          registerFile(toUnindex, c.getAfterRevision().getFile(), exceptions);
           toDelete.add(c.getAfterRevision().getFile());
           break;
         case MODIFICATION:
           // note that changes are also removed from index, if they got into index somehow
-          registerFile(myProject, toUnindex, c.getBeforeRevision().getFile());
-          registerFile(myProject, toRevert, c.getBeforeRevision().getFile());
+          registerFile(toUnindex, c.getBeforeRevision().getFile(), exceptions);
+          registerFile(toRevert, c.getBeforeRevision().getFile(), exceptions);
           break;
         case DELETED:
-          registerFile(myProject, toRevert, c.getBeforeRevision().getFile());
+          registerFile(toRevert, c.getBeforeRevision().getFile(), exceptions);
           break;
       }
     }
@@ -196,12 +196,19 @@ public class GitRollbackEnvironment implements RollbackEnvironment {
   /**
    * Register file in the map under appropriate root
    *
-   * @param project the context project
-   * @param files   a map to use
-   * @param file    a file to register
+   * @param files      a map to use
+   * @param file       a file to register
+   * @param exceptions the list of exceptions to update
    */
-  private static void registerFile(Project project, Map<VirtualFile, List<FilePath>> files, FilePath file) {
-    final VirtualFile root = GitUtil.getGitRoot(file);
+  private static void registerFile(Map<VirtualFile, List<FilePath>> files, FilePath file, List<VcsException> exceptions) {
+    final VirtualFile root;
+    try {
+      root = GitUtil.getGitRoot(file);
+    }
+    catch (VcsException e) {
+      exceptions.add(e);
+      return;
+    }
     List<FilePath> paths = files.get(root);
     if (paths == null) {
       paths = new ArrayList<FilePath>();
index eda7c52003b4116d8968deb6d75f0ad88a120059..3b7a86c815e28c525fcd879e0e27173f57618c73 100644 (file)
@@ -71,7 +71,14 @@ public class GitVFSListener extends VcsVFSListener {
    * {@inheritDoc}
    */
   protected void performAdding(final Collection<VirtualFile> addedFiles, final Map<VirtualFile, VirtualFile> copyFromMap) {
-    Map<VirtualFile, List<VirtualFile>> sortedFiles = GitUtil.sortFilesByGitRoot(addedFiles, true);
+    Map<VirtualFile, List<VirtualFile>> sortedFiles;
+    try {
+      sortedFiles = GitUtil.sortFilesByGitRoot(addedFiles, true);
+    }
+    catch (VcsException e) {
+      ((GitVcs)myVcs).showMessages(e.getMessage());
+      return;
+    }
     // note that copied files are not processed because they are included into added files.
     for (Map.Entry<VirtualFile, List<VirtualFile>> e : sortedFiles.entrySet()) {
       try {
@@ -91,7 +98,14 @@ public class GitVFSListener extends VcsVFSListener {
    * @param addedFiles the added files
    */
   private void performAdding(Collection<FilePath> addedFiles) {
-    Map<VirtualFile, List<FilePath>> sortedFiles = GitUtil.sortFilePathsByGitRoot(addedFiles, true);
+    Map<VirtualFile, List<FilePath>> sortedFiles;
+    try {
+      sortedFiles = GitUtil.sortFilePathsByGitRoot(addedFiles, true);
+    }
+    catch (VcsException e) {
+      ((GitVcs)myVcs).showMessages(e.getMessage());
+      return;
+    }
     // note that copied files are not processed because they are included into added files.
     for (Map.Entry<VirtualFile, List<FilePath>> e : sortedFiles.entrySet()) {
       try {
@@ -130,7 +144,14 @@ public class GitVFSListener extends VcsVFSListener {
    * {@inheritDoc}
    */
   protected void performDeletion(final List<FilePath> filesToDelete) {
-    Map<VirtualFile, List<FilePath>> sortedFiles = GitUtil.sortFilePathsByGitRoot(filesToDelete, true);
+    Map<VirtualFile, List<FilePath>> sortedFiles;
+    try {
+      sortedFiles = GitUtil.sortFilePathsByGitRoot(filesToDelete, true);
+    }
+    catch (VcsException e) {
+      ((GitVcs)myVcs).showMessages(e.getMessage());
+      return;
+    }
     for (Map.Entry<VirtualFile, List<FilePath>> e : sortedFiles.entrySet()) {
       try {
         final VirtualFile root = e.getKey();