use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class SparseCloneTest method testSparseCloneOnlyFirstMatch.
@Test
public void testSparseCloneOnlyFirstMatch() throws Exception {
Map<String, String> filter = new HashMap<String, String>();
filter.put("default", "BBOX(pp,9, -80, 15, -70,'EPSG:4326')");
createFilterFile(filter);
// Commit several features to the remote
List<Feature> features = Arrays.asList(city1, city2, city3, road1, road2, road3);
LinkedList<RevCommit> expected = new LinkedList<RevCommit>();
Map<Feature, ObjectId> oids = new HashMap<Feature, ObjectId>();
for (Feature f : features) {
ObjectId oId = insertAndAdd(remoteGeogig.geogig, f);
oids.put(f, oId);
final RevCommit commit = remoteGeogig.geogig.command(CommitOp.class).setMessage(f.getIdentifier().toString()).call();
expected.addFirst(commit);
Optional<RevObject> childObject = remoteGeogig.geogig.command(RevObjectParse.class).setObjectId(oId).call();
assertTrue(childObject.isPresent());
}
// Make sure the remote has all of the commits
Iterator<RevCommit> logs = remoteGeogig.geogig.command(LogOp.class).call();
List<RevCommit> logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(expected, logged);
// Make sure the local repository has no commits prior to clone
logs = localGeogig.geogig.command(LogOp.class).call();
assertNotNull(logs);
assertFalse(logs.hasNext());
// clone from the remote
CloneOp clone = clone();
clone.setDepth(0);
clone.setRepositoryURL(remoteGeogig.envHome.getCanonicalPath()).setBranch("master").call();
// Because only the first feature matches (Cities.1), the first commit should be the same,
// there will also be the commit that adds the "Roads" tree but no features, and finally an
// "Empty Placeholder Commit".
// Make sure the local repository got the correct commits
logs = localGeogig.geogig.command(LogOp.class).call();
logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(3, logged.size());
assertEquals(AbstractMappedRemoteRepo.PLACEHOLDER_COMMIT_MESSAGE, logged.get(0).getMessage());
assertFalse(expected.get(0).getId().equals(logged.get(0).getId()));
assertEquals("Roads.1", logged.get(1).getMessage());
assertFalse(expected.get(2).getId().equals(logged.get(1).getId()));
assertEquals("Cities.1", logged.get(2).getMessage());
assertTrue(expected.get(5).getId().equals(logged.get(2).getId()));
assertExists(localGeogig, oids.get(city1));
assertNotExists(localGeogig, oids.get(city2), oids.get(city3), oids.get(road1), oids.get(road2), oids.get(road3));
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class SparseCloneTest method testFeatureMovingIntoAOI.
@Test
public void testFeatureMovingIntoAOI() throws Exception {
Map<String, String> filter = new HashMap<String, String>();
filter.put("Cities", "BBOX(pp,30, -125, 40, -110,'EPSG:4326')");
createFilterFile(filter);
// Commit several features to the remote
List<Feature> features = Arrays.asList(city2, city1, city3, city1_modified);
LinkedList<RevCommit> expected = new LinkedList<RevCommit>();
Map<Feature, ObjectId> oids = new HashMap<Feature, ObjectId>();
for (Feature f : features) {
ObjectId oId = insertAndAdd(remoteGeogig.geogig, f);
oids.put(f, oId);
final RevCommit commit = remoteGeogig.geogig.command(CommitOp.class).setMessage(f.getIdentifier().toString()).call();
expected.addFirst(commit);
Optional<RevObject> childObject = remoteGeogig.geogig.command(RevObjectParse.class).setObjectId(oId).call();
assertTrue(childObject.isPresent());
}
// Make sure the remote has all of the commits
Iterator<RevCommit> logs = remoteGeogig.geogig.command(LogOp.class).call();
List<RevCommit> logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(expected, logged);
// Make sure the local repository has no commits prior to clone
logs = localGeogig.geogig.command(LogOp.class).call();
assertNotNull(logs);
assertFalse(logs.hasNext());
// clone from the remote
CloneOp clone = clone();
clone.setDepth(0);
clone.setRepositoryURL(remoteGeogig.envHome.getCanonicalPath()).setBranch("master").call();
// Cities.1 initially lies outside the filter, so the commit that adds it will not be part
// of the sparse clone. Later the feature is moved into the AOI so it will be added at that
// time.
// Make sure the local repository got the correct commits
logs = localGeogig.geogig.command(LogOp.class).call();
logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(3, logged.size());
assertEquals("Cities.1", logged.get(0).getMessage());
assertFalse(expected.get(0).getId().equals(logged.get(0).getId()));
assertEquals("Cities.3", logged.get(1).getMessage());
assertFalse(expected.get(1).getId().equals(logged.get(1).getId()));
assertEquals("Cities.2", logged.get(2).getMessage());
assertTrue(expected.get(3).getId().equals(logged.get(2).getId()));
assertExists(localGeogig, oids.get(city2), oids.get(city3), oids.get(city1_modified));
assertNotExists(localGeogig, oids.get(city1));
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class SparseCloneTest method testSparseClone.
@Test
public void testSparseClone() throws Exception {
Map<String, String> filter = new HashMap<String, String>();
filter.put("default", "BBOX(pp,30, -125, 40, -110,'EPSG:4326')");
filter.put("Cities", "BBOX(pp,33, -125, 40, -110,'EPSG:4326')");
createFilterFile(filter);
// Commit several features to the remote
List<Feature> features = Arrays.asList(city1, city2, city3, road1, road2, road3);
LinkedList<RevCommit> expected = new LinkedList<RevCommit>();
Map<Feature, ObjectId> oids = new HashMap<Feature, ObjectId>();
for (Feature f : features) {
ObjectId oId = insertAndAdd(remoteGeogig.geogig, f);
oids.put(f, oId);
final RevCommit commit = remoteGeogig.geogig.command(CommitOp.class).setMessage(f.getIdentifier().toString()).call();
expected.addFirst(commit);
Optional<RevObject> childObject = remoteGeogig.geogig.command(RevObjectParse.class).setObjectId(oId).call();
assertTrue(childObject.isPresent());
}
// Make sure the remote has all of the commits
Iterator<RevCommit> logs = remoteGeogig.geogig.command(LogOp.class).call();
List<RevCommit> logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(expected, logged);
// Make sure the local repository has no commits prior to clone
logs = localGeogig.geogig.command(LogOp.class).call();
assertNotNull(logs);
assertFalse(logs.hasNext());
// clone from the remote
CloneOp clone = clone();
clone.setDepth(0);
clone.setRepositoryURL(remoteGeogig.envHome.getCanonicalPath()).setBranch("master").call();
// The features that match the filter are "Cities.3", "Roads.1", "Roads.2", and "Roads.3",
// the "Cities.1" commit should be present since it added the "Cities" tree, but "Cities.1"
// should not be present in the tree.
// Make sure the local repository got the correct commits
logs = localGeogig.geogig.command(LogOp.class).call();
logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals(5, logged.size());
assertEquals("Roads.3", logged.get(0).getMessage());
assertFalse(expected.get(0).getId().equals(logged.get(0).getId()));
assertEquals("Roads.2", logged.get(1).getMessage());
assertFalse(expected.get(1).getId().equals(logged.get(1).getId()));
assertEquals("Roads.1", logged.get(2).getMessage());
assertFalse(expected.get(2).getId().equals(logged.get(2).getId()));
assertEquals("Cities.3", logged.get(3).getMessage());
assertFalse(expected.get(3).getId().equals(logged.get(3).getId()));
assertEquals("Cities.1", logged.get(4).getMessage());
assertFalse(expected.get(5).getId().equals(logged.get(4).getId()));
assertExists(localGeogig, oids.get(city3), oids.get(road1), oids.get(road2), oids.get(road3));
assertNotExists(localGeogig, oids.get(city1), oids.get(city2));
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class JEObjectDatabase method deleteAll.
@Override
public long deleteAll(Iterator<ObjectId> ids, final BulkOpListener listener) {
checkWritable();
long count = 0;
UnmodifiableIterator<List<ObjectId>> partition = partition(ids, getBulkPartitionSize());
final DatabaseEntry data = new DatabaseEntry();
// do not retrieve data
data.setPartial(0, 0, true);
while (partition.hasNext()) {
List<ObjectId> nextIds = Lists.newArrayList(partition.next());
Collections.sort(nextIds);
final Transaction transaction = newTransaction();
CursorConfig cconfig = new CursorConfig();
final Cursor cursor = objectDb.openCursor(transaction, cconfig);
try {
DatabaseEntry key = new DatabaseEntry(new byte[ObjectId.NUM_BYTES]);
for (ObjectId id : nextIds) {
// copy id to key object without allocating new byte[]
id.getRawValue(key.getData());
OperationStatus status = cursor.getSearchKey(key, data, LockMode.DEFAULT);
if (OperationStatus.SUCCESS.equals(status)) {
OperationStatus delete = cursor.delete();
if (OperationStatus.SUCCESS.equals(delete)) {
listener.deleted(id);
count++;
} else {
listener.notFound(id);
}
} else {
listener.notFound(id);
}
}
cursor.close();
} catch (Exception e) {
cursor.close();
abort(transaction);
Throwables.propagate(e);
}
commit(transaction);
}
return count;
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class CheckoutOp method _call.
/**
* @return the id of the new work tree
*/
@Override
protected CheckoutResult _call() {
checkState(branchOrCommit != null || !paths.isEmpty(), "No branch, tree, or path were specified");
checkArgument(!(ours && theirs), "Cannot use both --ours and --theirs.");
checkArgument((ours == theirs) || branchOrCommit == null, "--ours/--theirs is incompatible with switching branches.");
CheckoutResult result = new CheckoutResult();
List<Conflict> conflicts = stagingDatabase().getConflicts(null, null);
if (!paths.isEmpty()) {
result.setResult(CheckoutResult.Results.UPDATE_OBJECTS);
Optional<RevTree> tree = Optional.absent();
List<String> unmerged = lookForUnmerged(conflicts, paths);
if (!unmerged.isEmpty()) {
if (!(force || ours || theirs)) {
StringBuilder msg = new StringBuilder();
for (String path : unmerged) {
msg.append("error: path " + path + " is unmerged.\n");
}
throw new CheckoutException(msg.toString(), StatusCode.UNMERGED_PATHS);
}
}
if (branchOrCommit != null) {
Optional<ObjectId> id = command(ResolveTreeish.class).setTreeish(branchOrCommit).call();
checkState(id.isPresent(), "'" + branchOrCommit + "' not found in repository.");
tree = command(RevObjectParse.class).setObjectId(id.get()).call(RevTree.class);
} else {
tree = Optional.of(index().getTree());
}
Optional<RevTree> mainTree = tree;
for (String st : paths) {
if (unmerged.contains(st)) {
if (ours || theirs) {
String refspec = ours ? Ref.ORIG_HEAD : Ref.MERGE_HEAD;
Optional<ObjectId> treeId = command(ResolveTreeish.class).setTreeish(refspec).call();
if (treeId.isPresent()) {
tree = command(RevObjectParse.class).setObjectId(treeId.get()).call(RevTree.class);
}
} else {
// --force
continue;
}
} else {
tree = mainTree;
}
Optional<NodeRef> node = command(FindTreeChild.class).setParent(tree.get()).setIndex(true).setChildPath(st).call();
if ((ours || theirs) && !node.isPresent()) {
// remove the node.
command(RemoveOp.class).addPathToRemove(st).call();
} else {
checkState(node.isPresent(), "pathspec '" + st + "' didn't match a feature in the tree");
if (node.get().getType() == TYPE.TREE) {
RevTreeBuilder treeBuilder = new RevTreeBuilder(stagingDatabase(), workingTree().getTree());
treeBuilder.remove(st);
treeBuilder.put(node.get().getNode());
RevTree newRoot = treeBuilder.build();
stagingDatabase().put(newRoot);
workingTree().updateWorkHead(newRoot.getId());
} else {
ObjectId metadataId = ObjectId.NULL;
Optional<NodeRef> parentNode = command(FindTreeChild.class).setParent(workingTree().getTree()).setChildPath(node.get().getParentPath()).setIndex(true).call();
RevTreeBuilder treeBuilder = null;
if (parentNode.isPresent()) {
metadataId = parentNode.get().getMetadataId();
Optional<RevTree> parsed = command(RevObjectParse.class).setObjectId(parentNode.get().getNode().getObjectId()).call(RevTree.class);
checkState(parsed.isPresent(), "Parent tree couldn't be found in the repository.");
treeBuilder = new RevTreeBuilder(stagingDatabase(), parsed.get());
treeBuilder.remove(node.get().getNode().getName());
} else {
treeBuilder = new RevTreeBuilder(stagingDatabase());
}
treeBuilder.put(node.get().getNode());
ObjectId newTreeId = command(WriteBack.class).setAncestor(workingTree().getTree().builder(stagingDatabase())).setChildPath(node.get().getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
workingTree().updateWorkHead(newTreeId);
}
}
}
} else {
if (!conflicts.isEmpty()) {
if (!(force)) {
StringBuilder msg = new StringBuilder();
for (Conflict conflict : conflicts) {
msg.append("error: " + conflict.getPath() + " needs merge.\n");
}
msg.append("You need to resolve your index first.\n");
throw new CheckoutException(msg.toString(), StatusCode.UNMERGED_PATHS);
}
}
Optional<Ref> targetRef = Optional.absent();
Optional<ObjectId> targetCommitId = Optional.absent();
Optional<ObjectId> targetTreeId = Optional.absent();
targetRef = command(RefParse.class).setName(branchOrCommit).call();
if (targetRef.isPresent()) {
ObjectId commitId = targetRef.get().getObjectId();
if (targetRef.get().getName().startsWith(Ref.REMOTES_PREFIX)) {
String remoteName = targetRef.get().getName();
remoteName = remoteName.substring(Ref.REMOTES_PREFIX.length(), targetRef.get().getName().lastIndexOf("/"));
if (branchOrCommit.contains(remoteName + '/')) {
RevCommit commit = command(RevObjectParse.class).setObjectId(commitId).call(RevCommit.class).get();
targetTreeId = Optional.of(commit.getTreeId());
targetCommitId = Optional.of(commit.getId());
targetRef = Optional.absent();
} else {
Ref branch = command(BranchCreateOp.class).setName(targetRef.get().localName()).setSource(commitId.toString()).call();
command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName("branches." + branch.localName() + ".remote").setValue(remoteName).call();
command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName("branches." + branch.localName() + ".merge").setValue(targetRef.get().getName()).call();
targetRef = Optional.of(branch);
result.setResult(CheckoutResult.Results.CHECKOUT_REMOTE_BRANCH);
result.setRemoteName(remoteName);
}
}
if (commitId.isNull()) {
targetTreeId = Optional.of(ObjectId.NULL);
targetCommitId = Optional.of(ObjectId.NULL);
} else {
Optional<RevCommit> parsed = command(RevObjectParse.class).setObjectId(commitId).call(RevCommit.class);
checkState(parsed.isPresent());
checkState(parsed.get() instanceof RevCommit);
RevCommit commit = parsed.get();
targetCommitId = Optional.of(commit.getId());
targetTreeId = Optional.of(commit.getTreeId());
}
} else {
final Optional<ObjectId> addressed = command(RevParse.class).setRefSpec(branchOrCommit).call();
checkArgument(addressed.isPresent(), "source '" + branchOrCommit + "' not found in repository");
RevCommit commit = command(RevObjectParse.class).setObjectId(addressed.get()).call(RevCommit.class).get();
targetTreeId = Optional.of(commit.getTreeId());
targetCommitId = Optional.of(commit.getId());
}
if (targetTreeId.isPresent()) {
if (!force) {
if (!index().isClean() || !workingTree().isClean()) {
throw new CheckoutException(StatusCode.LOCAL_CHANGES_NOT_COMMITTED);
}
}
// update work tree
ObjectId treeId = targetTreeId.get();
workingTree().updateWorkHead(treeId);
index().updateStageHead(treeId);
result.setNewTree(treeId);
if (targetRef.isPresent()) {
// update HEAD
Ref target = targetRef.get();
String refName;
if (target instanceof SymRef) {
// beware of cyclic refs, peel symrefs
refName = ((SymRef) target).getTarget();
} else {
refName = target.getName();
}
command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(refName).call();
result.setNewRef(targetRef.get());
result.setOid(targetCommitId.get());
result.setResult(CheckoutResult.Results.CHECKOUT_LOCAL_BRANCH);
} else {
// set HEAD to a dettached state
ObjectId commitId = targetCommitId.get();
command(UpdateRef.class).setName(Ref.HEAD).setNewValue(commitId).call();
result.setOid(commitId);
result.setResult(CheckoutResult.Results.DETACHED_HEAD);
}
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 result;
}
}
result.setNewTree(workingTree().getTree().getId());
return result;
}
Aggregations