mrbytes
2012-08-14 975f7c55eea0c20a686d860b67b9a0d5fc3130bb
src/com/gitblit/utils/JGitUtils.java
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -44,7 +45,9 @@
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.StopWalkException;
import org.eclipse.jgit.lib.BlobBasedConfig;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -86,6 +89,7 @@
import com.gitblit.models.PathModel;
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.RefModel;
import com.gitblit.models.SubmoduleModel;
/**
 * Collection of static methods for retrieving information from a repository.
@@ -275,16 +279,26 @@
    *            false all repositories are included.
    * @param searchSubfolders
    *            recurse into subfolders to find grouped repositories
    * @param depth
    *            optional recursion depth, -1 = infinite recursion
    * @param exclusions
    *            list of regex exclusions for matching to folder names
    * @return list of repository names
    */
   public static List<String> getRepositoryList(File repositoriesFolder, boolean onlyBare,
         boolean searchSubfolders) {
         boolean searchSubfolders, int depth, List<String> exclusions) {
      List<String> list = new ArrayList<String>();
      if (repositoriesFolder == null || !repositoriesFolder.exists()) {
         return list;
      }
      List<Pattern> patterns = new ArrayList<Pattern>();
      if (!ArrayUtils.isEmpty(exclusions)) {
         for (String regex : exclusions) {
            patterns.add(Pattern.compile(regex));
         }
      }
      list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder,
            onlyBare, searchSubfolders));
            onlyBare, searchSubfolders, depth, patterns));
      StringUtils.sortRepositorynames(list);
      return list;
   }
@@ -301,14 +315,37 @@
    *            repositories are included.
    * @param searchSubfolders
    *            recurse into subfolders to find grouped repositories
    * @param depth
    *            recursion depth, -1 = infinite recursion
    * @param patterns
    *            list of regex patterns for matching to folder names
    * @return
    */
   private static List<String> getRepositoryList(String basePath, File searchFolder,
         boolean onlyBare, boolean searchSubfolders) {
         boolean onlyBare, boolean searchSubfolders, int depth, List<Pattern> patterns) {
      File baseFile = new File(basePath);
      List<String> list = new ArrayList<String>();
      if (depth == 0) {
         return list;
      }
      int nextDepth = (depth == -1) ? -1 : depth - 1;
      for (File file : searchFolder.listFiles()) {
         if (file.isDirectory()) {
            boolean exclude = false;
            for (Pattern pattern : patterns) {
               String path = FileUtils.getRelativePath(baseFile, file).replace('\\',  '/');
               if (pattern.matcher(path).matches()) {
                  LOGGER.debug(MessageFormat.format("excluding {0} because of rule {1}", path, pattern.pattern()));
                  exclude = true;
                  break;
               }
            }
            if (exclude) {
               // skip to next file
               continue;
            }
            File gitDir = FileKey.resolve(new File(searchFolder, file.getName()), FS.DETECTED);
            if (gitDir != null) {
               if (onlyBare && gitDir.getName().equals(".git")) {
@@ -320,11 +357,13 @@
                  list.add(repository);
               } else if (searchSubfolders && file.canRead()) {
                  // look for repositories in subfolders
                  list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders));
                  list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders,
                        nextDepth, patterns));
               }
            } else if (searchSubfolders && file.canRead()) {
               // look for repositories in subfolders
               list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders));
               list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders,
                     nextDepth, patterns));
            }
         }
      }
