use of org.locationtech.geogig.api.plumbing.diff.DiffEntry in project GeoGig by boundlessgeo.
the class WriteTree method _call.
/**
* Executes the write tree operation.
*
* @return the new root tree id, the current HEAD tree id if there are no differences between
* the index and the HEAD, or {@code null} if the operation has been cancelled (as
* indicated by the {@link #getProgressListener() progress listener}.
*/
@Override
protected ObjectId _call() {
final ProgressListener progress = getProgressListener();
final RevTree oldRootTree = resolveRootTree();
final ObjectDatabase repositoryDatabase = objectDatabase();
Iterator<DiffEntry> diffs = null;
long numChanges = 0;
if (diffSupplier == null) {
diffs = index().getStaged(pathFilters);
numChanges = index().countStaged(pathFilters).count();
} else {
diffs = diffSupplier.get();
}
if (!diffs.hasNext()) {
return oldRootTree.getId();
}
if (progress.isCanceled()) {
return null;
}
Map<String, RevTreeBuilder> repositoryChangedTrees = Maps.newHashMap();
Map<String, NodeRef> indexChangedTrees = Maps.newHashMap();
Map<String, ObjectId> changedTreesMetadataId = Maps.newHashMap();
Set<String> deletedTrees = Sets.newHashSet();
final boolean moveObjects = this.moveObjects;
NodeRef ref;
int i = 0;
RevTree stageHead = index().getTree();
while (diffs.hasNext()) {
if (numChanges != 0) {
progress.setProgress((float) (++i * 100) / numChanges);
}
if (progress.isCanceled()) {
return null;
}
DiffEntry diff = diffs.next();
// ignore the root entry
if (NodeRef.ROOT.equals(diff.newName()) || NodeRef.ROOT.equals(diff.oldName())) {
continue;
}
ref = diff.getNewObject();
if (ref == null) {
ref = diff.getOldObject();
}
final String parentPath = ref.getParentPath();
final boolean isDelete = ChangeType.REMOVED.equals(diff.changeType());
final TYPE type = ref.getType();
if (isDelete && deletedTrees.contains(parentPath)) {
// tree delete entry was processed
continue;
}
RevTreeBuilder parentTree = resolveTargetTree(oldRootTree, parentPath, repositoryChangedTrees, changedTreesMetadataId, ObjectId.NULL, repositoryDatabase);
if (type == TYPE.TREE && !isDelete) {
// cache the tree
resolveTargetTree(oldRootTree, ref.name(), repositoryChangedTrees, changedTreesMetadataId, ref.getMetadataId(), repositoryDatabase);
}
resolveSourceTreeRef(parentPath, indexChangedTrees, changedTreesMetadataId, stageHead);
Preconditions.checkState(parentTree != null);
if (isDelete) {
String oldName = diff.getOldObject().getNode().getName();
parentTree.remove(oldName);
if (TYPE.TREE.equals(type)) {
deletedTrees.add(ref.path());
}
} else {
if (moveObjects && ref.getType().equals(TYPE.TREE)) {
RevTree tree = stagingDatabase().getTree(ref.objectId());
if (!ref.getMetadataId().isNull()) {
repositoryDatabase.put(stagingDatabase().getFeatureType(ref.getMetadataId()));
}
if (tree.isEmpty()) {
repositoryDatabase.put(tree);
} else {
continue;
}
} else if (moveObjects) {
deepMove(ref.getNode());
}
parentTree.put(ref.getNode());
}
}
if (progress.isCanceled()) {
return null;
}
// now write back all changed trees
ObjectId newTargetRootId = oldRootTree.getId();
RevTreeBuilder directRootEntries = repositoryChangedTrees.remove(NodeRef.ROOT);
if (directRootEntries != null) {
RevTree newRoot = directRootEntries.build();
repositoryDatabase.put(newRoot);
newTargetRootId = newRoot.getId();
}
for (Map.Entry<String, RevTreeBuilder> e : repositoryChangedTrees.entrySet()) {
String treePath = e.getKey();
ObjectId metadataId = changedTreesMetadataId.get(treePath);
RevTreeBuilder treeBuilder = e.getValue();
RevTree newRoot = getTree(newTargetRootId);
RevTree tree = treeBuilder.build();
newTargetRootId = writeBack(newRoot.builder(repositoryDatabase), tree, treePath, metadataId);
}
progress.complete();
return newTargetRootId;
}
use of org.locationtech.geogig.api.plumbing.diff.DiffEntry in project GeoGig by boundlessgeo.
the class AddOpTest method testAddNewPathUsingPathFilter.
@Test
public void testAddNewPathUsingPathFilter() throws Exception {
insert(points1);
insert(points2);
geogig.command(AddOp.class).addPattern("Points/Points.1").call();
List<DiffEntry> unstaged = toList(repo.index().getStaged(null));
assertEquals(unstaged.toString(), 2, unstaged.size());
assertEquals(ChangeType.ADDED, unstaged.get(0).changeType());
assertEquals(RevObject.TYPE.TREE, unstaged.get(0).getNewObject().getType());
assertEquals("Points", unstaged.get(0).newName());
RevFeatureType ft = RevFeatureTypeImpl.build(pointsType);
ObjectId expectedTreeMdId = ft.getId();
assertEquals(expectedTreeMdId, unstaged.get(0).getNewObject().getMetadataId());
assertEquals(ChangeType.ADDED, unstaged.get(1).changeType());
assertEquals(RevObject.TYPE.FEATURE, unstaged.get(1).getNewObject().getType());
assertEquals("Points.1", unstaged.get(1).newName());
assertFalse("feature node's metadata id should not be set, as it uses the parent tree one", unstaged.get(1).getNewObject().getNode().getMetadataId().isPresent());
}
use of org.locationtech.geogig.api.plumbing.diff.DiffEntry 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.plumbing.diff.DiffEntry in project GeoGig by boundlessgeo.
the class Clean method runInternal.
@Override
public void runInternal(GeogigCLI cli) throws IOException {
final ConsoleReader console = cli.getConsole();
final GeoGIG geogig = cli.getGeogig();
String pathFilter = null;
if (!path.isEmpty()) {
pathFilter = path.get(0);
}
if (dryRun) {
if (pathFilter != null) {
// check that is a valid path
Repository repository = cli.getGeogig().getRepository();
NodeRef.checkValidPath(pathFilter);
Optional<NodeRef> ref = repository.command(FindTreeChild.class).setIndex(true).setParent(repository.workingTree().getTree()).setChildPath(pathFilter).call();
checkParameter(ref.isPresent(), "pathspec '%s' did not match any tree", pathFilter);
checkParameter(ref.get().getType() == TYPE.TREE, "pathspec '%s' did not resolve to a tree", pathFilter);
}
Iterator<DiffEntry> unstaged = geogig.command(DiffWorkTree.class).setFilter(pathFilter).call();
while (unstaged.hasNext()) {
DiffEntry entry = unstaged.next();
if (entry.changeType() == ChangeType.ADDED) {
console.println("Would remove " + entry.newPath());
}
}
} else {
geogig.command(CleanOp.class).setPath(pathFilter).call();
console.println("Clean operation completed succesfully.");
}
}
use of org.locationtech.geogig.api.plumbing.diff.DiffEntry in project GeoGig by boundlessgeo.
the class Commit method runInternal.
/**
* Executes the commit command using the provided options.
*
* @param cli
* @see org.locationtech.geogig.cli.AbstractCommand#runInternal(org.locationtech.geogig.cli.GeogigCLI)
*/
@Override
public void runInternal(GeogigCLI cli) throws IOException {
final GeoGIG geogig = cli.getGeogig();
if (message == null || Strings.isNullOrEmpty(message)) {
message = geogig.command(ReadMergeCommitMessageOp.class).call();
}
checkParameter(!Strings.isNullOrEmpty(message) || commitToReuse != null || amend, "No commit message provided");
ConsoleReader console = cli.getConsole();
Ansi ansi = newAnsi(console.getTerminal());
RevCommit commit;
try {
CommitOp commitOp = geogig.command(CommitOp.class).setMessage(message).setAmend(amend);
if (commitTimestamp != null && !Strings.isNullOrEmpty(commitTimestamp)) {
Long millis = geogig.command(ParseTimestamp.class).setString(commitTimestamp).call();
commitOp.setCommitterTimestamp(millis.longValue());
}
if (commitToReuse != null) {
Optional<ObjectId> commitId = geogig.command(RevParse.class).setRefSpec(commitToReuse).call();
checkParameter(commitId.isPresent(), "Provided reference does not exist");
TYPE type = geogig.command(ResolveObjectType.class).setObjectId(commitId.get()).call();
checkParameter(TYPE.COMMIT.equals(type), "Provided reference does not resolve to a commit");
commitOp.setCommit(geogig.getRepository().getCommit(commitId.get()));
}
commit = commitOp.setPathFilters(pathFilters).setProgressListener(cli.getProgressListener()).call();
} catch (NothingToCommitException noChanges) {
throw new CommandFailedException(noChanges.getMessage(), noChanges);
}
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());
}
Aggregations