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);
}
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;
}
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");
}
}
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);
}
}
}
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());
}
Aggregations