* This will default to apply the latest stashed commit (stash@{0}) if * unspecified * * @param stashRef * name of the stash {@code Ref} to apply * @return {@code this} */ public StashApplyCommand setStashRef(String stashRef) { this.stashRef = stashRef; return this; } /** * Whether to ignore the repository state when applying the stash * * @param willIgnoreRepositoryState * whether to ignore the repository state when applying the stash * @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; } /** * {@inheritDoc} *
* Apply the changes in a stashed commit to the working directory and index
*/
@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 (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);
ListMergeStrategy
to use.
*
* @param strategy
* The merge strategy to use in order to merge during this
* command execution.
* @return {@code this}
* @since 3.4
*/
public StashApplyCommand setStrategy(MergeStrategy strategy) {
this.strategy = strategy;
return this;
}
/**
* Sets the content merge strategy to use if the
* {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or
* "recursive".
*
* @param strategy
* the {@link ContentMergeStrategy} to be used
* @return {@code this}
* @since 5.12
*/
public StashApplyCommand setContentMergeStrategy(
ContentMergeStrategy strategy) {
checkCallable();
this.contentStrategy = strategy;
return this;
}
/**
* Whether the command should restore untracked files
*
* @param applyUntracked
* true (default) if the command should restore untracked files
* @since 3.4
* @deprecated use {@link #setRestoreUntracked} instead
*/
@Deprecated
public void setApplyUntracked(boolean applyUntracked) {
this.restoreUntracked = applyUntracked;
}
/**
* Whether the command should restore untracked files
*
* @param restoreUntracked
* true (default) if the command should restore untracked files
* @return {@code this}
* @since 5.3
*/
public StashApplyCommand setRestoreUntracked(boolean restoreUntracked) {
this.restoreUntracked = restoreUntracked;
return this;
}
private void resetIndex(RevTree tree) throws IOException {
DirCache dc = repo.lockDirCache();
try (TreeWalk walk = new TreeWalk(repo)) {
DirCacheBuilder builder = dc.builder();
walk.addTree(tree);
walk.addTree(new DirCacheIterator(dc));
walk.setRecursive(true);
while (walk.next()) {
AbstractTreeIterator cIter = walk.getTree(0,
AbstractTreeIterator.class);
if (cIter == null) {
// Not in commit, don't add to new index
continue;
}
final DirCacheEntry entry = new DirCacheEntry(walk.getRawPath());
entry.setFileMode(cIter.getEntryFileMode());
entry.setObjectIdFromRaw(cIter.idBuffer(), cIter.idOffset());
DirCacheIterator dcIter = walk.getTree(1,
DirCacheIterator.class);
if (dcIter != null && dcIter.idEqual(cIter)) {
DirCacheEntry indexEntry = dcIter.getDirCacheEntry();
entry.setLastModified(indexEntry.getLastModifiedInstant());
entry.setLength(indexEntry.getLength());
}
builder.add(entry);
}
builder.commit();
} finally {
dc.unlock();
}
}
private void resetUntracked(RevTree tree) throws CheckoutConflictException,
IOException {
Set