private boolean cherryPick(
      HttpServletRequest request,
      HttpServletResponse response,
      Repository db,
      String commitToCherryPick)
      throws ServletException, JSONException {
    RevWalk revWalk = new RevWalk(db);
    try {

      Ref headRef = db.getRef(Constants.HEAD);
      if (headRef == null)
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "An error occured when cherry-picking.",
                null));
      RevCommit head = revWalk.parseCommit(headRef.getObjectId());

      ObjectId objectId = db.resolve(commitToCherryPick);
      Git git = new Git(db);
      CherryPickResult cherryPickResult = git.cherryPick().include(objectId).call();
      RevCommit newHead = cherryPickResult.getNewHead();

      JSONObject result = new JSONObject();
      result.put(GitConstants.KEY_RESULT, cherryPickResult.getStatus().name());
      result.put(GitConstants.KEY_HEAD_UPDATED, !head.equals(newHead));
      OrionServlet.writeJSONResponse(
          request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
      return true;
    } catch (IOException e) {
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(
              IStatus.ERROR,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              "An error occured when cherry-picking.",
              e));
    } catch (GitAPIException e) {
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(
              IStatus.ERROR,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              "An error occured when cherry-picking.",
              e));
    } finally {
      revWalk.release();
    }
  }
 private boolean applyPatch(
     HttpServletRequest request, HttpServletResponse response, Repository db, String contentType)
     throws ServletException {
   try {
     String patch = readPatch(request.getInputStream(), contentType);
     Git git = new Git(db);
     ApplyCommand applyCommand = git.apply();
     applyCommand.setPatch(IOUtilities.toInputStream(patch));
     // TODO: ignore all errors for now, see bug 366008
     try {
       ApplyResult applyResult = applyCommand.call();
       JSONObject resp = new JSONObject();
       JSONArray modifiedFieles = new JSONArray();
       for (File file : applyResult.getUpdatedFiles()) {
         modifiedFieles.put(stripGlobalPaths(db, file.getAbsolutePath()));
       }
       resp.put("modifiedFieles", modifiedFieles);
       return statusHandler.handleRequest(
           request, response, new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, resp));
       // OrionServlet.writeJSONResponse(request, response, toJSON(applyResult));
     } catch (PatchFormatException e) {
       return statusHandler.handleRequest(
           request,
           response,
           new ServerStatus(
               IStatus.ERROR,
               HttpServletResponse.SC_BAD_REQUEST,
               stripGlobalPaths(db, e.getMessage()),
               null));
     } catch (PatchApplyException e) {
       return statusHandler.handleRequest(
           request,
           response,
           new ServerStatus(
               IStatus.ERROR,
               HttpServletResponse.SC_BAD_REQUEST,
               stripGlobalPaths(db, e.getMessage()),
               null));
     }
   } catch (Exception e) {
     return statusHandler.handleRequest(
         request,
         response,
         new ServerStatus(
             IStatus.ERROR,
             HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
             "An error occured when reading the patch.",
             e));
   }
 }
  /**
   * Returns absolute paths which have changed remotely comparing to the current branch, i.e.
   * performs <code>git diff --name-only master..origin/master</code>
   *
   * <p>Paths are absolute, Git-formatted (i.e. with forward slashes).
   */
  @NotNull
  public static Collection<String> getPathsDiffBetweenRefs(
      @NotNull Git git,
      @NotNull GitRepository repository,
      @NotNull String beforeRef,
      @NotNull String afterRef)
      throws VcsException {
    List<String> parameters = Arrays.asList("--name-only", "--pretty=format:");
    String range = beforeRef + ".." + afterRef;
    GitCommandResult result = git.diff(repository, parameters, range);
    if (!result.success()) {
      LOG.info(
          String.format(
              "Couldn't get diff in range [%s] for repository [%s]",
              range, repository.toLogString()));
      return Collections.emptyList();
    }

    final Collection<String> remoteChanges = new HashSet<String>();
    for (StringScanner s = new StringScanner(result.getOutputAsJoinedString()); s.hasMoreData(); ) {
      final String relative = s.line();
      if (StringUtil.isEmptyOrSpaces(relative)) {
        continue;
      }
      final String path = repository.getRoot().getPath() + "/" + unescapePath(relative);
      remoteChanges.add(path);
    }
    return remoteChanges;
  }
 private boolean merge(
     HttpServletRequest request,
     HttpServletResponse response,
     Repository db,
     String commitToMerge,
     boolean squash)
     throws ServletException, JSONException {
   try {
     ObjectId objectId = db.resolve(commitToMerge);
     Git git = new Git(db);
     MergeResult mergeResult = git.merge().setSquash(squash).include(objectId).call();
     JSONObject result = new JSONObject();
     result.put(GitConstants.KEY_RESULT, mergeResult.getMergeStatus().name());
     if (mergeResult.getFailingPaths() != null && !mergeResult.getFailingPaths().isEmpty())
       result.put(GitConstants.KEY_FAILING_PATHS, mergeResult.getFailingPaths());
     OrionServlet.writeJSONResponse(
         request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
     return true;
   } catch (CheckoutConflictException e) {
     return workaroundBug356918(request, response, e);
   } catch (IOException e) {
     return statusHandler.handleRequest(
         request,
         response,
         new ServerStatus(
             IStatus.ERROR,
             HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
             "An error occured when merging.",
             e));
   } catch (GitAPIException e) {
     return statusHandler.handleRequest(
         request,
         response,
         new ServerStatus(
             IStatus.ERROR,
             HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
             "An error occured when merging.",
             e));
   }
 }
  private boolean revert(
      HttpServletRequest request,
      HttpServletResponse response,
      Repository db,
      String commitToRevert)
      throws ServletException, JSONException {
    RevWalk revWalk = new RevWalk(db);
    try {

      Ref headRef = db.getRef(Constants.HEAD);
      if (headRef == null)
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "An error occured when reverting.",
                null));

      ObjectId objectId = db.resolve(commitToRevert);
      Git git = new Git(db);

      RevertCommand revertCommand = git.revert().include(objectId);
      RevCommit revertedCommit = revertCommand.call();

      if (revertedCommit == null) {
        JSONObject result = new JSONObject();
        result.put(GitConstants.KEY_RESULT, "FAILURE"); // $NON-NLS-1$
        OrionServlet.writeJSONResponse(
            request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
        return true;
      }

      JSONObject result = new JSONObject();
      result.put(GitConstants.KEY_RESULT, "OK"); // $NON-NLS-1$
      OrionServlet.writeJSONResponse(
          request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
      return true;
    } catch (IOException e) {
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(
              IStatus.ERROR,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              "An error occured when reverting.",
              e));
    } catch (GitAPIException e) {
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(
              IStatus.ERROR,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              "An error occured when reverting.",
              e));
    } finally {
      revWalk.release();
    }
  }
 private boolean rebase(
     HttpServletRequest request,
     HttpServletResponse response,
     Repository db,
     String commitToRebase,
     String rebaseOperation)
     throws ServletException, JSONException, AmbiguousObjectException, IOException {
   JSONObject result = new JSONObject();
   try {
     Git git = new Git(db);
     RebaseCommand rebase = git.rebase();
     Operation operation;
     if (rebaseOperation != null) {
       operation = Operation.valueOf(rebaseOperation);
     } else {
       operation = Operation.BEGIN;
     }
     if (commitToRebase != null && !commitToRebase.isEmpty()) {
       ObjectId objectId = db.resolve(commitToRebase);
       rebase.setUpstream(objectId);
     } else if (operation.equals(Operation.BEGIN)) {
       return statusHandler.handleRequest(
           request,
           response,
           new ServerStatus(
               IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Missing commit refId.", null));
     }
     rebase.setOperation(operation);
     RebaseResult rebaseResult = rebase.call();
     result.put(GitConstants.KEY_RESULT, rebaseResult.getStatus().name());
   } catch (UnmergedPathsException e) {
     // this error should be handled by client, so return a proper status
     result.put(GitConstants.KEY_RESULT, AdditionalRebaseStatus.FAILED_UNMERGED_PATHS.name());
   } catch (WrongRepositoryStateException e) {
     // this error should be handled by client, so return a proper status
     result.put(
         GitConstants.KEY_RESULT, AdditionalRebaseStatus.FAILED_WRONG_REPOSITORY_STATE.name());
   } catch (IllegalArgumentException e) {
     return statusHandler.handleRequest(
         request,
         response,
         new ServerStatus(
             IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Invalid rebase operation.", e));
   } catch (GitAPIException e) {
     // get cause and try to handle
     if (e.getCause() instanceof org.eclipse.jgit.errors.CheckoutConflictException) {
       // this error should be handled by client, so return a proper status
       result.put(GitConstants.KEY_RESULT, AdditionalRebaseStatus.FAILED_PENDING_CHANGES.name());
     } else {
       return statusHandler.handleRequest(
           request,
           response,
           new ServerStatus(
               IStatus.ERROR,
               HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
               "An error occured when rebasing.",
               e));
     }
   }
   OrionServlet.writeJSONResponse(
       request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
   return true;
 }
  @Override
  protected boolean handlePost(RequestInfo requestInfo) throws ServletException {
    String gitSegment = requestInfo.gitSegment;
    HttpServletRequest request = requestInfo.request;
    HttpServletResponse response = requestInfo.response;
    Repository db = requestInfo.db;
    String pattern = requestInfo.relativePath;
    JSONObject requestObject = requestInfo.getJSONRequest();
    try {
      String commitToMerge = requestObject.optString(GitConstants.KEY_MERGE, null);
      if (commitToMerge != null) {
        boolean squash = requestObject.optBoolean(GitConstants.KEY_SQUASH, false);
        return merge(request, response, db, commitToMerge, squash);
      }

      String commitToRebase = requestObject.optString(GitConstants.KEY_REBASE, null);
      String rebaseOperation = requestObject.optString(GitConstants.KEY_OPERATION, null);
      if (commitToRebase != null) {
        return rebase(request, response, db, commitToRebase, rebaseOperation);
      }

      String commitToCherryPick = requestObject.optString(GitConstants.KEY_CHERRY_PICK, null);
      if (commitToCherryPick != null) {
        return cherryPick(request, response, db, commitToCherryPick);
      }

      String commitToRevert = requestObject.optString(GitConstants.KEY_REVERT, null);
      if (commitToRevert != null) {
        return revert(request, response, db, commitToRevert);
      }

      String newCommit = requestObject.optString(GitConstants.KEY_COMMIT_NEW, null);
      if (newCommit != null) return identifyNewCommitResource(request, response, db, newCommit);

      String reviewReqLogin = requestObject.optString(GitConstants.KEY_REVIEW_REQ_NOTIFY_LOGIN);
      if (reviewReqLogin != null && reviewReqLogin.length() != 0) {
        String reviewReqUrl = requestObject.optString(GitConstants.KEY_REVIEW_REQ_URL);
        String ReviewReqCommit = requestObject.optString(GitConstants.KEY_REVIEW_REQ_COMMIT);
        String ReviewReqAuthorName =
            requestObject.optString(GitConstants.KEY_REVIEW_REQ_AUTHOR_NAME);
        String ReviewMessage = requestObject.optString(GitConstants.KEY_REVIEW_REQ_MESSAGE);
        return sendNotification(
            request,
            response,
            db,
            reviewReqLogin,
            ReviewReqCommit,
            reviewReqUrl,
            ReviewReqAuthorName,
            ReviewMessage);
      }

      ObjectId refId = db.resolve(gitSegment);
      if (refId == null || !Constants.HEAD.equals(gitSegment)) {
        String msg = NLS.bind("Commit failed. Ref must be HEAD and is {0}", gitSegment);
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
      }

      String message = requestObject.optString(GitConstants.KEY_COMMIT_MESSAGE, null);
      if (message == null || message.isEmpty()) {
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_BAD_REQUEST,
                "Missing commit message.",
                null));
      }

      Git git = new Git(db);
      CommitCommand cc = git.commit();
      Config config = git.getRepository().getConfig();

      boolean amend =
          Boolean.parseBoolean(requestObject.optString(GitConstants.KEY_COMMIT_AMEND, null));
      boolean insertChangeId =
          GitUtils.isGerrit(config)
              || Boolean.parseBoolean(requestObject.optString(GitConstants.KEY_CHANGE_ID, null));

      String committerName = requestObject.optString(GitConstants.KEY_COMMITTER_NAME, null);
      String committerEmail = requestObject.optString(GitConstants.KEY_COMMITTER_EMAIL, null);
      String authorName = requestObject.optString(GitConstants.KEY_AUTHOR_NAME, null);
      String authorEmail = requestObject.optString(GitConstants.KEY_AUTHOR_EMAIL, null);

      // workaround of a bug in JGit which causes invalid
      // support of null values of author/committer name/email, see bug 352984
      PersonIdent defPersonIdent = new PersonIdent(db);
      if (committerName == null) committerName = defPersonIdent.getName();
      if (committerEmail == null) committerEmail = defPersonIdent.getEmailAddress();
      if (authorName == null) authorName = committerName;
      if (authorEmail == null) authorEmail = committerEmail;
      cc.setCommitter(committerName, committerEmail);
      cc.setAuthor(authorName, authorEmail);
      if (insertChangeId) cc.setInsertChangeId(true);

      // support for committing by path: "git commit -o path"
      if (!pattern.isEmpty()) {
        cc.setOnly(pattern);
      }

      try {
        // "git commit [--amend] -m '{message}' [-a|{path}]"
        RevCommit lastCommit = cc.setAmend(amend).setMessage(message).call();

        URI cloneLocation =
            BaseToCloneConverter.getCloneLocation(
                getURI(request), BaseToCloneConverter.COMMIT_REFRANGE);
        Commit commit = new Commit(cloneLocation, db, lastCommit, pattern);
        JSONObject result = commit.toJSON();
        OrionServlet.writeJSONResponse(
            request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
        return true;
      } catch (GitAPIException e) {
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_BAD_REQUEST,
                "An error occured when commiting.",
                e));
      } catch (UnmergedPathException e) {
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "An internal error occured when commiting.",
                e));
      }
    } catch (Exception e) {
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(
              IStatus.ERROR,
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              "An error occured when requesting a commit info.",
              e));
    }
  }
  private boolean handleGetDiff(
      HttpServletRequest request,
      HttpServletResponse response,
      Repository db,
      String scope,
      String pattern,
      OutputStream out)
      throws Exception {
    Git git = new Git(db);
    DiffCommand diff = git.diff();
    diff.setOutputStream(new BufferedOutputStream(out));
    AbstractTreeIterator oldTree;
    AbstractTreeIterator newTree = new FileTreeIterator(db);
    if (scope.contains("..")) { // $NON-NLS-1$
      String[] commits = scope.split("\\.\\."); // $NON-NLS-1$
      if (commits.length != 2) {
        String msg = NLS.bind("Failed to generate diff for {0}", scope);
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
      }
      oldTree = getTreeIterator(db, commits[0]);
      newTree = getTreeIterator(db, commits[1]);
    } else if (scope.equals(GitConstants.KEY_DIFF_CACHED)) {
      ObjectId head = db.resolve(Constants.HEAD + "^{tree}"); // $NON-NLS-1$
      if (head == null) {
        String msg = NLS.bind("Failed to generate diff for {0}, no HEAD", scope);
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
      }
      CanonicalTreeParser p = new CanonicalTreeParser();
      ObjectReader reader = db.newObjectReader();
      try {
        p.reset(reader, head);
      } finally {
        reader.release();
      }
      oldTree = p;
      newTree = new DirCacheIterator(db.readDirCache());
    } else if (scope.equals(GitConstants.KEY_DIFF_DEFAULT)) {
      oldTree = new DirCacheIterator(db.readDirCache());
    } else {
      oldTree = getTreeIterator(db, scope);
    }

    String[] paths = request.getParameterValues(ProtocolConstants.KEY_PATH);
    TreeFilter filter = null;
    TreeFilter pathFilter = null;
    if (paths != null) {
      if (paths.length > 1) {
        Set<TreeFilter> pathFilters = new HashSet<TreeFilter>(paths.length);
        for (String path : paths) {
          pathFilters.add(PathFilter.create(path));
        }
        pathFilter = OrTreeFilter.create(pathFilters);
      } else if (paths.length == 1) {
        pathFilter = PathFilter.create(paths[0]);
      }
    }
    if (pattern != null) {
      PathFilter patternFilter = PathFilter.create(pattern);
      if (pathFilter != null) filter = AndTreeFilter.create(patternFilter, pathFilter);
      else filter = patternFilter;
    } else {
      filter = pathFilter;
    }
    if (filter != null) diff.setPathFilter(filter);

    diff.setOldTree(oldTree);
    diff.setNewTree(newTree);
    diff.call();
    return true;
  }