@Nullable final NodeRef rightTreeRef) {
Preconditions.checkArgument(leftTreeRef != null || rightTreeRef != null,
"either left or right tree shall be non null");
final ObjectDatabase repositoryDatabase = objectDatabase();
final String treePath = rightTreeRef == null ? leftTreeRef.path() : rightTreeRef.path();
final List<String> strippedPathFilters = stripParentAndFiltersThatDontApply(
this.pathFilters, treePath);
// find the diffs that apply to the path filters
final ObjectId leftTreeId = leftTreeRef == null ? RevTree.EMPTY_TREE_ID : leftTreeRef
.objectId();
final ObjectId rightTreeId = rightTreeRef == null ? RevTree.EMPTY_TREE_ID : rightTreeRef
.objectId();
final Predicate<Bounded> existsFilter = new Predicate<Bounded>() {
private final ObjectDatabase targetDb = repositoryDatabase;
@Override
public boolean apply(Bounded input) {
ObjectId id = null;
if (input instanceof Node && TYPE.TREE.equals(((Node) input).getType())) {
id = ((Node) input).getObjectId();
} else if (input instanceof Bucket) {
Bucket b = (Bucket) input;
id = b.id();
}
if (id != null) {
if (targetDb.exists(id)) {
LOGGER.trace("Ignoring {}. Already exists in target database.", input);
return false;
}
}
return true;
}
};
DiffTree diffs = command(DiffTree.class).setRecursive(false).setReportTrees(false)
.setOldTree(leftTreeId).setNewTree(rightTreeId).setPathFilter(strippedPathFilters)
.setCustomFilter(existsFilter);
// move new blobs from the index to the repository (note: this could be parallelized)
Supplier<Iterator<Node>> nodesToMove = asNodeSupplierOfNewContents(diffs,
strippedPathFilters);
command(DeepMove.class).setObjects(nodesToMove).call();
final StagingDatabase stagingDatabase = stagingDatabase();
final RevTree currentLeftTree = stagingDatabase.getTree(leftTreeId);
final RevTreeBuilder builder = currentLeftTree.builder(repositoryDatabase);
// remove the exists filter, we need to create the new trees taking into account all the
// nodes
diffs.setCustomFilter(null);
Iterator<DiffEntry> iterator = diffs.get();
if (!strippedPathFilters.isEmpty()) {
final Set<String> expected = Sets.newHashSet(strippedPathFilters);
iterator = Iterators.filter(iterator, new Predicate<DiffEntry>() {
@Override
public boolean apply(DiffEntry input) {
boolean applies;
if (input.isDelete()) {
applies = expected.contains(input.oldName());
} else {
applies = expected.contains(input.newName());
}
return applies;
}
});
}
for (; iterator.hasNext();) {
final DiffEntry diff = iterator.next();
if (diff.isDelete()) {
builder.remove(diff.oldName());
} else {
NodeRef newObject = diff.getNewObject();
Node node = newObject.getNode();
builder.put(node);
}
}
final RevTree newTree = builder.build();
repositoryDatabase.put(newTree);
return newTree;
}