Ref head = getHead();
ObjectReader reader = repo.newObjectReader();
try {
RevCommit headCommit = parseCommit(reader, head.getObjectId());
DirCache cache = repo.lockDirCache();
ObjectInserter inserter = repo.newObjectInserter();
ObjectId commitId;
try {
TreeWalk treeWalk = new TreeWalk(reader);
treeWalk.setRecursive(true);
treeWalk.addTree(headCommit.getTree());
treeWalk.addTree(new DirCacheIterator(cache));
treeWalk.addTree(new FileTreeIterator(repo));
treeWalk.setFilter(AndTreeFilter.create(new SkipWorkTreeFilter(
1), new IndexDiffFilter(1, 2)));
// Return null if no local changes to stash
if (!treeWalk.next())
return null;
MutableObjectId id = new MutableObjectId();
List<PathEdit> wtEdits = new ArrayList<PathEdit>();
List<String> wtDeletes = new ArrayList<String>();
List<DirCacheEntry> untracked = new ArrayList<DirCacheEntry>();
boolean hasChanges = false;
do {
AbstractTreeIterator headIter = treeWalk.getTree(0,
AbstractTreeIterator.class);
DirCacheIterator indexIter = treeWalk.getTree(1,
DirCacheIterator.class);
WorkingTreeIterator wtIter = treeWalk.getTree(2,
WorkingTreeIterator.class);
if (indexIter != null
&& !indexIter.getDirCacheEntry().isMerged())
throw new UnmergedPathsException(
new UnmergedPathException(
indexIter.getDirCacheEntry()));
if (wtIter != null) {
if (indexIter == null && headIter == null
&& !includeUntracked)
continue;
hasChanges = true;
if (indexIter != null && wtIter.idEqual(indexIter))
continue;
if (headIter != null && wtIter.idEqual(headIter))
continue;
treeWalk.getObjectId(id, 0);
final DirCacheEntry entry = new DirCacheEntry(
treeWalk.getRawPath());
entry.setLength(wtIter.getEntryLength());
entry.setLastModified(wtIter.getEntryLastModified());
entry.setFileMode(wtIter.getEntryFileMode());
long contentLength = wtIter.getEntryContentLength();
InputStream in = wtIter.openEntryStream();
try {
entry.setObjectId(inserter.insert(
Constants.OBJ_BLOB, contentLength, in));
} finally {
in.close();
}
if (indexIter == null && headIter == null)
untracked.add(entry);
else
wtEdits.add(new PathEdit(entry) {
public void apply(DirCacheEntry ent) {
ent.copyMetaData(entry);
}
});
}
hasChanges = true;
if (wtIter == null && headIter != null)
wtDeletes.add(treeWalk.getPathString());
} while (treeWalk.next());
if (!hasChanges)
return null;
String branch = Repository.shortenRefName(head.getTarget()
.getName());
// Commit index changes
CommitBuilder builder = createBuilder();
builder.setParentId(headCommit);
builder.setTreeId(cache.writeTree(inserter));
builder.setMessage(MessageFormat.format(indexMessage, branch,
headCommit.abbreviate(7).name(),
headCommit.getShortMessage()));
ObjectId indexCommit = inserter.insert(builder);
// Commit untracked changes
ObjectId untrackedCommit = null;
if (!untracked.isEmpty()) {
DirCache untrackedDirCache = DirCache.newInCore();
DirCacheBuilder untrackedBuilder = untrackedDirCache
.builder();
for (DirCacheEntry entry : untracked)
untrackedBuilder.add(entry);
untrackedBuilder.finish();
builder.setParentIds(new ObjectId[0]);
builder.setTreeId(untrackedDirCache.writeTree(inserter));
builder.setMessage(MessageFormat.format(MSG_UNTRACKED,
branch, headCommit.abbreviate(7).name(),
headCommit.getShortMessage()));
untrackedCommit = inserter.insert(builder);
}