Package org.locationtech.geogig.api.porcelain

Source Code of org.locationtech.geogig.api.porcelain.ResetOp

/* 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:
* Johnathan Garrett (LMN Solutions) - initial implementation
*/
package org.locationtech.geogig.api.porcelain;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.locationtech.geogig.api.AbstractGeoGigOp;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.Ref;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.api.SymRef;
import org.locationtech.geogig.api.plumbing.DiffTree;
import org.locationtech.geogig.api.plumbing.RefParse;
import org.locationtech.geogig.api.plumbing.UpdateRef;
import org.locationtech.geogig.api.plumbing.UpdateSymRef;
import org.locationtech.geogig.api.plumbing.diff.DiffEntry;
import org.locationtech.geogig.di.CanRunDuringConflict;
import org.locationtech.geogig.repository.Repository;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Iterators;

/**
*
* Reset current HEAD to the specified state.
*
*/
@CanRunDuringConflict
public class ResetOp extends AbstractGeoGigOp<Boolean> {

    /**
     * Enumeration of the possible reset modes.
     */
    public enum ResetMode {
        SOFT, MIXED, HARD, MERGE, KEEP, NONE
    };

    private Supplier<ObjectId> commit;

    private ResetMode mode = ResetMode.NONE;

    private Set<String> patterns = new HashSet<String>();

    /**
     * Sets the reset mode.
     *
     * @param mode the reset mode
     * @return {@code this}
     */
    public ResetOp setMode(ResetMode mode) {
        this.mode = mode;
        return this;
    }

    /**
     * Sets the base commit.
     *
     * @param commit a supplier for the {@link ObjectId id} of the commit
     * @return {@code this}
     */
    public ResetOp setCommit(final Supplier<ObjectId> commit) {
        this.commit = commit;
        return this;
    }

    /**
     * Adds a pattern.
     *
     * @param pattern a regular expression to match what content to be reset
     * @return {@code this}
     */
    public ResetOp addPattern(final String pattern) {
        patterns.add(pattern);
        return this;
    }

    /**
     * Executes the reset operation.
     *
     * @return always {@code true}
     */
    @Override
    protected Boolean _call() {
        Preconditions.checkState(!(patterns.size() > 0 && mode != ResetMode.NONE),
                "Ambiguous call, cannot specify paths and reset mode.");

        final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
        Preconditions.checkState(currHead.isPresent(), "Repository has no HEAD, can't reset.");
        Preconditions
                .checkState(currHead.get() instanceof SymRef, "Can't reset from detached HEAD");
        final SymRef headRef = (SymRef) currHead.get();

        final String currentBranch = headRef.getTarget();

        if (commit == null) {
            commit = Suppliers.ofInstance(currHead.get().getObjectId());
        }

        Preconditions.checkState(!ObjectId.NULL.equals(commit.get()),
                "Commit could not be resolved.");

        Repository repository = repository();
        RevCommit oldCommit = repository.getCommit(commit.get());

        if (patterns.size() > 0) {
            for (String pattern : patterns) {
                DiffTree diffOp = command(DiffTree.class)
                        .setOldTree(repository.index().getTree().getId())
                        .setNewTree(oldCommit.getTreeId()).setPathFilter(pattern);

                Iterator<DiffEntry> diff = diffOp.call();

                final long numChanges = Iterators.size(diffOp.call());
                if (numChanges == 0) {
                    // We are reseting to the current version, so there is nothing to do. However,
                    // if we are in a conflict state, the conflict should be removed and calling
                    // stage() will not do it, so we do it here
                    repository.stagingDatabase().removeConflict(null, pattern);
                } else {
                    repository.index().stage(subProgress((1.f / patterns.size()) * 100.f), diff,
                            numChanges);
                }
            }
        } else {
            if (mode == ResetMode.NONE) {
                mode = ResetMode.MIXED;
            }
            switch (mode) {
            case HARD:
                // Update the index and the working tree to the target tree
                index().updateStageHead(oldCommit.getTreeId());
                workingTree().updateWorkHead(oldCommit.getTreeId());
                break;
            case SOFT:
                // Do not update index or working tree to the target tree
                break;
            case MIXED:
                // Only update the index to the target tree
                index().updateStageHead(oldCommit.getTreeId());
                break;
            default:
                throw new UnsupportedOperationException("Unsupported reset mode.");
            }

            // Update branch head to the specified commit
            command(UpdateRef.class).setName(currentBranch).setNewValue(oldCommit.getId()).call();
            command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(currentBranch).call();

            Optional<Ref> ref = command(RefParse.class).setName(Ref.MERGE_HEAD).call();
            if (ref.isPresent()) {
                command(UpdateRef.class).setName(Ref.MERGE_HEAD).setDelete(true).call();
            }
        }
        return true;
    }
}
TOP

Related Classes of org.locationtech.geogig.api.porcelain.ResetOp

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.