&& repo.getRepositoryState() != RepositoryState.SAFE)
throw new WrongRepositoryStateException(MessageFormat.format(
JGitText.get().stashApplyOnUnsafeRepository,
repo.getRepositoryState()));
ObjectReader reader = repo.newObjectReader();
try {
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 (applyUntracked && stashCommit.getParentCount() == 3)
untrackedCommit = revWalk.parseCommit(stashCommit.getParent(2));
ResolveMerger merger = (ResolveMerger) strategy.newMerger(repo);
merger.setCommitNames(new String[] { "stashed HEAD", "HEAD",
"stash" });
merger.setBase(stashHeadCommit);
merger.setWorkingTreeIterator(new FileTreeIterator(repo));
if (merger.merge(headCommit, stashCommit)) {
DirCache dc = repo.lockDirCache();
DirCacheCheckout dco = new DirCacheCheckout(repo, headTree,
dc, merger.getResultTreeId());
dco.setFailOnConflict(true);
dco.checkout(); // Ignoring failed deletes....
if (applyIndex) {
ResolveMerger ixMerger = (ResolveMerger) strategy
.newMerger(repo, true);
ixMerger.setCommitNames(new String[] { "stashed HEAD",
"HEAD", "stashed index" });
ixMerger.setBase(stashHeadCommit);
boolean ok = ixMerger.merge(headCommit, stashIndexCommit);
if (ok) {
resetIndex(revWalk
.parseTree(ixMerger.getResultTreeId()));
} else {
throw new StashApplyFailureException(
JGitText.get().stashApplyConflict);
}
}
if (untrackedCommit != null) {
ResolveMerger untrackedMerger = (ResolveMerger) strategy
.newMerger(repo, true);
untrackedMerger.setCommitNames(new String[] {
"stashed HEAD", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
untrackedMerger.setBase(stashHeadCommit);
boolean ok = untrackedMerger.merge(headCommit,
untrackedCommit);
if (ok)
try {
RevTree untrackedTree = revWalk
.parseTree(untrackedMerger
.getResultTreeId());
resetUntracked(untrackedTree);
} catch (CheckoutConflictException e) {
throw new StashApplyFailureException(
JGitText.get().stashApplyConflict);
}
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);
} finally {
reader.release();
}
}