Florian Zschocke
2013-08-15 69007029f122c3f77db044e879188cc12be3c2f6
src/main/java/com/gitblit/GitBlit.java
@@ -1497,22 +1497,13 @@
         } else {
            // we are caching this list
            String msg = "{0} repositories identified in {1} msecs";
            // optionally (re)calculate repository sizes
            if (getBoolean(Keys.web.showRepositorySizes, true)) {
               ByteFormat byteFormat = new ByteFormat();
               // optionally (re)calculate repository sizes
               msg = "{0} repositories identified with calculated folder sizes in {1} msecs";
               for (String repository : repositories) {
                  RepositoryModel model = getRepositoryModel(repository);
                  if (!model.skipSizeCalculation) {
                     model.size = byteFormat.format(calculateSize(model));
                  }
               }
            } else {
               // update cache
               for (String repository : repositories) {
                  getRepositoryModel(repository);
               }
            }
            for (String repository : repositories) {
               getRepositoryModel(repository);
            }
            
            // rebuild fork networks
@@ -1557,6 +1548,10 @@
    * @return repository or null
    */
   public Repository getRepository(String repositoryName, boolean logError) {
      // Decode url-encoded repository name (issue-278)
      // http://stackoverflow.com/questions/17183110
      repositoryName = repositoryName.replace("%7E", "~").replace("%7e", "~");
      if (isCollectingGarbage(repositoryName)) {
         logger.warn(MessageFormat.format("Rejecting request for {0}, busy collecting garbage!", repositoryName));
         return null;
@@ -1603,23 +1598,6 @@
            }
         }
      }
      if (getBoolean(Keys.web.showRepositorySizes, true)) {
         int repoCount = 0;
         long startTime = System.currentTimeMillis();
         ByteFormat byteFormat = new ByteFormat();
         for (RepositoryModel model : repositories) {
            if (!model.skipSizeCalculation) {
               repoCount++;
               model.size = byteFormat.format(calculateSize(model));
            }
         }
         long duration = System.currentTimeMillis() - startTime;
         if (duration > 250) {
            // only log calcualtion time if > 250 msecs
            logger.info(MessageFormat.format("{0} repository sizes calculated in {1} msecs",
               repoCount, duration));
         }
      }
      long duration = System.currentTimeMillis() - methodStart;
      logger.info(MessageFormat.format("{0} repository models loaded for {1} in {2} msecs",
            repositories.size(), user == null ? "anonymous" : user.username, duration));
@@ -1656,13 +1634,17 @@
    * @return repository model or null
    */
   public RepositoryModel getRepositoryModel(String repositoryName) {
      // Decode url-encoded repository name (issue-278)
      // http://stackoverflow.com/questions/17183110
      repositoryName = repositoryName.replace("%7E", "~").replace("%7e", "~");
      if (!repositoryListCache.containsKey(repositoryName)) {
         RepositoryModel model = loadRepositoryModel(repositoryName);
         if (model == null) {
            return null;
         }
         addToCachedRepositoryList(model);
         return model;
         return DeepCopier.copy(model);
      }
      
      // cached model
@@ -1698,13 +1680,7 @@
            model.hasCommits = JGitUtils.hasCommits(r);
         }
         LastChange lc = JGitUtils.getLastChange(r);
         model.lastChange = lc.when;
         model.lastChangeAuthor = lc.who;
         if (!model.skipSizeCalculation) {
            ByteFormat byteFormat = new ByteFormat();
            model.size = byteFormat.format(calculateSize(model));
         }
         updateLastChangeFields(r, model);
      }
      r.close();
      
@@ -2003,16 +1979,20 @@
         // is symlinked.  Use the provided repository name.
         model.name = repositoryName;
      }
      model.hasCommits = JGitUtils.hasCommits(r);
      LastChange lc = JGitUtils.getLastChange(r);
      model.lastChange = lc.when;
      model.lastChangeAuthor = lc.who;
      model.projectPath = StringUtils.getFirstPathElement(repositoryName);
      
      StoredConfig config = r.getConfig();
      boolean hasOrigin = !StringUtils.isEmpty(config.getString("remote", "origin", "url"));
      
      if (config != null) {
         // Initialize description from description file
         if (getConfig(config,"description", null) == null) {
            File descFile = new File(r.getDirectory(), "description");
            if (descFile.exists()) {
               config.setString(Constants.CONFIG_GITBLIT, null, "description",
                     com.gitblit.utils.FileUtils.readContent(descFile, System.getProperty("line.separator")));
            }
         }
         model.description = getConfig(config, "description", "");
         model.originRepository = getConfig(config, "originRepository", null);
         model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
@@ -2068,6 +2048,8 @@
      model.HEAD = JGitUtils.getHEADRef(r);
      model.availableRefs = JGitUtils.getAvailableHeadTargets(r);
      model.sparkleshareId = JGitUtils.getSparkleshareId(r);
      model.hasCommits = JGitUtils.hasCommits(r);
      updateLastChangeFields(r, model);
      r.close();
      
      if (StringUtils.isEmpty(model.originRepository) && model.origin != null && model.origin.startsWith("file://")) {
@@ -2263,21 +2245,31 @@
   }
   /**
    * Returns the size in bytes of the repository. Gitblit caches the
    * repository sizes to reduce the performance penalty of recursive
    * calculation. The cache is updated if the repository has been changed
    * since the last calculation.
    * Updates the last changed fields and optionally calculates the size of the
    * repository.  Gitblit caches the repository sizes to reduce the performance
    * penalty of recursive calculation. The cache is updated if the repository
    * has been changed since the last calculation.
    * 
    * @param model
    * @return size in bytes
    * @return size in bytes of the repository
    */
   public long calculateSize(RepositoryModel model) {
      if (repositorySizeCache.hasCurrent(model.name, model.lastChange)) {
         return repositorySizeCache.getObject(model.name);
   public long updateLastChangeFields(Repository r, RepositoryModel model) {
      LastChange lc = JGitUtils.getLastChange(r);
      model.lastChange = lc.when;
      model.lastChangeAuthor = lc.who;
      if (!getBoolean(Keys.web.showRepositorySizes, true) || model.skipSizeCalculation) {
         model.size = null;
         return 0L;
      }
      File gitDir = FileKey.resolve(new File(repositoriesFolder, model.name), FS.DETECTED);
      long size = com.gitblit.utils.FileUtils.folderSize(gitDir);
      repositorySizeCache.updateObject(model.name, model.lastChange, size);
      if (!repositorySizeCache.hasCurrent(model.name, model.lastChange)) {
         File gitDir = r.getDirectory();
         long sz = com.gitblit.utils.FileUtils.folderSize(gitDir);
         repositorySizeCache.updateObject(model.name, model.lastChange, sz);
      }
      long size = repositorySizeCache.getObject(model.name);
      ByteFormat byteFormat = new ByteFormat();
      model.size = byteFormat.format(size);
      return size;
   }
@@ -2513,6 +2505,15 @@
      // update settings
      if (r != null) {
         updateConfiguration(r, repository);
         // Update the description file
         File descFile = new File(r.getDirectory(), "description");
         if (repository.description != null)
         {
            com.gitblit.utils.FileUtils.writeContent(descFile, repository.description);
         }
         else if (descFile.exists() && !descFile.isDirectory()) {
            descFile.delete();
         }
         // only update symbolic head if it changes
         String currentRef = JGitUtils.getHEADRef(r);
         if (!StringUtils.isEmpty(repository.HEAD) && !repository.HEAD.equals(currentRef)) {