James Moger
2013-05-24 51c76e7366c2e8851f1639fbdbf2b8deb219c7fc
src/main/java/com/gitblit/utils/JGitUtils.java
@@ -19,6 +19,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -66,7 +67,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
@@ -82,8 +83,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.models.GitNote;
import com.gitblit.models.PathModel;
import com.gitblit.models.PathModel.PathChangeModel;
@@ -98,7 +97,6 @@
 */
public class JGitUtils {
   private static final String REVISION_TAG_PREFIX = "rev_";
   static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class);
   /**
@@ -200,7 +198,7 @@
      File folder = new File(repositoriesFolder, name);
      if (folder.exists()) {
         File gitDir = FileKey.resolve(new File(repositoriesFolder, name), FS.DETECTED);
         FileRepository repository = new FileRepository(gitDir);
         Repository repository = new FileRepositoryBuilder().setGitDir(gitDir).build();
         result.fetchResult = fetchRepository(credentialsProvider, repository);
         repository.close();
      } else {
@@ -773,6 +771,51 @@
   }
   /**
    * Returns the list of files changed in a specified commit. If the
    * repository does not exist or is empty, an empty list is returned.
    *
    * @param repository
    * @param startCommit
    *            earliest commit
    * @param endCommit
    *            most recent commit. if null, HEAD is assumed.
    * @return list of files changed in a commit range
    */
   public static List<PathChangeModel> getFilesInRange(Repository repository, RevCommit startCommit, RevCommit endCommit) {
      List<PathChangeModel> list = new ArrayList<PathChangeModel>();
      if (!hasCommits(repository)) {
         return list;
      }
      try {
         DiffFormatter df = new DiffFormatter(null);
         df.setRepository(repository);
         df.setDiffComparator(RawTextComparator.DEFAULT);
         df.setDetectRenames(true);
         List<DiffEntry> diffEntries = df.scan(startCommit.getTree(), endCommit.getTree());
         for (DiffEntry diff : diffEntries) {
            if (diff.getChangeType().equals(ChangeType.DELETE)) {
               list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff
                     .getNewMode().getBits(), diff.getOldId().name(), null, diff
                     .getChangeType()));
            } else if (diff.getChangeType().equals(ChangeType.RENAME)) {
               list.add(new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff
                     .getNewMode().getBits(), diff.getNewId().name(), null, diff
                     .getChangeType()));
            } else {
               list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff
                     .getNewMode().getBits(), diff.getNewId().name(), null, diff
                     .getChangeType()));
            }
         }
         Collections.sort(list);
      } catch (Throwable t) {
         error(t, repository, "{0} failed to determine files in range {1}..{2}!", startCommit, endCommit);
      }
      return list;
   }
   /**
    * Returns the list of files in the repository on the default branch that
    * match one of the specified extensions. This is a CASE-SENSITIVE search.
    * If the repository does not exist or is empty, an empty list is returned.
@@ -983,18 +1026,30 @@
      }
      try {
         // resolve branch
         ObjectId branchObject;
         ObjectId startRange = null;
         ObjectId endRange;
         if (StringUtils.isEmpty(objectId)) {
            branchObject = getDefaultBranch(repository);
            endRange = getDefaultBranch(repository);
         } else {
            branchObject = repository.resolve(objectId);
            if( objectId.contains("..") ) {
               // range expression
               String[] parts = objectId.split("\\.\\.");
               startRange = repository.resolve(parts[0]);
               endRange = repository.resolve(parts[1]);
            } else {
               // objectid
               endRange= repository.resolve(objectId);
            }
         }
         if (branchObject == null) {
         if (endRange == null) {
            return list;
         }
         RevWalk rw = new RevWalk(repository);
         rw.markStart(rw.parseCommit(branchObject));
         rw.markStart(rw.parseCommit(endRange));
         if (startRange != null) {
            rw.markUninteresting(rw.parseCommit(startRange));
         }
         if (!StringUtils.isEmpty(path)) {
            TreeFilter filter = AndTreeFilter.create(
                  PathFilterGroup.createFromStrings(Collections.singleton(path)),
@@ -1692,59 +1747,58 @@
      }
      return list;
   }
   /**
    * this method creates an incremental revision number as a tag according to
    * the amount of already existing tags, which start with a defined prefix {@link REVISION_TAG_PREFIX}
    * the amount of already existing tags, which start with a defined prefix.
    * 
    * @param repository
    * @param objectId
    * @param tagger
    * @param prefix
    * @param intPattern
    * @param message
    * @return true if operation was successful, otherwise false
    */
   public static boolean createIncrementalRevisionTag(Repository repository, String objectId) {
   public static boolean createIncrementalRevisionTag(Repository repository,
         String objectId, PersonIdent tagger, String prefix, String intPattern, String message) {
      boolean result = false;
      Iterator<Entry<String, Ref>> iterator = repository.getTags().entrySet().iterator();
      long revisionNumber = 1;
      long lastRev = 0;
      while (iterator.hasNext()) {
         Entry<String, Ref> entry = iterator.next();
         if (entry.getKey().startsWith(REVISION_TAG_PREFIX)) {
            revisionNumber++;
         if (entry.getKey().startsWith(prefix)) {
            try {
               long val = Long.parseLong(entry.getKey().substring(prefix.length()));
               if (val > lastRev) {
                  lastRev = val;
               }
            } catch (Exception e) {
               // this tag is NOT an incremental revision tag
            }
         }
      }
      result = createTag(repository,REVISION_TAG_PREFIX+revisionNumber,objectId);
      DecimalFormat df = new DecimalFormat(intPattern);
      result = createTag(repository, objectId, tagger, prefix + df.format((lastRev + 1)), message);
      return result;
   }
   /**
    * creates a tag in a repository referring to the current head
    *
    * @param repository
    * @param tag, the string label
    * @return boolean, true if operation was successful, otherwise false
    */
   public static boolean createTag(Repository repository, String tag) {
      return createTag(repository, tag, null);
   }
   /**
    * creates a tag in a repository
    * 
    * @param repository
    * @param tag, the string label
    * @param objectId, the ref the tag points towards
    * @param tagger, the person tagging the object
    * @param tag, the string label
    * @param message, the string message
    * @return boolean, true if operation was successful, otherwise false
    */
   public static boolean createTag(Repository repository, String tag,
         String objectId) {
   public static boolean createTag(Repository repository, String objectId, PersonIdent tagger, String tag, String message) {
      try {         
         PersonIdent author = new PersonIdent("GitblitAutoTagPush",
               "gitblit@localhost");
         LOGGER.debug("createTag in repo: "+repository.getDirectory().getAbsolutePath());
         Git gitClient = Git.open(repository.getDirectory());
         TagCommand tagCommand = gitClient.tag();
         tagCommand.setTagger(author);
         tagCommand.setMessage("autotag");
         tagCommand.setTagger(tagger);
         tagCommand.setMessage(message);
         if (objectId != null) {
            RevObject revObj = getCommit(repository, objectId);
            tagCommand.setObjectId(revObj);
@@ -1753,7 +1807,7 @@
         Ref call = tagCommand.call();         
         return call != null ? true : false;
      } catch (Exception e) {
         e.printStackTrace();
         error(e, repository, "Failed to create tag {1} in repository {0}", objectId, tag);
      }
      return false;
   }