* This will default to apply the latest stashed commit (stash@{0}) if
* unspecified
*
* @param stashRef
* @return {@code this}
*/
public StashApplyCommand setStashRef(final String stashRef) {
this.stashRef = stashRef;
return this;
}
/**
* @param willIgnoreRepositoryState
* @return {@code this}
* @since 3.2
*/
public StashApplyCommand ignoreRepositoryState(boolean willIgnoreRepositoryState) {
this.ignoreRepositoryState = willIgnoreRepositoryState;
return this;
}
private ObjectId getStashId() throws GitAPIException {
final String revision = stashRef != null ? stashRef : DEFAULT_REF;
final ObjectId stashId;
try {
stashId = repo.resolve(revision);
} catch (IOException e) {
throw new InvalidRefNameException(MessageFormat.format(
JGitText.get().stashResolveFailed, revision), e);
}
if (stashId == null)
throw new InvalidRefNameException(MessageFormat.format(
JGitText.get().stashResolveFailed, revision));
return stashId;
}
/**
* Apply the changes in a stashed commit to the working directory and index
*
* @return id of stashed commit that was applied TODO: Does anyone depend on
* this, or could we make it more like Merge/CherryPick/Revert?
* @throws GitAPIException
* @throws WrongRepositoryStateException
* @throws NoHeadException
* @throws StashApplyFailureException
*/
@Override
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 (applyUntracked && stashCommit.getParentCount() == 3)
untrackedCommit = revWalk.parseCommit(stashCommit.getParent(2));
ResolveMerger merger = (ResolveMerger) strategy.newMerger(repo);
merger.setCommitNames(new String[] { "stashed HEAD", "HEAD", //$NON-NLS-1$ //$NON-NLS-2$
"stash" }); //$NON-NLS-1$
merger.setBase(stashHeadCommit);
merger.setWorkingTreeIterator(new FileTreeIterator(repo));
boolean mergeSucceeded = merger.merge(headCommit, stashCommit);
List