protected void doCherryPick(Exchange exchange, String operation) throws Exception { CherryPickResult result = null; String commitId = null; try { if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(GitConstants.GIT_COMMIT_ID))) { commitId = exchange.getIn().getHeader(GitConstants.GIT_COMMIT_ID, String.class); } else { throw new IllegalArgumentException("Commit id must be specified to execute " + operation); } RevWalk walk = new RevWalk(repo); ObjectId id = repo.resolve(commitId); RevCommit commit = walk.parseCommit(id); walk.dispose(); if (ObjectHelper.isNotEmpty(endpoint.getBranchName())) { git.checkout().setCreateBranch(false).setName(endpoint.getBranchName()).call(); } result = git.cherryPick().include(commit).call(); } catch (Exception e) { LOG.error("There was an error in Git " + operation + " operation"); throw e; } exchange.getOut().setBody(result); }
private void cherryPickCommitToBranch(ObjectId id, Project project, Branch branch) { doWithGit(project, git -> { try { checkout(project, branch); } catch (RuntimeException o_O) { logger.log(project, "Couldn't check out branch %s. Skipping cherrypick of commit %s.", branch, id.getName()); return; } logger.log(project, "git cp %s", id.getName()); CherryPickResult result = git.cherryPick().include(id).call(); if (result.getStatus().equals(CherryPickStatus.OK)) { logger.log(project, "Successfully cherry-picked commit %s to branch %s.", id.getName(), branch); } else { logger.warn(project, "Cherry pick failed. aborting…"); logger.log(project, "git reset --hard"); git.reset().setMode(ResetType.HARD).call(); } }); }
private GitCherryPickResult createResult (CherryPickResult res, List<Ref> cherryPickedRefs) { GitRevisionInfo currHead = getCurrentHead(); GitCherryPickResult.CherryPickStatus status = GitCherryPickResult.CherryPickStatus.valueOf(res.getStatus().name()); List<File> conflicts; if (res.getStatus() == CherryPickResult.CherryPickStatus.CONFLICTING) { conflicts = getConflicts(currHead); } else { conflicts = Collections.<File>emptyList(); } List<GitRevisionInfo> commits = toCommits(cherryPickedRefs); return getClassFactory().createCherryPickResult(status, conflicts, getFailures(res), currHead, commits); }
private List<File> getFailures (CherryPickResult result) { List<File> files = new ArrayList<>(); File workDir = getRepository().getWorkTree(); if (result.getStatus() == CherryPickResult.CherryPickStatus.FAILED) { Map<String, ResolveMerger.MergeFailureReason> obstructions = result.getFailingPaths(); if (obstructions != null) { for (Map.Entry<String, ResolveMerger.MergeFailureReason> failure : obstructions.entrySet()) { files.add(new File(workDir, failure.getKey())); } } } return Collections.unmodifiableList(files); }
@Override protected void run () throws GitException { Repository repository = getRepository(); ObjectId originalCommit = getOriginalCommit(); ObjectId head = getHead(); List<RebaseTodoLine> steps; try { switch (operation) { case BEGIN: // initialize sequencer and cherry-pick steps if there are // more commits to cherry-pick steps = prepareCommand(head); // apply the selected steps applySteps(steps, false); break; case ABORT: // delete the sequencer and reset to the original head if (repository.getRepositoryState() == RepositoryState.CHERRY_PICKING || repository.getRepositoryState() == RepositoryState.CHERRY_PICKING_RESOLVED) { if (originalCommit == null) { // maybe the sequencer is not created in that case simply reset to HEAD originalCommit = head; } } Utils.deleteRecursively(getSequencerFolder()); if (originalCommit != null) { ResetCommand reset = new ResetCommand(repository, getClassFactory(), originalCommit.name(), GitClient.ResetType.HARD, new DelegatingGitProgressMonitor(monitor), listener); reset.execute(); } result = createCustomResult(GitCherryPickResult.CherryPickStatus.ABORTED); break; case QUIT: // used to reset the sequencer only Utils.deleteRecursively(getSequencerFolder()); switch (repository.getRepositoryState()) { case CHERRY_PICKING: // unresolved conflicts result = createResult(CherryPickResult.CONFLICT); break; case CHERRY_PICKING_RESOLVED: result = createCustomResult(GitCherryPickResult.CherryPickStatus.UNCOMMITTED); break; default: result = createCustomResult(GitCherryPickResult.CherryPickStatus.OK); break; } break; case CONTINUE: switch (repository.getRepositoryState()) { case CHERRY_PICKING: // unresolved conflicts, cannot continue result = createResult(CherryPickResult.CONFLICT); break; case CHERRY_PICKING_RESOLVED: // cannot continue without manual commit result = createCustomResult(GitCherryPickResult.CherryPickStatus.UNCOMMITTED); break; default: // read steps from sequencer and apply them // if sequencer is empty this will be a noop steps = readTodoFile(repository); applySteps(steps, true); break; } break; default: throw new IllegalStateException("Unexpected operation " + operation.name()); } } catch (GitAPIException | IOException ex) { throw new GitException(ex); } }
private void applySteps (List<RebaseTodoLine> steps, boolean skipFirstStep) throws GitAPIException, IOException { Repository repository = getRepository(); ObjectReader or = repository.newObjectReader(); CherryPickResult res = null; boolean skipped = false; List<Ref> cherryPickedRefs = new ArrayList<>(); for (Iterator<RebaseTodoLine> it = steps.iterator(); it.hasNext();) { RebaseTodoLine step = it.next(); if (step.getAction() == RebaseTodoLine.Action.PICK) { if (skipFirstStep && !skipped) { it.remove(); writeTodoFile(repository, steps); skipped = true; continue; } Collection<ObjectId> ids = or.resolve(step.getCommit()); if (ids.size() != 1) { throw new JGitInternalException("Could not resolve uniquely the abbreviated object ID"); } org.eclipse.jgit.api.CherryPickCommand command = new Git(repository).cherryPick(); command.include(ids.iterator().next()); if (workAroundStrategyIssue) { command.setStrategy(new FailuresDetectRecurciveStrategy()); } res = command.call(); if (res.getStatus() == CherryPickResult.CherryPickStatus.OK) { it.remove(); writeTodoFile(repository, steps); cherryPickedRefs.addAll(res.getCherryPickedRefs()); } else { break; } } else { it.remove(); } } if (res == null) { result = createCustomResult(GitCherryPickResult.CherryPickStatus.OK, cherryPickedRefs); } else { result = createResult(res, cherryPickedRefs); } if (steps.isEmpty()) { // sequencer no longer needed Utils.deleteRecursively(getSequencerFolder()); } }
private GitCherryPickResult createResult (CherryPickResult res) { return createResult(res, Collections.<Ref>emptyList()); }
public void testCherryPickStatus () { for (CherryPickResult.CherryPickStatus status : CherryPickResult.CherryPickStatus.values()) { assertNotNull(GitCherryPickResult.CherryPickStatus.valueOf(status.name())); } }