use of org.locationtech.geogig.api.porcelain.MergeOp in project GeoGig by boundlessgeo.
the class MergeOpTest method testOctopusMergeWithAutomerge.
@Test
public void testOctopusMergeWithAutomerge() throws Exception {
insertAndAdd(points1);
geogig.command(CommitOp.class).call();
geogig.command(BranchCreateOp.class).setName("branch1").call();
geogig.command(BranchCreateOp.class).setName("branch2").call();
geogig.command(BranchCreateOp.class).setName("branch3").call();
geogig.command(BranchCreateOp.class).setName("branch4").call();
geogig.command(BranchCreateOp.class).setName("branch5").call();
geogig.command(BranchCreateOp.class).setName("branch6").call();
Feature points1Modified = feature(pointsType, idP1, "StringProp1_2", new Integer(1000), "POINT(1 1)");
insertAndAdd(points1Modified);
geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch1").call();
insertAndAdd(points2);
RevCommit branch1 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch2").call();
insertAndAdd(points3);
RevCommit branch2 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch3").call();
insertAndAdd(lines1);
RevCommit branch3 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch4").call();
insertAndAdd(lines2);
RevCommit branch4 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch5").call();
insertAndAdd(lines3);
RevCommit branch5 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("branch6").call();
Feature points1ModifiedB = feature(pointsType, idP1, "StringProp1_3", new Integer(2000), "POINT(1 1)");
insertAndAdd(points1ModifiedB);
RevCommit branch6 = geogig.command(CommitOp.class).call();
geogig.command(CheckoutOp.class).setSource("master").call();
MergeOp mergeOp = geogig.command(MergeOp.class).addCommit(Suppliers.ofInstance(branch1.getId())).addCommit(Suppliers.ofInstance(branch2.getId())).addCommit(Suppliers.ofInstance(branch3.getId())).addCommit(Suppliers.ofInstance(branch4.getId())).addCommit(Suppliers.ofInstance(branch5.getId())).addCommit(Suppliers.ofInstance(branch6.getId()));
try {
mergeOp.call();
fail();
} catch (IllegalStateException e) {
assertTrue(e.getMessage().contains("Cannot merge more than two commits when conflicts exist"));
}
}
use of org.locationtech.geogig.api.porcelain.MergeOp in project GeoGig by boundlessgeo.
the class SparseCloneTest method testPushSparseMerge.
@Test
public void testPushSparseMerge() throws Exception {
setupSparseClone();
// create a branch off an early commit
Iterator<RevCommit> logs = localGeogig.geogig.command(LogOp.class).call();
RevCommit initialCommit = logs.next();
ObjectId masterCommit = initialCommit.getId();
while (logs.hasNext()) {
initialCommit = logs.next();
}
localGeogig.geogig.command(BranchCreateOp.class).setName("Branch1").setAutoCheckout(true).setSource(initialCommit.getId().toString()).call();
// Add some commits to the local (sparse) repository
List<Feature> features = Arrays.asList(city1, city1_modified, road3);
LinkedList<RevCommit> expected = new LinkedList<RevCommit>();
Map<Feature, ObjectId> oids = new HashMap<Feature, ObjectId>();
for (Feature f : features) {
ObjectId oId = insertAndAdd(localGeogig.geogig, f);
oids.put(f, oId);
final RevCommit commit = localGeogig.geogig.command(CommitOp.class).setMessage(f.getIdentifier().toString()).call();
expected.addFirst(commit);
Optional<RevObject> childObject = localGeogig.geogig.command(RevObjectParse.class).setObjectId(oId).call();
assertTrue(childObject.isPresent());
}
// Merge master into Branch1
MergeOp merge = localGeogig.geogig.command(MergeOp.class);
MergeReport report = merge.addCommit(Suppliers.ofInstance(masterCommit)).setMessage("Merge").call();
// Update master to the new merge commit
localGeogig.geogig.command(UpdateRef.class).setName("refs/heads/master").setNewValue(report.getMergeCommit().getId()).call();
// Checkout master
localGeogig.geogig.command(CheckoutOp.class).setSource("master").call();
PushOp push = push();
push.addRefSpec("refs/heads/master").call();
logs = remoteGeogig.geogig.command(LogOp.class).call();
List<RevCommit> logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals("Merge", logged.get(0).getMessage());
assertFalse(report.getMergeCommit().getId().equals(logged.get(0).getId()));
// Although we merged "Roads.2" commit into the "Roads.3" commit, making the "Roads.2"
// commit the second parent, they should have been swapped when pushing to the full
// repository to prevent any sparse data from being lost.
ObjectId parent1Id = logged.get(0).getParentIds().get(0);
ObjectId parent2Id = logged.get(0).getParentIds().get(1);
RevCommit parent1 = remoteGeogig.geogig.getRepository().getCommit(parent1Id);
assertNotNull(parent1);
assertEquals("Roads.2", parent1.getMessage());
RevCommit parent2 = remoteGeogig.geogig.getRepository().getCommit(parent2Id);
assertNotNull(parent2);
assertEquals("Roads.3", parent2.getMessage());
// Verify they weren't swapped in the original
parent1Id = report.getMergeCommit().getParentIds().get(0);
parent2Id = report.getMergeCommit().getParentIds().get(1);
parent1 = localGeogig.geogig.getRepository().getCommit(parent1Id);
assertNotNull(parent1);
assertEquals("Roads.3", parent1.getMessage());
parent2 = localGeogig.geogig.getRepository().getCommit(parent2Id);
assertNotNull(parent2);
assertEquals("Roads.2", parent2.getMessage());
assertExists(remoteGeogig, oids.get(city1), oids.get(city1_modified), oids.get(road3));
}
use of org.locationtech.geogig.api.porcelain.MergeOp in project GeoGig by boundlessgeo.
the class RevertFeatureWebOp method run.
/**
* Runs the command and builds the appropriate response
*
* @param context - the context to use for this command
*
* @throws CommandSpecException
*/
@Override
public void run(CommandContext context) {
if (this.getTransactionId() == null) {
throw new CommandSpecException("No transaction was specified, revert feature requires a transaction to preserve the stability of the repository.");
}
final Context geogig = this.getCommandLocator(context);
Optional<RevTree> newTree = Optional.absent();
Optional<RevTree> oldTree = Optional.absent();
// get tree from new commit
Optional<ObjectId> treeId = geogig.command(ResolveTreeish.class).setTreeish(newCommitId).call();
Preconditions.checkState(treeId.isPresent(), "New commit id did not resolve to a valid tree.");
newTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the new commit tree.");
// get tree from old commit
treeId = geogig.command(ResolveTreeish.class).setTreeish(oldCommitId).call();
Preconditions.checkState(treeId.isPresent(), "Old commit id did not resolve to a valid tree.");
oldTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the old commit tree.");
// get feature from old tree
Optional<NodeRef> node = geogig.command(FindTreeChild.class).setParent(oldTree.get()).setIndex(true).setChildPath(featurePath).call();
boolean delete = false;
if (!node.isPresent()) {
delete = true;
node = geogig.command(FindTreeChild.class).setParent(newTree.get()).setIndex(true).setChildPath(featurePath).call();
Preconditions.checkState(node.isPresent(), "The feature was not found in either commit tree.");
}
// get the new parent tree
ObjectId metadataId = ObjectId.NULL;
Optional<NodeRef> parentNode = geogig.command(FindTreeChild.class).setParent(newTree.get()).setChildPath(node.get().getParentPath()).setIndex(true).call();
RevTreeBuilder treeBuilder = null;
if (parentNode.isPresent()) {
metadataId = parentNode.get().getMetadataId();
Optional<RevTree> parsed = geogig.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(geogig.stagingDatabase(), parsed.get());
treeBuilder.remove(node.get().getNode().getName());
} else {
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase());
}
// put the old feature into the new tree
if (!delete) {
treeBuilder.put(node.get().getNode());
}
ObjectId newTreeId = geogig.command(WriteBack.class).setAncestor(newTree.get().builder(geogig.stagingDatabase())).setChildPath(node.get().getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
// build new commit with parent of new commit and the newly built tree
CommitBuilder builder = new CommitBuilder();
builder.setParentIds(Lists.newArrayList(newCommitId));
builder.setTreeId(newTreeId);
builder.setAuthor(authorName.orNull());
builder.setAuthorEmail(authorEmail.orNull());
builder.setMessage(commitMessage.or("Reverted changes made to " + featurePath + " at " + newCommitId.toString()));
RevCommit mapped = builder.build();
context.getGeoGIG().getRepository().objectDatabase().put(mapped);
// merge commit into current branch
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
if (!currHead.isPresent()) {
throw new CommandSpecException("Repository has no HEAD, can't merge.");
}
MergeOp merge = geogig.command(MergeOp.class);
merge.setAuthor(authorName.orNull(), authorEmail.orNull());
merge.addCommit(Suppliers.ofInstance(mapped.getId()));
merge.setMessage(mergeMessage.or("Merged revert of " + featurePath));
try {
final MergeReport report = merge.call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeMergeResponse(Optional.fromNullable(report.getMergeCommit()), report.getReport().get(), geogig, report.getOurs(), report.getPairs().get(0).getTheirs(), report.getPairs().get(0).getAncestor());
out.finish();
}
});
} catch (Exception e) {
final RevCommit ours = context.getGeoGIG().getRepository().getCommit(currHead.get().getObjectId());
final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(mapped.getId());
final Optional<ObjectId> ancestor = geogig.command(FindCommonAncestor.class).setLeft(ours).setRight(theirs).call();
context.setResponseContent(new CommandResponse() {
final MergeScenarioReport report = geogig.command(ReportMergeScenarioOp.class).setMergeIntoCommit(ours).setToMergeCommit(theirs).call();
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
Optional<RevCommit> mergeCommit = Optional.absent();
out.writeMergeResponse(mergeCommit, report, geogig, ours.getId(), theirs.getId(), ancestor.get());
out.finish();
}
});
}
}
use of org.locationtech.geogig.api.porcelain.MergeOp in project GeoGig by boundlessgeo.
the class Merge method runInternal.
/**
* Executes the merge command using the provided options.
*/
@Override
public void runInternal(GeogigCLI cli) throws IOException {
checkParameter(commits.size() > 0 || abort, "No commits provided to merge.");
ConsoleReader console = cli.getConsole();
final GeoGIG geogig = cli.getGeogig();
Ansi ansi = newAnsi(console.getTerminal());
if (abort) {
Optional<Ref> ref = geogig.command(RefParse.class).setName(Ref.ORIG_HEAD).call();
if (!ref.isPresent()) {
throw new CommandFailedException("There is no merge to abort <ORIG_HEAD missing>.");
}
geogig.command(ResetOp.class).setMode(ResetMode.HARD).setCommit(Suppliers.ofInstance(ref.get().getObjectId())).call();
console.println("Merge aborted successfully.");
return;
}
RevCommit commit;
try {
MergeOp merge = geogig.command(MergeOp.class);
merge.setOurs(ours).setTheirs(theirs).setNoCommit(noCommit);
merge.setMessage(message).setProgressListener(cli.getProgressListener());
for (String commitish : commits) {
Optional<ObjectId> commitId;
commitId = geogig.command(RevParse.class).setRefSpec(commitish).call();
checkParameter(commitId.isPresent(), "Commit not found '%s'", commitish);
merge.addCommit(Suppliers.ofInstance(commitId.get()));
}
MergeReport report = merge.call();
commit = report.getMergeCommit();
} catch (RuntimeException e) {
if (e instanceof NothingToCommitException || e instanceof IllegalArgumentException || e instanceof IllegalStateException) {
throw new CommandFailedException(e.getMessage(), e);
}
throw e;
}
final ObjectId parentId = commit.parentN(0).or(ObjectId.NULL);
console.println("[" + commit.getId() + "] " + commit.getMessage());
console.print("Committed, counting objects...");
Iterator<DiffEntry> diff = geogig.command(DiffOp.class).setOldVersion(parentId).setNewVersion(commit.getId()).call();
int adds = 0, deletes = 0, changes = 0;
DiffEntry diffEntry;
while (diff.hasNext()) {
diffEntry = diff.next();
switch(diffEntry.changeType()) {
case ADDED:
++adds;
break;
case REMOVED:
++deletes;
break;
case MODIFIED:
++changes;
break;
}
}
ansi.fg(Color.GREEN).a(adds).reset().a(" features added, ").fg(Color.YELLOW).a(changes).reset().a(" changed, ").fg(Color.RED).a(deletes).reset().a(" deleted.").reset().newline();
console.print(ansi.toString());
}
use of org.locationtech.geogig.api.porcelain.MergeOp in project GeoGig by boundlessgeo.
the class SparseCloneTest method testPushSparseMergeScenario2.
@Test
public void testPushSparseMergeScenario2() throws Exception {
setupSparseClone();
// create a branch off an early commit
Iterator<RevCommit> logs = localGeogig.geogig.command(LogOp.class).call();
RevCommit initialCommit = logs.next();
while (logs.hasNext()) {
initialCommit = logs.next();
}
localGeogig.geogig.command(BranchCreateOp.class).setName("Branch1").setAutoCheckout(true).setSource(initialCommit.getId().toString()).call();
// Add some commits to the local (sparse) repository
List<Feature> features = Arrays.asList(city1, city1_modified, road3);
LinkedList<RevCommit> expected = new LinkedList<RevCommit>();
Map<Feature, ObjectId> oids = new HashMap<Feature, ObjectId>();
for (Feature f : features) {
ObjectId oId = insertAndAdd(localGeogig.geogig, f);
oids.put(f, oId);
final RevCommit commit = localGeogig.geogig.command(CommitOp.class).setMessage(f.getIdentifier().toString()).call();
expected.addFirst(commit);
Optional<RevObject> childObject = localGeogig.geogig.command(RevObjectParse.class).setObjectId(oId).call();
assertTrue(childObject.isPresent());
}
// Checkout master
localGeogig.geogig.command(CheckoutOp.class).setSource("master").call();
// Merge Branch1 into master
MergeOp merge = localGeogig.geogig.command(MergeOp.class);
MergeReport report = merge.addCommit(Suppliers.ofInstance(expected.get(0).getId())).setMessage("Merge").call();
PushOp push = push();
push.addRefSpec("refs/heads/master").call();
logs = remoteGeogig.geogig.command(LogOp.class).call();
List<RevCommit> logged = new ArrayList<RevCommit>();
for (; logs.hasNext(); ) {
logged.add(logs.next());
}
assertEquals("Merge", logged.get(0).getMessage());
assertFalse(report.getMergeCommit().getId().equals(logged.get(0).getId()));
// Because we merged Branch1 into the "sparse" master, we don't need to swap the parents, so
// the history should look the same.
ObjectId parent1Id = logged.get(0).getParentIds().get(0);
ObjectId parent2Id = logged.get(0).getParentIds().get(1);
RevCommit parent1 = remoteGeogig.geogig.getRepository().getCommit(parent1Id);
assertNotNull(parent1);
assertEquals("Roads.2", parent1.getMessage());
RevCommit parent2 = remoteGeogig.geogig.getRepository().getCommit(parent2Id);
assertNotNull(parent2);
assertEquals("Roads.3", parent2.getMessage());
// Verify they weren't swapped in the original
parent1Id = report.getMergeCommit().getParentIds().get(0);
parent2Id = report.getMergeCommit().getParentIds().get(1);
parent1 = localGeogig.geogig.getRepository().getCommit(parent1Id);
assertNotNull(parent1);
assertEquals("Roads.2", parent1.getMessage());
parent2 = localGeogig.geogig.getRepository().getCommit(parent2Id);
assertNotNull(parent2);
assertEquals("Roads.3", parent2.getMessage());
assertExists(remoteGeogig, oids.get(city1), oids.get(city1_modified), oids.get(road3));
}
Aggregations