Search in sources :

Example 31 with RevCommit

use of org.locationtech.geogig.api.RevCommit in project GeoGig by boundlessgeo.

the class HttpRemoteRepo method fetchMoreData.

/**
     * Retrieve objects from the remote repository, and update have/want lists accordingly.
     * Specifically, any retrieved commits are removed from the want list and added to the have
     * list, and any parents of those commits are removed from the have list (it only represents the
     * most recent common commits.) Retrieved objects are added to the local repository, and the
     * want/have lists are updated in-place.
     * 
     * @param want a list of ObjectIds that need to be fetched
     * @param have a list of ObjectIds that are in common with the remote repository
     * @param progress
     */
private void fetchMoreData(final List<ObjectId> want, final Set<ObjectId> have, final ProgressListener progress) {
    final JsonObject message = createFetchMessage(want, have);
    final URL resourceURL;
    try {
        resourceURL = new URL(repositoryURL.toString() + "/repo/batchobjects");
    } catch (MalformedURLException e) {
        throw Throwables.propagate(e);
    }
    final HttpURLConnection connection;
    try {
        final Gson gson = new Gson();
        OutputStream out;
        final Writer writer;
        connection = (HttpURLConnection) resourceURL.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.addRequestProperty("Accept-Encoding", "gzip");
        out = connection.getOutputStream();
        writer = new OutputStreamWriter(out);
        gson.toJson(message, writer);
        writer.flush();
        out.flush();
    } catch (IOException e) {
        throw Throwables.propagate(e);
    }
    final HttpUtils.ReportingInputStream in = HttpUtils.getResponseStream(connection);
    BinaryPackedObjects unpacker = new BinaryPackedObjects(localRepository.objectDatabase());
    BinaryPackedObjects.Callback callback = new BinaryPackedObjects.Callback() {

        @Override
        public void callback(Supplier<RevObject> supplier) {
            RevObject object = supplier.get();
            progress.setProgress(progress.getProgress() + 1);
            if (object instanceof RevCommit) {
                RevCommit commit = (RevCommit) object;
                want.remove(commit.getId());
                have.removeAll(commit.getParentIds());
                have.add(commit.getId());
            } else if (object instanceof RevTag) {
                RevTag tag = (RevTag) object;
                want.remove(tag.getId());
                have.remove(tag.getCommitId());
                have.add(tag.getId());
            }
        }
    };
    Stopwatch sw = Stopwatch.createStarted();
    IngestResults ingestResults = unpacker.ingest(in, callback);
    sw.stop();
    String msg = String.format("Processed %,d objects. Inserted: %,d. Existing: %,d. Time: %s. Compressed size: %,d bytes. Uncompressed size: %,d bytes.", ingestResults.total(), ingestResults.getInserted(), ingestResults.getExisting(), sw, in.compressedSize(), in.unCompressedSize());
    LOGGER.info(msg);
    progress.setDescription(msg);
}
Also used : MalformedURLException(java.net.MalformedURLException) RevTag(org.locationtech.geogig.api.RevTag) RevObject(org.locationtech.geogig.api.RevObject) ReportingOutputStream(org.locationtech.geogig.remote.HttpUtils.ReportingOutputStream) OutputStream(java.io.OutputStream) FilterOutputStream(java.io.FilterOutputStream) Stopwatch(com.google.common.base.Stopwatch) JsonObject(com.google.gson.JsonObject) Gson(com.google.gson.Gson) IOException(java.io.IOException) IngestResults(org.locationtech.geogig.remote.BinaryPackedObjects.IngestResults) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) OutputStreamWriter(java.io.OutputStreamWriter) Supplier(com.google.common.base.Supplier) OutputStreamWriter(java.io.OutputStreamWriter) Writer(java.io.Writer) RevCommit(org.locationtech.geogig.api.RevCommit)

Example 32 with RevCommit

use of org.locationtech.geogig.api.RevCommit in project GeoGig by boundlessgeo.

the class ResetOp method _call.

