private boolean doCheckout() throws CorruptObjectException, IOException,
MissingObjectException, IncorrectObjectTypeException,
CheckoutConflictException, IndexWriteException {
toBeDeleted.clear();
ObjectReader objectReader = repo.getObjectDatabase().newReader();
try {
if (headCommitTree != null)
preScanTwoTrees();
else
prescanOneTree();
if (!conflicts.isEmpty()) {
if (failOnConflict)
throw new CheckoutConflictException(conflicts.toArray(new String[conflicts.size()]));
else
cleanUpConflicts();
}
// update our index
builder.finish();
File file = null;
String last = "";
// when deleting files process them in the opposite order as they have
// been reported. This ensures the files are deleted before we delete
// their parent folders
for (int i = removed.size() - 1; i >= 0; i--) {
String r = removed.get(i);
file = new File(repo.getWorkTree(), r);
if (!file.delete() && file.exists()) {
// The list of stuff to delete comes from the index
// which will only contain a directory if it is
// a submodule, in which case we shall not attempt
// to delete it. A submodule is not empty, so it
// is safe to check this after a failed delete.
if (!file.isDirectory())
toBeDeleted.add(r);
} else {
if (!isSamePrefix(r, last))
removeEmptyParents(new File(repo.getWorkTree(), last));
last = r;
}
}
if (file != null)
removeEmptyParents(file);
for (String path : updated.keySet()) {
// ... create/overwrite this file ...
file = new File(repo.getWorkTree(), path);
if (!file.getParentFile().mkdirs()) {
// ignore
}
DirCacheEntry entry = dc.getEntry(path);
// submodules are handled with separate operations
if (FileMode.GITLINK.equals(entry.getRawMode()))
continue;
checkoutEntry(repo, file, entry, objectReader);
}
// commit the index builder - a new index is persisted
if (!builder.commit())
throw new IndexWriteException();
} finally {
objectReader.release();
}
return toBeDeleted.size() == 0;
}