Philip L. McMahon
2012-01-27 30f9d25d77ccb5cd978d4cf8fa389ec819e90e95
src/com/gitblit/utils/JGitUtils.java
@@ -47,15 +47,20 @@
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.StopWalkException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
@@ -1151,6 +1156,66 @@
   }
   /**
    * Returns the default HEAD for a repository. Normally returns the ref HEAD points to, but if HEAD points to nothing
    * it returns null.
    *
    * @param repository
    * @return the refmodel for HEAD or null
    */
   public static RefModel getDefaultHead(Repository repository) {
      RefModel ref = null;
      try {
         Ref head = repository.getRef(Constants.HEAD);
         if (head != null) {
            Ref target = head.getTarget();
            RevWalk rw = new RevWalk(repository);
            ObjectId targetId = target.getObjectId();
            if (targetId != null) {
               RevObject object = rw.parseAny(targetId);
               ref = new RefModel(target.getName(), target, object);
            }
            rw.dispose();
         }
      } catch (Throwable t) {
         LOGGER.error("Failed to get default head!", t);
      }
      return ref;
   }
   /**
    * Sets the default HEAD symbolic ref for a repository.
    *
    * @param repository
    * @param ref
    */
   public static void setDefaultHead(Repository repository, Ref ref) {
      try {
         boolean detach = !ref.getName().startsWith(Constants.R_HEADS); // detach if not a branch
         RefUpdate.Result result;
         RefUpdate head = repository.updateRef(Constants.HEAD, detach);
         if (detach) { // Tag
            RevCommit commit = getCommit(repository, ref.getObjectId().getName());
            head.setNewObjectId(commit.getId());
            result = head.forceUpdate();
         } else {
            result = head.link(ref.getName());
         }
         switch (result) {
         case NEW:
         case FORCED:
         case NO_CHANGE:
         case FAST_FORWARD:
            break;
         default:
            LOGGER.error(MessageFormat.format("{0} failed to set default head to {1} ({2})",
                  repository.getDirectory().getAbsolutePath(), ref.getName(), result));
         }
      } catch (Throwable t) {
         error(t, repository, "{0} failed to set default head to {1}", ref.getName());
      }
   }
   /**
    * Returns all refs grouped by their associated object id.
    * 
    * @param repository
@@ -1291,29 +1356,40 @@
    * @return a refmodel for the gh-pages branch or null
    */
   public static RefModel getPagesBranch(Repository repository) {
      RefModel ghPages = null;
      return getBranch(repository, "gh-pages");
   }
   /**
    * Returns a RefModel for a specific branch name in the repository. If the
    * branch can not be found, null is returned.
    *
    * @param repository
    * @return a refmodel for the branch or null
    */
   public static RefModel getBranch(Repository repository, String name) {
      RefModel branch = null;
      try {
         // search for gh-pages branch in local heads
         // search for the branch in local heads
         for (RefModel ref : JGitUtils.getLocalBranches(repository, false, -1)) {
            if (ref.displayName.endsWith("gh-pages")) {
               ghPages = ref;
            if (ref.displayName.endsWith(name)) {
               branch = ref;
               break;
            }
         }
         // search for gh-pages branch in remote heads
         if (ghPages == null) {
         // search for the branch in remote heads
         if (branch == null) {
            for (RefModel ref : JGitUtils.getRemoteBranches(repository, false, -1)) {
               if (ref.displayName.endsWith("gh-pages")) {
                  ghPages = ref;
               if (ref.displayName.endsWith(name)) {
                  branch = ref;
                  break;
               }
            }
         }
      } catch (Throwable t) {
         LOGGER.error("Failed to find gh-pages branch!", t);
         LOGGER.error(MessageFormat.format("Failed to find {0} branch!", name), t);
      }
      return ghPages;
      return branch;
   }
   /**
@@ -1349,37 +1425,74 @@
   }
   /**
    * Create an orphaned branch in a repository. This code does not work.
    * Create an orphaned branch in a repository.
    * 
    * @param repository
    * @param name
    * @return
    * @param branchName
    * @param author
    *            if unspecified, Gitblit will be the author of this new branch
    * @return true if successful
    */
   public static boolean createOrphanBranch(Repository repository, String name) {
      return true;
      // boolean success = false;
      // try {
      // ObjectId prev = repository.resolve(Constants.HEAD + "^1");
      // // create the orphan branch
      // RefUpdate orphanRef = repository.updateRef(Constants.R_HEADS + name);
      // orphanRef.setNewObjectId(prev);
      // orphanRef.setExpectedOldObjectId(ObjectId.zeroId());
      // Result updateResult = orphanRef.update();
      //
      // switch (updateResult) {
      // case NEW:
      // success = true;
      // break;
      // case NO_CHANGE:
      // default:
      // break;
      // }
      //
      // } catch (Throwable t) {
      // error(t, repository, "{0} failed to create orphaned branch {1}",
      // name);
      // }
      // return success;
   public static boolean createOrphanBranch(Repository repository, String branchName,
         PersonIdent author) {
      boolean success = false;
      String message = "Created branch " + branchName;
      if (author == null) {
         author = new PersonIdent("Gitblit", "gitblit@localhost");
      }
      try {
         ObjectInserter odi = repository.newObjectInserter();
         try {
            // Create a blob object to insert into a tree
            ObjectId blobId = odi.insert(Constants.OBJ_BLOB,
                  message.getBytes(Constants.CHARACTER_ENCODING));
            // Create a tree object to reference from a commit
            TreeFormatter tree = new TreeFormatter();
            tree.append("NEWBRANCH", FileMode.REGULAR_FILE, blobId);
            ObjectId treeId = odi.insert(tree);
            // Create a commit object
            CommitBuilder commit = new CommitBuilder();
            commit.setAuthor(author);
            commit.setCommitter(author);
            commit.setEncoding(Constants.CHARACTER_ENCODING);
            commit.setMessage(message);
            commit.setTreeId(treeId);
            // Insert the commit into the repository
            ObjectId commitId = odi.insert(commit);
            odi.flush();
            RevWalk revWalk = new RevWalk(repository);
            try {
               RevCommit revCommit = revWalk.parseCommit(commitId);
               if (!branchName.startsWith("refs/")) {
                  branchName = "refs/heads/" + branchName;
               }
               RefUpdate ru = repository.updateRef(branchName);
               ru.setNewObjectId(commitId);
               ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
               Result rc = ru.forceUpdate();
               switch (rc) {
               case NEW:
               case FORCED:
               case FAST_FORWARD:
                  success = true;
                  break;
               default:
                  success = false;
               }
            } finally {
               revWalk.release();
            }
         } finally {
            odi.release();
         }
      } catch (Throwable t) {
         error(t, repository, "Failed to create orphan branch {1} in repository {0}", branchName);
      }
      return success;
   }
   /**