@Override
 protected IStatus performJob() {
   try {
     // list all tags
     File gitDir = GitUtils.getGitDir(path);
     Repository db = new FileRepository(gitDir);
     Git git = new Git(db);
     List<Ref> refs = git.tagList().call();
     JSONObject result = new JSONObject();
     List<Tag> tags = new ArrayList<Tag>();
     for (Ref ref : refs) {
       Tag tag = new Tag(cloneLocation, db, ref);
       tags.add(tag);
     }
     Collections.sort(tags, Tag.COMPARATOR);
     JSONArray children = new JSONArray();
     int firstTag = pageSize > 0 ? pageSize * (pageNo - 1) : 0;
     int lastTag = pageSize > 0 ? firstTag + pageSize - 1 : tags.size() - 1;
     lastTag = lastTag > tags.size() - 1 ? tags.size() - 1 : lastTag;
     if (pageNo > 1 && baseLocation != null) {
       String prev = baseLocation + "?page=" + (pageNo - 1) + "&pageSize=" + pageSize;
       if (commitsSize > 0) {
         prev += "&" + GitConstants.KEY_TAG_COMMITS + "=" + commitsSize;
       }
       result.put(ProtocolConstants.KEY_PREVIOUS_LOCATION, prev);
     }
     if (lastTag < tags.size() - 1) {
       String next = baseLocation + "?page=" + (pageNo + 1) + "&pageSize=" + pageSize;
       if (commitsSize > 0) {
         next += "&" + GitConstants.KEY_TAG_COMMITS + "=" + commitsSize;
       }
       result.put(ProtocolConstants.KEY_NEXT_LOCATION, next);
     }
     for (int i = firstTag; i <= lastTag; i++) {
       Tag tag = tags.get(i);
       if (this.commitsSize == 0) {
         children.put(tag.toJSON());
       } else {
         // add info about commits if requested
         LogCommand lc = git.log();
         String toCommitName = tag.getRevCommitName();
         ObjectId toCommitId = db.resolve(toCommitName);
         Ref toCommitRef = db.getRef(toCommitName);
         toCommitId = getCommitObjectId(db, toCommitId);
         lc.add(toCommitId);
         lc.setMaxCount(this.commitsSize);
         Iterable<RevCommit> commits = lc.call();
         Log log = new Log(cloneLocation, db, commits, null, null, toCommitRef);
         children.put(tag.toJSON(log.toJSON(1, commitsSize)));
       }
     }
     result.put(ProtocolConstants.KEY_CHILDREN, children);
     result.put(ProtocolConstants.KEY_TYPE, Tag.TYPE);
     return new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, result);
   } catch (Exception e) {
     String msg = NLS.bind("An error occured when listing tags for {0}", path);
     return new Status(IStatus.ERROR, GitActivator.PI_GIT, msg, e);
   }
 }
  private boolean handleGetCommitBody(
      HttpServletRequest request,
      HttpServletResponse response,
      Repository db,
      String ref,
      String pattern)
      throws IOException, ServletException, CoreException {
    ObjectId refId = db.resolve(ref);
    if (refId == null) {
      String msg = NLS.bind("Failed to get commit body for ref {0}", ref);
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
    }
    RevWalk walk = new RevWalk(db);
    walk.setTreeFilter(
        AndTreeFilter.create(
            PathFilterGroup.createFromStrings(Collections.singleton(pattern)),
            TreeFilter.ANY_DIFF));
    RevCommit revCommit = walk.parseCommit(refId);
    walk.dispose();

    Commit commit = new Commit(null /* not needed */, db, revCommit, pattern);
    ObjectStream stream = commit.toObjectStream();
    if (stream == null) {
      String msg = NLS.bind("Commit body for ref {0} not found", ref);
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null));
    }
    IOUtilities.pipe(stream, response.getOutputStream(), true, false);

    return true;
  }