use of org.locationtech.geogig.repository.Repository in project GeoGig by boundlessgeo.
the class RevertOp method applyRevertedChanges.
private List<Conflict> applyRevertedChanges(RevCommit commit) {
ObjectId parentCommitId = ObjectId.NULL;
if (commit.getParentIds().size() > 0) {
parentCommitId = commit.getParentIds().get(0);
}
ObjectId parentTreeId = ObjectId.NULL;
Repository repository = repository();
if (repository.commitExists(parentCommitId)) {
parentTreeId = repository.getCommit(parentCommitId).getTreeId();
}
// get changes (in reverse)
Iterator<DiffEntry> reverseDiff = command(DiffTree.class).setNewTree(parentTreeId).setOldTree(commit.getTreeId()).setReportTrees(false).call();
ObjectId headTreeId = repository.getCommit(revertHead).getTreeId();
final RevTree headTree = repository.getTree(headTreeId);
ArrayList<Conflict> conflicts = new ArrayList<Conflict>();
DiffEntry diff;
while (reverseDiff.hasNext()) {
diff = reverseDiff.next();
if (diff.isAdd()) {
// Feature was deleted
Optional<NodeRef> node = command(FindTreeChild.class).setChildPath(diff.newPath()).setIndex(true).setParent(headTree).call();
// make sure it is still deleted
if (node.isPresent()) {
conflicts.add(new Conflict(diff.newPath(), diff.oldObjectId(), node.get().objectId(), diff.newObjectId()));
} else {
index().stage(getProgressListener(), Iterators.singletonIterator(diff), 1);
}
} else {
// Feature was added or modified
Optional<NodeRef> node = command(FindTreeChild.class).setChildPath(diff.oldPath()).setIndex(true).setParent(headTree).call();
ObjectId nodeId = node.get().getNode().getObjectId();
// Make sure it wasn't changed
if (node.isPresent() && nodeId.equals(diff.oldObjectId())) {
index().stage(getProgressListener(), Iterators.singletonIterator(diff), 1);
} else {
// do not mark as conflict if reverting to the same feature currently in HEAD
if (!nodeId.equals(diff.newObjectId())) {
conflicts.add(new Conflict(diff.newPath(), diff.oldObjectId(), node.get().objectId(), diff.newObjectId()));
}
}
}
}
return conflicts;
}
use of org.locationtech.geogig.repository.Repository in project GeoGig by boundlessgeo.
the class RevertOp method _call.
/**
* Executes the revert operation.
*
* @return always {@code true}
*/
@Override
protected Boolean _call() {
final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
Preconditions.checkState(currHead.isPresent(), "Repository has no HEAD, can't revert.");
Preconditions.checkState(currHead.get() instanceof SymRef, "Can't revert from detached HEAD");
final SymRef headRef = (SymRef) currHead.get();
Preconditions.checkState(!headRef.getObjectId().equals(ObjectId.NULL), "HEAD has no history.");
currentBranch = headRef.getTarget();
revertHead = currHead.get().getObjectId();
Preconditions.checkArgument(!(continueRevert && abort), "Cannot continue and abort at the same time");
// count staged and unstaged changes
long staged = index().countStaged(null).count();
long unstaged = workingTree().countUnstaged(null).count();
Preconditions.checkState((staged == 0 && unstaged == 0) || abort || continueRevert, "You must have a clean working tree and index to perform a revert.");
getProgressListener().started();
// Revert can only be run in a conflicted situation if the abort option is used
List<Conflict> conflicts = command(ConflictsReadOp.class).call();
Preconditions.checkState(conflicts.isEmpty() || abort, "Cannot run operation while merge conflicts exist.");
Optional<Ref> ref = command(RefParse.class).setName(Ref.ORIG_HEAD).call();
if (abort) {
Preconditions.checkState(ref.isPresent(), "Cannot abort. You are not in the middle of a revert process.");
command(ResetOp.class).setMode(ResetMode.HARD).setCommit(Suppliers.ofInstance(ref.get().getObjectId())).call();
command(UpdateRef.class).setDelete(true).setName(Ref.ORIG_HEAD).call();
return true;
} else if (continueRevert) {
Preconditions.checkState(ref.isPresent(), "Cannot continue. You are not in the middle of a revert process.");
// Commit the manually-merged changes with the info of the commit that caused the
// conflict
applyNextCommit(false);
// Commit files should already be prepared, so we do nothing else
} else {
Preconditions.checkState(!ref.isPresent(), "You are currently in the middle of a merge or rebase operation <ORIG_HEAD is present>.");
getProgressListener().started();
command(UpdateRef.class).setName(Ref.ORIG_HEAD).setNewValue(currHead.get().getObjectId()).call();
// Here we prepare the files with the info about the commits to apply in reverse
List<RevCommit> commitsToRevert = Lists.newArrayList();
Repository repository = repository();
for (ObjectId id : commits) {
Preconditions.checkArgument(repository.commitExists(id), "Commit was not found in the repository: " + id.toString());
RevCommit commit = repository.getCommit(id);
commitsToRevert.add(commit);
}
createRevertCommitsInfoFiles(commitsToRevert);
}
boolean ret;
do {
ret = applyNextCommit(true);
} while (ret);
command(UpdateRef.class).setDelete(true).setName(Ref.ORIG_HEAD).call();
getProgressListener().complete();
return true;
}
use of org.locationtech.geogig.repository.Repository in project GeoGig by boundlessgeo.
the class CherryPickOp method _call.
/**
* Executes the cherry pick operation.
*
* @return RevCommit the new commit with the changes from the cherry-picked commit
*/
@Override
protected RevCommit _call() {
final Repository repository = repository();
final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
Preconditions.checkState(currHead.isPresent(), "Repository has no HEAD, can't cherry pick.");
Preconditions.checkState(currHead.get() instanceof SymRef, "Can't cherry pick from detached HEAD");
final SymRef headRef = (SymRef) currHead.get();
Preconditions.checkState(index().isClean() && workingTree().isClean(), "You must have a clean working tree and index to perform a cherry pick.");
getProgressListener().started();
Preconditions.checkArgument(repository.commitExists(commit), "Commit could not be resolved: %s.", commit);
RevCommit commitToApply = repository.getCommit(commit);
ObjectId headId = headRef.getObjectId();
ObjectId parentCommitId = ObjectId.NULL;
if (commitToApply.getParentIds().size() > 0) {
parentCommitId = commitToApply.getParentIds().get(0);
}
ObjectId parentTreeId = ObjectId.NULL;
if (repository.commitExists(parentCommitId)) {
parentTreeId = repository.getCommit(parentCommitId).getTreeId();
}
// get changes
Iterator<DiffEntry> diff = command(DiffTree.class).setOldTree(parentTreeId).setNewTree(commitToApply.getTreeId()).setReportTrees(true).call();
// see if there are conflicts
MergeScenarioReport report = command(ReportCommitConflictsOp.class).setCommit(commitToApply).call();
if (report.getConflicts().isEmpty()) {
// stage changes
index().stage(getProgressListener(), diff, 0);
// write new tree
ObjectId newTreeId = command(WriteTree2.class).call();
RevCommit newCommit = command(CommitOp.class).setCommit(commitToApply).call();
repository.workingTree().updateWorkHead(newTreeId);
repository.index().updateStageHead(newTreeId);
getProgressListener().complete();
return newCommit;
} else {
Iterator<DiffEntry> unconflicted = report.getUnconflicted().iterator();
// stage changes
index().stage(getProgressListener(), unconflicted, 0);
workingTree().updateWorkHead(index().getTree().getId());
command(UpdateRef.class).setName(Ref.CHERRY_PICK_HEAD).setNewValue(commit).call();
command(UpdateRef.class).setName(Ref.ORIG_HEAD).setNewValue(headId).call();
command(ConflictsWriteOp.class).setConflicts(report.getConflicts()).call();
StringBuilder msg = new StringBuilder();
msg.append("error: could not apply ");
msg.append(commitToApply.getId().toString().substring(0, 7));
msg.append(" " + commitToApply.getMessage());
for (Conflict conflict : report.getConflicts()) {
msg.append("\t" + conflict.getPath() + "\n");
}
StringBuilder sb = new StringBuilder();
for (Conflict conflict : report.getConflicts()) {
sb.append("CONFLICT: conflict in " + conflict.getPath() + "\n");
}
sb.append("Fix conflicts and then commit the result using 'geogig commit -c " + commitToApply.getId().toString().substring(0, 7) + "\n");
throw new IllegalStateException(sb.toString());
}
}
use of org.locationtech.geogig.repository.Repository in project GeoGig by boundlessgeo.
the class GlobalState method insert.
public static List<ObjectId> insert(Feature... features) throws Exception {
geogigCLI.close();
GeoGIG geogig = geogigCLI.newGeoGIG(Hints.readWrite());
Preconditions.checkNotNull(geogig);
List<ObjectId> ids = Lists.newArrayListWithCapacity(features.length);
try {
Repository repository = geogig.getRepository();
final WorkingTree workTree = repository.workingTree();
for (Feature f : features) {
Name name = f.getType().getName();
String parentPath = name.getLocalPart();
Node ref = workTree.insert(parentPath, f);
ObjectId objectId = ref.getObjectId();
ids.add(objectId);
}
} finally {
geogig.close();
}
return ids;
}
use of org.locationtech.geogig.repository.Repository in project GeoGig by boundlessgeo.
the class InitOpTest method testCreateNewRepo.
@Test
public void testCreateNewRepo() throws Exception {
when(injector.repository()).thenReturn(mockRepo);
Optional<Ref> absent = Optional.absent();
when(mockRefParse.call()).thenReturn(absent);
Repository created = init.call();
assertSame(mockRepo, created);
assertTrue(new File(workingDir, ".geogig").exists());
assertTrue(new File(workingDir, ".geogig").isDirectory());
verify(injector, times(1)).repository();
verify(platform, atLeastOnce()).pwd();
verify(mockUpdateRef, times(1)).setName(eq(Ref.MASTER));
verify(mockUpdateRef, times(1)).setName(eq(Ref.WORK_HEAD));
verify(mockUpdateRef, times(1)).setName(eq(Ref.STAGE_HEAD));
verify(mockUpdateRef, times(1)).setNewValue(eq(ObjectId.NULL));
verify(mockUpdateRef, times(2)).setNewValue(eq(RevTree.EMPTY_TREE_ID));
verify(mockUpdateRef, times(3)).setReason(anyString());
verify(mockUpdateRef, times(3)).call();
verify(mockUpdateSymRef, times(1)).setName(eq(Ref.HEAD));
verify(mockUpdateSymRef, times(1)).setNewValue(eq(Ref.MASTER));
verify(mockUpdateSymRef, times(1)).call();
assertEquals(RevTree.EMPTY, objectDatabase.get(RevTree.EMPTY_TREE_ID));
}
Aggregations