/**
     * 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;
}
Also used : UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) Ref(org.locationtech.geogig.api.Ref) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) SymRef(org.locationtech.geogig.api.SymRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) SymRef(org.locationtech.geogig.api.SymRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) Repository(org.locationtech.geogig.repository.Repository) DiffTree(org.locationtech.geogig.api.plumbing.DiffTree) RevCommit(org.locationtech.geogig.api.RevCommit) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry)

Example 33 with RevCommit

use of org.locationtech.geogig.api.RevCommit in project GeoGig by boundlessgeo.

the class RevertOp method applyNextCommit.

private boolean applyNextCommit(boolean useCommitChanges) {
    File rebaseFolder = getRevertFolder();
    File nextFile = new File(rebaseFolder, "next");
    Repository repository = repository();
    try {
        String idx = Files.readFirstLine(nextFile, Charsets.UTF_8);
        File commitFile = new File(rebaseFolder, idx);
        if (commitFile.exists()) {
            String commitId = Files.readFirstLine(commitFile, Charsets.UTF_8);
            RevCommit commit = repository.getCommit(ObjectId.valueOf(commitId));
            List<Conflict> conflicts = Lists.newArrayList();
            if (useCommitChanges) {
                conflicts = applyRevertedChanges(commit);
            }
            if (createCommit && conflicts.isEmpty()) {
                createCommit(commit);
            } else {
                workingTree().updateWorkHead(repository.index().getTree().getId());
                if (!conflicts.isEmpty()) {
                    // mark conflicted elements
                    command(ConflictsWriteOp.class).setConflicts(conflicts).call();
                    // created exception message
                    StringBuilder msg = new StringBuilder();
                    msg.append("error: could not apply ");
                    msg.append(commit.getId().toString().substring(0, 7));
                    msg.append(" " + commit.getMessage() + "\n");
                    for (Conflict conflict : conflicts) {
                        msg.append("CONFLICT: conflict in " + conflict.getPath() + "\n");
                    }
                    throw new RevertConflictsException(msg.toString());
                }
            }
            commitFile.delete();
            int newIdx = Integer.parseInt(idx) + 1;
            Files.write(Integer.toString(newIdx), nextFile, Charsets.UTF_8);
            return true;
        } else {
            return false;
        }
    } catch (IOException e) {
        throw new IllegalStateException("Cannot read/write revert commits index file");
    }
}
Also used : Repository(org.locationtech.geogig.repository.Repository) Conflict(org.locationtech.geogig.api.plumbing.merge.Conflict) CanRunDuringConflict(org.locationtech.geogig.di.CanRunDuringConflict) IOException(java.io.IOException) File(java.io.File) RevCommit(org.locationtech.geogig.api.RevCommit)

Example 34 with RevCommit

use of org.locationtech.geogig.api.RevCommit in project GeoGig by boundlessgeo.

the class HttpRemoteRepo method sendPackedObjects.

private void sendPackedObjects(final List<ObjectId> toSend, final Set<ObjectId> roots, Deduplicator deduplicator, final ProgressListener progress) {
    Set<ObjectId> sent = new HashSet<ObjectId>();
    while (!toSend.isEmpty()) {
        try {
            BinaryPackedObjects.Callback callback = new BinaryPackedObjects.Callback() {

                @Override
                public void callback(Supplier<RevObject> supplier) {
                    RevObject object = supplier.get();
                    progress.setProgress(progress.getProgress() + 1);
                    if (object instanceof RevCommit) {
                        RevCommit commit = (RevCommit) object;
                        toSend.remove(commit.getId());
                        roots.removeAll(commit.getParentIds());
                        roots.add(commit.getId());
                    }
                }
            };
            ObjectDatabase database = localRepository.objectDatabase();
            BinaryPackedObjects packer = new BinaryPackedObjects(database);
            ImmutableList<ObjectId> have = ImmutableList.copyOf(roots);
            final boolean traverseCommits = false;
            Stopwatch sw = Stopwatch.createStarted();
            ObjectSerializingFactory serializer = DataStreamSerializationFactoryV1.INSTANCE;
            SendObjectsConnectionFactory outFactory;
            ObjectFunnel objectFunnel;
            outFactory = new SendObjectsConnectionFactory(repositoryURL);
            int pushBytesLimit = parsePushLimit();
            objectFunnel = ObjectFunnels.newFunnel(outFactory, serializer, pushBytesLimit);
            final long writtenObjectsCount = packer.write(objectFunnel, toSend, have, sent, callback, traverseCommits, deduplicator);
            objectFunnel.close();
            sw.stop();
            long compressedSize = outFactory.compressedSize;
            long uncompressedSize = outFactory.uncompressedSize;
            LOGGER.info(String.format("HttpRemoteRepo: Written %,d objects." + " Time to process: %s." + " Compressed size: %,d bytes. Uncompressed size: %,d bytes.", writtenObjectsCount, sw, compressedSize, uncompressedSize));
        } catch (IOException e) {
            Throwables.propagate(e);
        }
    }
}
Also used : ObjectSerializingFactory(org.locationtech.geogig.storage.ObjectSerializingFactory) ObjectId(org.locationtech.geogig.api.ObjectId) RevObject(org.locationtech.geogig.api.RevObject) Stopwatch(com.google.common.base.Stopwatch) IOException(java.io.IOException) ObjectDatabase(org.locationtech.geogig.storage.ObjectDatabase) Supplier(com.google.common.base.Supplier) HashSet(java.util.HashSet) RevCommit(org.locationtech.geogig.api.RevCommit)

Example 35 with RevCommit

use of org.locationtech.geogig.api.RevCommit in project GeoGig by boundlessgeo.

the class BinaryPackedObjects method scanForPrevisitList.

/**
     * Find commits which should be previsited to avoid resending objects that are already on the
     * receiving end. A commit should be previsited if:
     * <ul>
     * <li>It is not going to be visited, and
     * <li>It is the immediate ancestor of a commit which is going to be previsited.
     * </ul>
     * 
     */