@@ -523,18 +562,20 @@
            }
            ObjectId entid = tw.getObjectId(0);
            FileMode entmode = tw.getFileMode(0);
            RevObject ro = rw.lookupAny(entid, entmode.getObjectType());
            rw.parseBody(ro);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ObjectLoader ldr = repository.open(ro.getId(), Constants.OBJ_BLOB);
            byte[] tmp = new byte[4096];
            InputStream in = ldr.openStream();
            int n;
            while ((n = in.read(tmp)) > 0) {
               os.write(tmp, 0, n);
            if (entmode != FileMode.GITLINK) {
               RevObject ro = rw.lookupAny(entid, entmode.getObjectType());
               rw.parseBody(ro);
               ByteArrayOutputStream os = new ByteArrayOutputStream();
               ObjectLoader ldr = repository.open(ro.getId(), Constants.OBJ_BLOB);
               byte[] tmp = new byte[4096];
               InputStream in = ldr.openStream();
               int n;
               while ((n = in.read(tmp)) > 0) {
                  os.write(tmp, 0, n);
               }
               in.close();
               content = os.toByteArray();
            }
            in.close();
            content = os.toByteArray();
         }
      } catch (Throwable t) {
         error(t, repository, "{0} can't find {1} in tree {2}", path, tree.name());
@@ -694,7 +735,8 @@
            tw.addTree(commit.getTree());
            while (tw.next()) {
               list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw
                     .getRawMode(0), commit.getId().getName(), ChangeType.ADD));
                     .getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(),
                     ChangeType.ADD));
            }
            tw.release();
         } else {
@@ -707,15 +749,15 @@
            for (DiffEntry diff : diffs) {
               if (diff.getChangeType().equals(ChangeType.DELETE)) {
                  list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff
                        .getNewMode().getBits(), commit.getId().getName(), diff
                        .getNewMode().getBits(), null, commit.getId().getName(), diff
                        .getChangeType()));
               } else if (diff.getChangeType().equals(ChangeType.RENAME)) {
                  list.add(new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff
                        .getNewMode().getBits(), commit.getId().getName(), diff
                        .getNewMode().getBits(), null, commit.getId().getName(), diff
                        .getChangeType()));
               } else {
                  list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff
                        .getNewMode().getBits(), commit.getId().getName(), diff
                        .getNewMode().getBits(), null, commit.getId().getName(), diff
                        .getChangeType()));
               }
            }
@@ -808,15 +850,16 @@
      } else {
         name = tw.getPathString().substring(basePath.length() + 1);
      }
      ObjectId objectId = tw.getObjectId(0);
      try {
         if (!tw.isSubtree()) {
            size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB);
         if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {
            size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB);
         }
      } catch (Throwable t) {
         error(t, null, "failed to retrieve blob size for " + tw.getPathString());
      }
      return new PathModel(name, tw.getPathString(), size, tw.getFileMode(0).getBits(),
            commit.getName());
            objectId.getName(), commit.getName());
   }
   /**
@@ -833,13 +876,10 @@
      } else if (FileMode.EXECUTABLE_FILE.equals(mode)) {
         return "-rwxr-xr-x";
      } else if (FileMode.SYMLINK.equals(mode)) {
         // FIXME symlink permissions
         return "symlink";
      } else if (FileMode.GITLINK.equals(mode)) {
         // FIXME gitlink permissions
         return "gitlink";
         return "submodule";
      }
      // FIXME missing permissions
      return "missing";
   }
@@ -1495,6 +1535,62 @@
      }
      return branch;
   }
   /**
    * Returns the list of submodules for this repository.
    *
    * @param repository
    * @param commit
    * @return list of submodules
    */
   public static List<SubmoduleModel> getSubmodules(Repository repository, String commitId) {
      RevCommit commit = getCommit(repository, commitId);
      return getSubmodules(repository, commit.getTree());
   }
   /**
    * Returns the list of submodules for this repository.
    *
    * @param repository
    * @param commit
    * @return list of submodules
    */
   public static List<SubmoduleModel> getSubmodules(Repository repository, RevTree tree) {
      List<SubmoduleModel> list = new ArrayList<SubmoduleModel>();
      byte [] blob = getByteContent(repository, tree, ".gitmodules");
      if (blob == null) {
         return list;
      }
      try {
         BlobBasedConfig config = new BlobBasedConfig(repository.getConfig(), blob);
         for (String module : config.getSubsections("submodule")) {
            String path = config.getString("submodule", module, "path");
            String url = config.getString("submodule", module, "url");
            list.add(new SubmoduleModel(module, path, url));
         }
      } catch (ConfigInvalidException e) {
         LOGGER.error("Failed to load .gitmodules file for " + repository.getDirectory(), e);
      }
      return list;
   }
   /**
    * Returns the submodule definition for the specified path at the specified
    * commit.  If no module is defined for the path, null is returned.
    *
    * @param repository
    * @param commit
    * @param path
    * @return a submodule definition or null if there is no submodule
    */
   public static SubmoduleModel getSubmoduleModel(Repository repository, String commitId, String path) {
      for (SubmoduleModel model : getSubmodules(repository, commitId)) {
         if (model.path.equals(path)) {
            return model;
         }
      }
      return null;
   }
   /**
    * Returns the list of notes entered about the commit from the refs/notes