/*
   * Use the binary git repo and/or the remote service to figure out
   * the new commits made since the last pull on source repository.
   */
  public void findNewCommits() throws GitException {

    // get the history from binary repository
    Git bingit = Git.wrap(binaryRepository);
    RevWalk binwalk = new RevWalk(binaryRepository);

    Iterable<RevCommit> logs;
    try {
      logs = bingit.log().call();
      Iterator<RevCommit> i = logs.iterator();

      while (i.hasNext()) {
        RevCommit commit = binwalk.parseCommit(i.next());
        System.out.println(commit.getFullMessage());
      }

    } catch (NoHeadException e) {
      // TODO Auto-generated catch block
      throw new GitException(e);
    } catch (GitAPIException e) {
      throw new GitException(e);
    } catch (MissingObjectException e) {
      throw new GitException(e);
    } catch (IncorrectObjectTypeException e) {
      throw new GitException(e);
    } catch (IOException e) {
      throw new GitException(e);
    }
  }
  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 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));
   }
 }
  /*
   * Pull latest from 'source' and 'binary' repository.
   */
  public boolean gitpull() throws GitException {

    boolean result = false;

    // do 'pull' on 'source'
    Git srcgit = Git.wrap(sourceRepository);
    Git bingit = Git.wrap(binaryRepository);

    try {

      PullResult srcpull = srcgit.pull().call();
      PullResult binpull = bingit.pull().call();

      if (srcpull.isSuccessful() && binpull.isSuccessful()) {
        if (srcpull.getFetchResult() != null
            && (srcpull.getFetchResult().getTrackingRefUpdates().size() > 0)) {
          result = true;
        }
        if (srcpull.getMergeResult() != null
            && (srcpull.getMergeResult().getMergeStatus() == MergeStatus.FAST_FORWARD
                || srcpull.getMergeResult().getMergeStatus() == MergeStatus.MERGED)) {
          result = true;
        }

        // TODO: rebase status needs to be checked but it is ignored for now
      }

    } catch (WrongRepositoryStateException e) {
      throw new GitException(e);
    } catch (InvalidConfigurationException e) {
      throw new GitException(e);
    } catch (DetachedHeadException e) {
      throw new GitException(e);
    } catch (InvalidRemoteException e) {
      throw new GitException(e);
    } catch (CanceledException e) {
      throw new GitException(e);
    } catch (RefNotFoundException e) {
      throw new GitException(e);
    } catch (NoHeadException e) {
      throw new GitException(e);
    } catch (TransportException e) {
      throw new GitException(e);
    } catch (GitAPIException e) {
      throw new GitException(e);
    }

    return result;
  }
  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));
    }
  }
  public void updateBinaryRepository() throws IOException, GitException, MapServiceException {

    // 1. Check if repository exists remotely [email protected]/Binary/Repo_Binary.git
    // find the name of the "source repository"
    final String repoUrl = getSourceRemoteUrl();

    // find where ".git" folder is found
    // SourceRepository = D:\dev\devex\binrepo-devex
    // BinaryRepository = D:\dev\devex\.binrepo-devex
    final File srcRepoDir = sourceRepository.getDirectory();
    final File sourceDir = srcRepoDir.getParentFile();

    final String sourceRepoFolder = srcRepoDir.getParentFile().getCanonicalPath();

    final File parent = srcRepoDir.getParentFile().getParentFile();
    final File binaryRepoDir = new File(parent, "." + srcRepoDir.getParentFile().getName());
    System.out.println(
        "SourceRepository = "
            + sourceRepoFolder
            + "\nBinaryRepository = "
            + binaryRepoDir.getCanonicalPath());

    // 2. Get branch/commit hash for the source repo - the actual source code
    final org.eclipse.jgit.lib.Repository repository =
        new org.eclipse.jgit.storage.file.FileRepository(srcRepoDir);
    final String branch = repository.getBranch();

    final RevWalk revWalk = new RevWalk(repository);
    final ObjectId resolve = repository.resolve(Constants.HEAD);
    final RevCommit commit = revWalk.parseCommit(resolve);
    String commitHash = commit.getName();
    System.out.println("CommitHash:" + commitHash + "\tMessage:" + commit.getFullMessage());

    // 3. Call the BinRepo service and check if a corresponding BinRepo entry exists
    final String url =
        getUrlForFindByRepoBranchCommit()
            + "repourl="
            + URLEncoder.encode(repoUrl, UTF_8)
            + "&branch="
            + URLEncoder.encode(branch, UTF_8)
            + "&commitid="
            + URLEncoder.encode(commitHash, UTF_8);
    System.out.println("svc url : " + url);

    WebResource webResource = client.resource(url);

    boolean noContent = false;
    BinRepoBranchCommitDO binRepoBranchCommitDO1 = null;

    try {
      binRepoBranchCommitDO1 =
          webResource.accept(MediaType.APPLICATION_JSON).get(BinRepoBranchCommitDO.class);
    } catch (UniformInterfaceException e) {
      int statusCode = e.getResponse().getClientResponseStatus().getStatusCode();
      System.out.println("Service Status Code : " + statusCode);
      noContent =
          (statusCode == 204 || statusCode == 404); // HTTP 204 is NO CONTENT which is ok for us
    } catch (Exception e) { // Catch-all to deal with network problems etc.
      e.printStackTrace();
    }

    System.out.println(
        binRepoBranchCommitDO1 != null
            ? binRepoBranchCommitDO1.toString()
            : "Resource not found on server");

    // 4. If not copy all the target folders from the source repo to the binary repo - root to root
    // copy of artifacts
    if (noContent) {
      System.out.println(
          "Source Directory:'"
              + sourceDir.getCanonicalPath()
              + "' Destination Directory:'"
              + binaryRepoDir.getCanonicalPath()
              + "'");
      FileUtil.copyBinaries(sourceDir, binaryRepoDir);
    }

    // 5. Call git status to get the delta (Use StatusCommand and refine it)
    Git binaryRepo;
    try {
      binaryRepo = Git.open(binaryRepoDir);
    } catch (IOException e) {
      throw new GitException("Unable to open repository" + binaryRepoDir, e);
    }

    // get "status"
    final StatusCommand statusCommand = binaryRepo.status();
    // TODO: RGIROTI Ask Nambi if we should actually filter this to only add .class files and
    // nothing else
    Collection<String> filesToStage = GitUtils.getFilesToStage(statusCommand);
    /*for (String file : filesToStage) {
        System.out.println("File to be added:" + file);
    }*/

    // add files to "staging" - if there is nothing to stage none of the other operations make any
    // sense at all
    if (filesToStage.size() > 0) {
      final AddCommand addCmd = binaryRepo.add();
      for (String file : filesToStage) {
        addCmd.addFilepattern(file);
      }
      final String[] filesArr = filesToStage.toArray(new String[filesToStage.size()]);
      final String files = StringUtils.join(filesArr, ",");
      try {
        addCmd.call();
      } catch (Exception e) {
        throw new GitException("Unable to add files to repository" + files, e);
      }

      // 6. Commit the changes to local and call push after that (use JGit API for this)
      // 6a. COmmit message should use format "Saving url:branch:commit:UTC time"
      // commit
      final CommitCommand commitCommand = binaryRepo.commit();
      String msg = "Saving Repo:%s Branch:%s CommitHash:%s Time:%s";
      final String formattedMsg =
          String.format(msg, repoUrl, branch, commitHash, new Date().toString());
      commitCommand.setMessage(formattedMsg);
      String commitHashBinRepo;
      try {
        final RevCommit call = commitCommand.call();
        commitHashBinRepo = call.getName();
      } catch (Exception e) {
        throw new GitException("Unable to read commit hash from commit command", e);
      }

      // push to origin now
      final PushCommand push = binaryRepo.push();
      final String remote = push.getRemote();
      final String remoteBranch = push.getRepository().getBranch();
      System.out.println("Remote to push to:'" + remote + "'");
      try {
        push.call();
      } catch (Exception e) {
        throw new GitException("Unable to push to remote", e);
      }

      // Calculate the remote url for binary repository
      String binRepoUrl = calculateBinaryRepositoryUrl();

      // 7. Call the BinRepo service and create a new entity for this change - repoUrl, branch, and
      // commit
      System.out.println(
          "Update Bin Repo Service with the new changes - POST new object to service");
      final BinRepoBranchCommitDO binRepoBranchCommitDO =
          newInstance(repoUrl, branch, commitHash, binRepoUrl, remoteBranch, commitHashBinRepo);
      webResource = client.resource(getUrlForPost());

      BinRepoBranchCommitDO postedDO = null;
      try {
        postedDO =
            webResource
                .accept(MediaType.APPLICATION_XML)
                .post(BinRepoBranchCommitDO.class, binRepoBranchCommitDO);
      } catch (UniformInterfaceException e) {
        int statusCode = e.getResponse().getClientResponseStatus().getStatusCode();
        System.out.println("status code: " + statusCode);
        throw new MapServiceException("Unable to register the commit details in update binrepo", e);
      }
      System.out.println(postedDO != null ? postedDO.toString() : "Post failed");
    }
  }
  public void cloneBinaryRepository() throws GitException {

    // find the name of the "source repository"
    String srcRepoUrl = getSourceRemoteUrl();
    String org = GitUtils.getOrgName(srcRepoUrl);
    String repoName = GitUtils.getRepositoryName(srcRepoUrl);
    String binaryRepoName = calculateBinaryRepositoryName(org, repoName);

    // find where ".git" folder is found
    File f = sourceRepository.getDirectory();
    File sourceDir = f.getParentFile();

    String sourceRepoFolderName = f.getParentFile().getName();

    // construct the binary repository URL
    String giturl = "[email protected]:Binary/" + binaryRepoName + ".git";

    // calculate binary repository folder
    File parent = f.getParentFile().getParentFile();
    File binaryRepoFolder = new File(parent, ("." + sourceRepoFolderName));

    // clone the binary repository
    CloneCommand cloneCmd = Git.cloneRepository();
    cloneCmd.setURI(giturl);
    cloneCmd.setDirectory(binaryRepoFolder);
    cloneCmd.setCloneAllBranches(true);

    Git binrepository = null;

    try {

      System.out.println("cloning repository " + giturl);
      binrepository = cloneCmd.call();

      binaryRepository = new FileRepository(binrepository.getRepository().getDirectory());

    } catch (InvalidRemoteException e) {
      throw new GitException("unable to clone " + giturl, e);
    } catch (TransportException e) {
      throw new GitException("unable to clone " + giturl, e);
    } catch (GitAPIException e) {
      throw new GitException("unable to clone " + giturl, e);
    } catch (IOException e) {
      throw new GitException("unable assign " + giturl, e);
    }

    // read the branch from "source" repository
    String branchName = "master";
    try {
      branchName = sourceRepository.getBranch();
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Checkout the "branch" if it is not equal to "master"
    if (!branchName.toLowerCase().equals("master")) {

      // check whether the branch exists
      boolean remoteBranchExists = GitUtils.isRemoteBranchExists(binaryRepository, branchName);

      CheckoutResult result = null;

      if (!remoteBranchExists) {

        try {

          // create branch
          Git binrepo = Git.wrap(binaryRepository);
          CreateBranchCommand branchCmd = binrepo.branchCreate();
          branchCmd.setName(branchName);
          branchCmd.call();

          // checkout the branch
          CheckoutCommand checkout = binrepo.checkout();
          checkout.setName(branchName);
          Ref ref = checkout.call();

          if (ref == null) {
            // TODO:
          } else {
            result = checkout.getResult();
          }

        } catch (RefAlreadyExistsException e) {
          throw new GitException("unable to create branch " + branchName, e);
        } catch (RefNotFoundException e) {
          throw new GitException("unable to create branch " + branchName, e);
        } catch (InvalidRefNameException e) {
          throw new GitException("unable to create branch " + branchName, e);
        } catch (GitAPIException e) {
          throw new GitException("unable to create branch " + branchName, e);
        }

      } else {

        CheckoutCommand checkoutCmd = binrepository.checkout();
        checkoutCmd.setCreateBranch(true);
        checkoutCmd.setName(branchName);
        checkoutCmd.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK);
        checkoutCmd.setStartPoint("origin/" + branchName);

        System.out.println("checking out branch " + branchName);

        try {
          // Ref branch = branchCmd.call();
          Ref ref = checkoutCmd.call();
          System.out.println("checkout is complete");
          if (ref != null) {
            // System.out.println("ref " + ref.getName() );
            result = checkoutCmd.getResult();
          }

        } catch (RefAlreadyExistsException e) {
          throw new GitException("unable to checkout branch " + branchName, e);
        } catch (RefNotFoundException e) {
          throw new GitException("unable to checkout branch " + branchName, e);
        } catch (InvalidRefNameException e) {
          throw new GitException("unable to checkout branch " + branchName, e);
        } catch (CheckoutConflictException e) {
          throw new GitException("unable to checkout branch " + branchName, e);
        } catch (GitAPIException e) {
          throw new GitException("unable to checkout branch " + branchName, e);
        }
      }

      if (result.getStatus().equals(CheckoutResult.OK_RESULT)) {
        System.out.println("checkout is OK");
      } else {
        // TODO: handle the error.
      }
    }

    // System.out.println( result.getStatus());
    // TODO: find out whether Binary is upto-date with the sources

    /*
    // call the MapSvc to find it out.
          final org.eclipse.jgit.lib.Repository repository = new org.eclipse.jgit.storage.file.FileRepository(f);
          final RevWalk revWalk = new RevWalk(repository);
          final ObjectId resolve = repository.resolve(Constants.HEAD);
          final RevCommit commit = revWalk.parseCommit(resolve);
          final String commitHash = commit.getName();
          final String url = getUrlForFindByRepoBranchCommit() + "repourl=" + URLEncoder.encode(getSourceRemoteUrl(), UTF_8) +
                  "&branch=" + URLEncoder.encode(branchName, UTF_8) + "&commitid=" + URLEncoder.encode(commitHash, UTF_8);

          final WebResource webResource = client.resource(url);
          boolean noContent = false;

          BinRepoBranchCommitDO binRepoBranchCommitDO = null;
          try {
          	System.out.println("calling mapsvc ");
              binRepoBranchCommitDO = webResource.accept(MediaType.APPLICATION_JSON_TYPE).get(BinRepoBranchCommitDO.class);
          } catch (UniformInterfaceException e) {
              int statusCode = e.getResponse().getClientResponseStatus().getStatusCode();
              noContent = (statusCode == 204);
          } catch (Exception e) { // catch-all in case there are network problems
              e.printStackTrace();
          }


          // No matching entry found in mapping service
          // TODO: RGIROTI Talk to Nambi and find out what we want to do in this case
          if (noContent) {

          } else {
              // if it matches copy the .class files from binaryrepository to source-repository
              if (binRepoBranchCommitDO != null &&
                      binRepoBranchCommitDO.getRepoUrl().equalsIgnoreCase(getSourceRemoteUrl()) &&
                      binRepoBranchCommitDO.getBranch().equalsIgnoreCase(branchName) &&
                      binRepoBranchCommitDO.getCommitId().equalsIgnoreCase(commitHash)) {

              }
          }
          */

    try {
      FileUtil.copyBinaryFolders(binaryRepoFolder, sourceDir, ".git");
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  public void createBinaryRepository() throws IOException, GitException, MapServiceException {
    // check whether "binary repository" exists
    if (isBinaryRepositoryAvailable()) throw new GitException("Repository already exists");

    // find the name of the "source repository"
    // String sourceRepoName = getRepositoryName();

    // find where ".git" folder is found
    File f = sourceRepository.getDirectory();
    File sourceRepoFolder = f.getParentFile();

    String sourceRepoFolderName = f.getParentFile().getName();

    // calculate binary repository folder
    File parent = f.getParentFile().getParentFile();
    File binaryRepoFolder = new File(parent, ("." + sourceRepoFolderName));

    // create binary repository folder
    FileUtils.mkdir(binaryRepoFolder, true);

    // initialize "git" repository
    InitCommand initCmd = Git.init();
    initCmd.setDirectory(binaryRepoFolder);
    Git binaryRepo = null;
    try {
      System.out.println("initializing bare repository");
      binaryRepo = initCmd.call();
    } catch (GitAPIException e) {
      throw new GitException("unable to initialize repository", e);
    }

    System.out.println("adding readme.md file");
    createReadMeFile(binaryRepoFolder);

    // get "status"
    StatusCommand statusC = binaryRepo.status();
    Collection<String> toadd = GitUtils.getFilesToStage(statusC);

    // add "readme" file to staging
    if (toadd.size() > 0) {
      AddCommand add = binaryRepo.add();
      for (String file : toadd) {
        add.addFilepattern(file);
      }
      try {
        add.call();
        CommitCommand commit = binaryRepo.commit();
        commit.setMessage("initial commit");
        System.out.println("performing first commit");
        commit.call();
      } catch (NoFilepatternException e) {
        throw new GitException("unable to add file(s)", e);
      } catch (GitAPIException e) {
        throw new GitException("Unable to add or commit", e);
      }
    }

    // Calculate the remote url for binary repository
    String remoteUrl = calculateBinaryRepositoryUrl();

    // TODO: check whether the remote exists, if not create it, else fail
    GitHub github = new GitHubClient().getGithub();
    GHOrganization githubOrg = github.getOrganization("Binary");
    GHRepository repository = githubOrg.getRepository(GitUtils.getRepositoryName(remoteUrl));

    if (repository == null) {

      System.out.println("creating remote repository : " + remoteUrl);
      GHRepository repo =
          githubOrg.createRepository(
              GitUtils.getRepositoryName(remoteUrl),
              "Binary repository",
              "https://github.scm.corp.ebay.com",
              "Owners",
              true);

      System.out.println(repo.getUrl() + " created successfully ");

    } else {
      // fail, it shouldn't come here
    }

    // add "remote" repository
    StoredConfig config = binaryRepo.getRepository().getConfig();
    config.setString("remote", "origin", "url", remoteUrl);
    System.out.println("adding remote origin " + remoteUrl);
    config.save();

    // get "status"
    StatusCommand stat = binaryRepo.status();
    Collection<String> filesToAdd = GitUtils.getFilesToStage(stat);

    // add files to "staging"
    if (filesToAdd.size() > 0) {
      AddCommand addCmd = binaryRepo.add();
      for (String file : filesToAdd) {
        addCmd.addFilepattern(file);
      }
      try {
        addCmd.call();
      } catch (NoFilepatternException e) {
        throw new GitException("unable to add files", e);
      } catch (GitAPIException e) {
        throw new GitException("unable to add files", e);
      }
    }

    // commit
    System.out.println("commiting the files");
    CommitCommand commit = binaryRepo.commit();
    // add the 'source' repository git-url, commit-id and branch
    commit.setMessage("adding readme.md file");

    try {
      commit.call();
    } catch (NoHeadException e) {
      throw new GitException("unable to commit", e);
    } catch (NoMessageException e) {
      throw new GitException("unable to commit", e);
    } catch (UnmergedPathsException e) {
      throw new GitException("unable to commit", e);
    } catch (ConcurrentRefUpdateException e) {
      throw new GitException("unable to commit", e);
    } catch (WrongRepositoryStateException e) {
      throw new GitException("unable to commit", e);
    } catch (GitAPIException e) {
      throw new GitException("unable to commit", e);
    }

    // push
    System.out.println("pushing to remote");
    PushCommand push = binaryRepo.push();
    try {
      push.call();
    } catch (InvalidRemoteException e) {
      throw new GitException("unable to push", e);
    } catch (TransportException e) {
      throw new GitException("unable to push", e);
    } catch (GitAPIException e) {
      throw new GitException("unable to push", e);
    }

    // read the branch from "source" repository
    String branchname = sourceRepository.getBranch();

    // create a "branch"
    if (!branchname.toLowerCase().equals("master")) {
      CreateBranchCommand branchCmd = binaryRepo.branchCreate();
      branchCmd.setName(branchname);
      try {
        // create branch
        branchCmd.call();

        // checkout the branch
        CheckoutCommand checkout = binaryRepo.checkout();
        checkout.setName(branchname);
        checkout.call();
      } catch (RefAlreadyExistsException e) {
        throw new GitException("unable to create a branch", e);
      } catch (RefNotFoundException e) {
        throw new GitException("unable to create a branch", e);
      } catch (InvalidRefNameException e) {
        throw new GitException("unable to create a branch", e);
      } catch (GitAPIException e) {
        throw new GitException("unable to create a branch", e);
      }
    }

    // find the "localobr" folders and exclude them during copy
    List<String> excludes = new ArrayList<String>();
    Collection<File> excludeFiles =
        FileUtil.findDirectoriesThatEndWith(sourceRepoFolder, "localobr");
    for (File file : excludeFiles) {
      excludes.add(file.getCanonicalPath());
    }

    // copy the classes
    System.out.println("copying binary files");
    copyBinaryFolders("target", excludes, binaryRepoFolder);

    // get "status"
    StatusCommand statusCmd = binaryRepo.status();
    Collection<String> tobeAdded = GitUtils.getFilesToStage(statusCmd);

    // add files to "staging"
    if (tobeAdded.size() > 0) {
      AddCommand addCmd = binaryRepo.add();
      for (String file : tobeAdded) {
        addCmd.addFilepattern(file);
      }
      try {
        addCmd.call();
      } catch (NoFilepatternException e) {
        throw new GitException("unable to add files", e);
      } catch (GitAPIException e) {
        throw new GitException("unable to add files", e);
      }
    }

    // commit
    System.out.println("commiting the files");
    CommitCommand commit1 = binaryRepo.commit();
    commit1.setMessage("saving the files");

    try {
      commit1.call();
    } catch (NoHeadException e) {
      throw new GitException("unable to commit", e);
    } catch (NoMessageException e) {
      throw new GitException("unable to commit", e);
    } catch (UnmergedPathsException e) {
      throw new GitException("unable to commit", e);
    } catch (ConcurrentRefUpdateException e) {
      throw new GitException("unable to commit", e);
    } catch (WrongRepositoryStateException e) {
      throw new GitException("unable to commit", e);
    } catch (GitAPIException e) {
      throw new GitException("unable to commit", e);
    }

    // push
    System.out.println("pushing to remote");
    PushCommand pushCmd = binaryRepo.push();
    try {
      pushCmd.call();
    } catch (InvalidRemoteException e) {
      throw new GitException("unable to push", e);
    } catch (TransportException e) {
      throw new GitException("unable to push", e);
    } catch (GitAPIException e) {
      throw new GitException("unable to push", e);
    }

    final String repoUrl = getSourceRemoteUrl();
    // branchName was computed above
    final org.eclipse.jgit.lib.Repository repo =
        new org.eclipse.jgit.storage.file.FileRepository(f);
    final RevWalk revWalk = new RevWalk(repo);
    final ObjectId resolve = repo.resolve(Constants.HEAD);
    final RevCommit commitRev = revWalk.parseCommit(resolve);
    final String commitHash = commitRev.getName();

    Git git = Git.open(binaryRepoFolder);
    final RevCommit binRepoResolveCommitRev;
    try {
      binRepoResolveCommitRev = git.log().call().iterator().next();
    } catch (NoHeadException e) {
      throw new GitException("No head found for repo", e);
    } catch (GitAPIException e) {
      throw new GitException("No head found for repo", e);
    }
    final String binRepoResolveCommitHash = binRepoResolveCommitRev.getName();
    final String binRepoBranchName = git.getRepository().getBranch();

    System.out.println("Update Bin Repo Service with the new changes - POST new object to service");
    final BinRepoBranchCommitDO binRepoBranchCommitDO =
        newInstance(
            repoUrl,
            branchname,
            commitHash,
            remoteUrl,
            binRepoBranchName,
            binRepoResolveCommitHash);
    final WebResource resource = client.resource(getUrlForPost());

    BinRepoBranchCommitDO postedDO = null;
    try {
      postedDO =
          resource
              .accept(MediaType.APPLICATION_XML)
              .post(BinRepoBranchCommitDO.class, binRepoBranchCommitDO);
      System.out.println("Posted Object = " + postedDO.toString());
    } catch (UniformInterfaceException e) {
      int statusCode = e.getResponse().getClientResponseStatus().getStatusCode();
      System.out.println("status code: " + statusCode);
      throw new MapServiceException("Unable to register the commit details", e);
    }

    // System.out.println(postedDO != null ? postedDO.toString() : "postedDO was null");
    System.out.println("updated the map service");
  }