private ImmutableList<ObjectId> scanForPrevisitList(List<ObjectId> want, List<ObjectId> have, Deduplicator deduplicator) {
    /*
         * @note Implementation note: To find the previsit list, we just iterate over all the
         * commits that will be visited according to our want and have lists. Any parents of commits
         * in this traversal which are part of the 'have' list will be in the previsit list.
         */
    Iterator<RevCommit> willBeVisited = //
    Iterators.filter(//
    PostOrderIterator.rangeOfCommits(want, have, database, deduplicator), RevCommit.class);
    ImmutableSet.Builder<ObjectId> builder = ImmutableSet.builder();
    while (willBeVisited.hasNext()) {
        RevCommit next = willBeVisited.next();
        List<ObjectId> parents = new ArrayList<ObjectId>(next.getParentIds());
        parents.retainAll(have);
        builder.addAll(parents);
    }
    return ImmutableList.copyOf(builder.build());
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) ObjectId(org.locationtech.geogig.api.ObjectId) ArrayList(java.util.ArrayList) RevCommit(org.locationtech.geogig.api.RevCommit)

Aggregations

RevCommit (org.locationtech.geogig.api.RevCommit)291 Test (org.junit.Test)212 ObjectId (org.locationtech.geogig.api.ObjectId)109 CommitOp (org.locationtech.geogig.api.porcelain.CommitOp)107 LogOp (org.locationtech.geogig.api.porcelain.LogOp)86 Ref (org.locationtech.geogig.api.Ref)71 Feature (org.opengis.feature.Feature)52 NodeRef (org.locationtech.geogig.api.NodeRef)47 ArrayList (java.util.ArrayList)44 BranchCreateOp (org.locationtech.geogig.api.porcelain.BranchCreateOp)44 RevTree (org.locationtech.geogig.api.RevTree)36 SymRef (org.locationtech.geogig.api.SymRef)33 RefParse (org.locationtech.geogig.api.plumbing.RefParse)33 DiffEntry (org.locationtech.geogig.api.plumbing.diff.DiffEntry)31 RevObject (org.locationtech.geogig.api.RevObject)30 UpdateRef (org.locationtech.geogig.api.plumbing.UpdateRef)30 MergeScenarioReport (org.locationtech.geogig.api.plumbing.merge.MergeScenarioReport)30 UpdateSymRef (org.locationtech.geogig.api.plumbing.UpdateSymRef)26 LinkedList (java.util.LinkedList)24 AddOp (org.locationtech.geogig.api.porcelain.AddOp)21