public ObjectId call()

in org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java [139:261]


	public ObjectId call() throws GitAPIException,
			WrongRepositoryStateException, NoHeadException,
			StashApplyFailureException {
		checkCallable();

		if (!ignoreRepositoryState
				&& repo.getRepositoryState() != RepositoryState.SAFE)
			throw new WrongRepositoryStateException(MessageFormat.format(
					JGitText.get().stashApplyOnUnsafeRepository,
					repo.getRepositoryState()));

		try (ObjectReader reader = repo.newObjectReader();
				RevWalk revWalk = new RevWalk(reader)) {

			ObjectId headCommit = repo.resolve(Constants.HEAD);
			if (headCommit == null)
				throw new NoHeadException(JGitText.get().stashApplyWithoutHead);

			final ObjectId stashId = getStashId();
			RevCommit stashCommit = revWalk.parseCommit(stashId);
			if (stashCommit.getParentCount() < 2
					|| stashCommit.getParentCount() > 3)
				throw new JGitInternalException(MessageFormat.format(
						JGitText.get().stashCommitIncorrectNumberOfParents,
						stashId.name(),
						Integer.valueOf(stashCommit.getParentCount())));

			ObjectId headTree = repo.resolve(Constants.HEAD + "^{tree}"); //$NON-NLS-1$
			ObjectId stashIndexCommit = revWalk.parseCommit(stashCommit
					.getParent(1));
			ObjectId stashHeadCommit = stashCommit.getParent(0);
			ObjectId untrackedCommit = null;
			if (restoreUntracked && stashCommit.getParentCount() == 3)
				untrackedCommit = revWalk.parseCommit(stashCommit.getParent(2));

			Merger merger = strategy.newMerger(repo);
			boolean mergeSucceeded;
			if (merger instanceof ResolveMerger) {
				ResolveMerger resolveMerger = (ResolveMerger) merger;
				resolveMerger
						.setCommitNames(new String[] { "stashed HEAD", "HEAD", //$NON-NLS-1$ //$NON-NLS-2$
								"stash" }); //$NON-NLS-1$
				resolveMerger.setBase(stashHeadCommit);
				resolveMerger
						.setWorkingTreeIterator(new FileTreeIterator(repo));
				resolveMerger.setContentMergeStrategy(contentStrategy);
				mergeSucceeded = resolveMerger.merge(headCommit, stashCommit);
				List<String> modifiedByMerge = resolveMerger.getModifiedFiles();
				if (!modifiedByMerge.isEmpty()) {
					repo.fireEvent(new WorkingTreeModifiedEvent(modifiedByMerge,
							null));
				}
			} else {
				mergeSucceeded = merger.merge(headCommit, stashCommit);
			}
			if (mergeSucceeded) {
				DirCache dc = repo.lockDirCache();
				DirCacheCheckout dco = new DirCacheCheckout(repo, headTree,
						dc, merger.getResultTreeId());
				dco.setFailOnConflict(true);
				dco.checkout(); // Ignoring failed deletes....
				if (restoreIndex) {
					Merger ixMerger = strategy.newMerger(repo, true);
					if (ixMerger instanceof ResolveMerger) {
						ResolveMerger resolveMerger = (ResolveMerger) ixMerger;
						resolveMerger.setCommitNames(new String[] { "stashed HEAD", //$NON-NLS-1$
								"HEAD", "stashed index" }); //$NON-NLS-1$//$NON-NLS-2$
						resolveMerger.setBase(stashHeadCommit);
						resolveMerger.setContentMergeStrategy(contentStrategy);
					}
					boolean ok = ixMerger.merge(headCommit, stashIndexCommit);
					if (ok) {
						resetIndex(revWalk
								.parseTree(ixMerger.getResultTreeId()));
					} else {
						throw new StashApplyFailureException(
								JGitText.get().stashApplyConflict);
					}
				}

				if (untrackedCommit != null) {
					Merger untrackedMerger = strategy.newMerger(repo, true);
					if (untrackedMerger instanceof ResolveMerger) {
						ResolveMerger resolveMerger = (ResolveMerger) untrackedMerger;
						resolveMerger.setCommitNames(new String[] { "null", "HEAD", //$NON-NLS-1$//$NON-NLS-2$
								"untracked files" }); //$NON-NLS-1$
						// There is no common base for HEAD & untracked files
						// because the commit for untracked files has no parent.
						// If we use stashHeadCommit as common base (as in the
						// other merges) we potentially report conflicts for
						// files which are not even member of untracked files
						// commit.
						resolveMerger.setBase(null);
						resolveMerger.setContentMergeStrategy(contentStrategy);
					}
					boolean ok = untrackedMerger.merge(headCommit,
							untrackedCommit);
					if (ok) {
						try {
							RevTree untrackedTree = revWalk
									.parseTree(untrackedCommit);
							resetUntracked(untrackedTree);
						} catch (CheckoutConflictException e) {
							throw new StashApplyFailureException(
									JGitText.get().stashApplyConflict, e);
						}
					} else {
						throw new StashApplyFailureException(
								JGitText.get().stashApplyConflict);
					}
				}
			} else {
				throw new StashApplyFailureException(
						JGitText.get().stashApplyConflict);
			}
			return stashId;

		} catch (JGitInternalException e) {
			throw e;
		} catch (IOException e) {
			throw new JGitInternalException(JGitText.get().stashApplyFailed, e);
		}
	}