/** * Execute the SubmoduleUpdateCommand command. * * @return a collection of updated submodule paths * @throws ConcurrentRefUpdateException * @throws CheckoutConflictException * @throws InvalidMergeHeadsException * @throws InvalidConfigurationException * @throws NoHeadException * @throws NoMessageException * @throws RefNotFoundException * @throws WrongRepositoryStateException * @throws GitAPIException */ public Collection<String> call() throws InvalidConfigurationException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException, InvalidMergeHeadsException, WrongRepositoryStateException, NoMessageException, NoHeadException, RefNotFoundException, GitAPIException { checkCallable(); try { SubmoduleWalk generator = SubmoduleWalk.forIndex(repo); if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); List<String> updated = new ArrayList<String>(); while (generator.next()) { // Skip submodules not registered in .gitmodules file if (generator.getModulesPath() == null) continue; // Skip submodules not registered in parent repository's config String url = generator.getConfigUrl(); if (url == null) continue; Repository submoduleRepo = generator.getRepository(); // Clone repository is not present if (submoduleRepo == null) { CloneCommand clone = Git.cloneRepository(); configure(clone); clone.setURI(url); clone.setDirectory(generator.getDirectory()); clone.setGitDir( new File(new File(repo.getDirectory(), Constants.MODULES), generator.getPath())); if (monitor != null) clone.setProgressMonitor(monitor); submoduleRepo = clone.call().getRepository(); } try { RevWalk walk = new RevWalk(submoduleRepo); RevCommit commit = walk.parseCommit(generator.getObjectId()); String update = generator.getConfigUpdate(); if (ConfigConstants.CONFIG_KEY_MERGE.equals(update)) { MergeCommand merge = new MergeCommand(submoduleRepo); merge.include(commit); merge.setStrategy(strategy); merge.call(); } else if (ConfigConstants.CONFIG_KEY_REBASE.equals(update)) { RebaseCommand rebase = new RebaseCommand(submoduleRepo); rebase.setUpstream(commit); rebase.setStrategy(strategy); rebase.call(); } else { // Checkout commit referenced in parent repository's // index as a detached HEAD DirCacheCheckout co = new DirCacheCheckout(submoduleRepo, submoduleRepo.lockDirCache(), commit.getTree()); co.setFailOnConflict(true); co.checkout(); RefUpdate refUpdate = submoduleRepo.updateRef(Constants.HEAD, true); refUpdate.setNewObjectId(commit); refUpdate.forceUpdate(); } } finally { submoduleRepo.close(); } updated.add(generator.getPath()); } return updated; } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } catch (ConfigInvalidException e) { throw new InvalidConfigurationException(e.getMessage(), e); } }
public static CherryPickResult cherryPickNoMerge(final Git git, Ref src) throws GitAPIException, CantMergeCommitWithZeroParentsException { // Does the same as the original git-cherryPick // except commiting after running merger Repository repo = git.getRepository(); RevCommit newHead = null; List<Ref> cherryPickedRefs = new LinkedList<Ref>(); RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.getRef(Constants.HEAD); if (headRef == null) throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId()); newHead = headCommit; // get the commit to be cherry-picked // handle annotated tags ObjectId srcObjectId = src.getPeeledObjectId(); if (srcObjectId == null) srcObjectId = src.getObjectId(); RevCommit srcCommit = revWalk.parseCommit(srcObjectId); // get the parent of the commit to cherry-pick if (srcCommit.getParentCount() == 0) throw new CantMergeCommitWithZeroParentsException( "Commit with zero parents cannot be merged"); if (srcCommit.getParentCount() > 1) throw new MultipleParentsNotAllowedException( MessageFormat.format( JGitText.get().canOnlyCherryPickCommitsWithOneParent, srcCommit.name(), Integer.valueOf(srcCommit.getParentCount()))); RevCommit srcParent = srcCommit.getParent(0); revWalk.parseHeaders(srcParent); ResolveMerger merger = (ResolveMerger) MergeStrategy.RESOLVE.newMerger(repo); merger.setWorkingTreeIterator(new FileTreeIterator(repo)); merger.setBase(srcParent.getTree()); if (merger.merge(headCommit, srcCommit)) { DirCacheCheckout dco = new DirCacheCheckout( repo, headCommit.getTree(), repo.lockDirCache(), merger.getResultTreeId()); dco.setFailOnConflict(true); dco.checkout(); cherryPickedRefs.add(src); } else { if (merger.failed()) return new CherryPickResult(merger.getFailingPaths()); // there are merge conflicts String message = new MergeMessageFormatter() .formatWithConflicts(srcCommit.getFullMessage(), merger.getUnmergedPaths()); repo.writeCherryPickHead(srcCommit.getId()); repo.writeMergeCommitMsg(message); return CherryPickResult.CONFLICT; } } catch (IOException e) { throw new JGitInternalException( MessageFormat.format(JGitText.get().exceptionCaughtDuringExecutionOfCherryPickCommand, e), e); } finally { revWalk.release(); } return new CherryPickResult(newHead, cherryPickedRefs); }