/* Copyright (c) 2012-2014 Boundless and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Distribution License v1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/edl-v10.html * * Contributors: * Victor Olaya (Boundless) - initial implementation */ package org.locationtech.geogig.api.porcelain; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.locationtech.geogig.api.AbstractGeoGigOp; import org.locationtech.geogig.api.NodeRef; import org.locationtech.geogig.api.plumbing.FindTreeChild; import org.locationtech.geogig.api.plumbing.diff.DiffEntry; import org.locationtech.geogig.api.plumbing.merge.Conflict; import org.locationtech.geogig.di.CanRunDuringConflict; import org.locationtech.geogig.repository.WorkingTree; import com.google.common.base.Optional; import com.google.common.base.Preconditions; /** * Removes a feature or a tree from the working tree and index * */ @CanRunDuringConflict public class RemoveOp extends AbstractGeoGigOp<WorkingTree> { private List<String> pathsToRemove; public RemoveOp() { this.pathsToRemove = new ArrayList<String>(); } /** * @param path a path to remove * @return {@code this} */ public RemoveOp addPathToRemove(final String path) { pathsToRemove.add(path); return this; } /** * @see java.util.concurrent.Callable#call() */ protected WorkingTree _call() { // Check that all paths are valid and exist for (String pathToRemove : pathsToRemove) { NodeRef.checkValidPath(pathToRemove); Optional<NodeRef> node; node = command(FindTreeChild.class).setParent(workingTree().getTree()).setIndex(true) .setChildPath(pathToRemove).call(); List<Conflict> conflicts = index().getConflicted(pathToRemove); if (conflicts.size() > 0) { for (Conflict conflict : conflicts) { stagingDatabase().removeConflict(null, conflict.getPath()); } } else { Preconditions.checkArgument(node.isPresent(), "pathspec '%s' did not match any feature or tree", pathToRemove); } } // separate trees from features an delete accordingly for (String pathToRemove : pathsToRemove) { Optional<NodeRef> node = command(FindTreeChild.class) .setParent(workingTree().getTree()).setIndex(true).setChildPath(pathToRemove) .call(); if (!node.isPresent()) { continue; } switch (node.get().getType()) { case TREE: workingTree().delete(pathToRemove); break; case FEATURE: String parentPath = NodeRef.parentPath(pathToRemove); String name = node.get().name(); workingTree().delete(parentPath, name); break; default: break; } final long numChanges = workingTree().countUnstaged(pathToRemove).count(); Iterator<DiffEntry> unstaged = workingTree().getUnstaged(pathToRemove); index().stage(getProgressListener(), unstaged, numChanges); } return workingTree(); } }