use of org.locationtech.geogig.api.porcelain.SynchronizationException in project GeoGig by boundlessgeo.
the class Fetch method runInternal.
/**
* Executes the fetch command using the provided options.
*/
@Override
public void runInternal(GeogigCLI cli) throws IOException {
checkParameter(depth > 0 ? !fulldepth : true, "Cannot specify a depth and full depth. Use --depth <depth> or --fulldepth.");
if (depth > 0 || fulldepth) {
checkParameter(cli.getGeogig().getRepository().getDepth().isPresent(), "Depth operations can only be used on a shallow clone.");
}
TransferSummary result;
try {
FetchOp fetch = cli.getGeogig().command(FetchOp.class);
fetch.setProgressListener(cli.getProgressListener());
fetch.setAll(all).setPrune(prune).setFullDepth(fulldepth);
fetch.setDepth(depth);
if (args != null) {
for (String repo : args) {
fetch.addRemote(repo);
}
}
result = fetch.call();
} catch (SynchronizationException e) {
switch(e.statusCode) {
case HISTORY_TOO_SHALLOW:
default:
throw new CommandFailedException("Unable to fetch, the remote history is shallow.", e);
}
} catch (IllegalArgumentException iae) {
throw new CommandFailedException(iae.getMessage(), iae);
} catch (IllegalStateException ise) {
throw new CommandFailedException(ise.getMessage(), ise);
}
ConsoleReader console = cli.getConsole();
if (result.getChangedRefs().isEmpty()) {
console.println("Already up to date.");
} else {
FetchResultPrinter.print(result, console);
}
}
use of org.locationtech.geogig.api.porcelain.SynchronizationException in project GeoGig by boundlessgeo.
the class AbstractRemoteRepo method checkPush.
/**
* Determine if it is safe to push to the remote repository.
*
* @param ref the ref to push
* @param remoteRefOpt the ref to push to
* @throws SynchronizationException if its not safe or possible to push to the given remote ref
* (see {@link StatusCode} for the possible reasons)
*/
protected void checkPush(Ref ref, Optional<Ref> remoteRefOpt) throws SynchronizationException {
if (!remoteRefOpt.isPresent()) {
// safe to push
return;
}
final Ref remoteRef = remoteRefOpt.get();
if (remoteRef instanceof SymRef) {
throw new SynchronizationException(StatusCode.CANNOT_PUSH_TO_SYMBOLIC_REF);
}
final ObjectId remoteObjectId = remoteRef.getObjectId();
final ObjectId localObjectId = ref.getObjectId();
if (remoteObjectId.equals(localObjectId)) {
// The branches are equal, no need to push.
throw new SynchronizationException(StatusCode.NOTHING_TO_PUSH);
} else if (localRepository.blobExists(remoteObjectId)) {
Optional<ObjectId> ancestor = localRepository.command(FindCommonAncestor.class).setLeftId(remoteObjectId).setRightId(localObjectId).call();
if (!ancestor.isPresent()) {
// There is no common ancestor, a push will overwrite history
throw new SynchronizationException(StatusCode.REMOTE_HAS_CHANGES);
} else if (ancestor.get().equals(localObjectId)) {
// My last commit is the common ancestor, the remote already has my data.
throw new SynchronizationException(StatusCode.NOTHING_TO_PUSH);
} else if (!ancestor.get().equals(remoteObjectId)) {
// loss of history.
throw new SynchronizationException(StatusCode.REMOTE_HAS_CHANGES);
}
} else if (!remoteObjectId.isNull()) {
// The remote has data that I do not, a push will cause this data to be lost.
throw new SynchronizationException(StatusCode.REMOTE_HAS_CHANGES);
}
}
use of org.locationtech.geogig.api.porcelain.SynchronizationException in project GeoGig by boundlessgeo.
the class PullWebOp method run.
/**
* Runs the command and builds the appropriate response.
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
final Context geogig = this.getCommandLocator(context);
PullOp command = geogig.command(PullOp.class).setAuthor(authorName.orNull(), authorEmail.orNull()).setRemote(remoteName).setAll(fetchAll).addRefSpec(refSpec);
try {
final PullResult result = command.call();
final Iterator<DiffEntry> iter;
if (result.getOldRef() != null && result.getNewRef() != null && result.getOldRef().equals(result.getNewRef())) {
iter = null;
} else {
if (result.getOldRef() == null) {
iter = geogig.command(DiffOp.class).setNewVersion(result.getNewRef().getObjectId()).setOldVersion(ObjectId.NULL).call();
} else {
iter = geogig.command(DiffOp.class).setNewVersion(result.getNewRef().getObjectId()).setOldVersion(result.getOldRef().getObjectId()).call();
}
}
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writePullResponse(result, iter, geogig);
out.finish();
}
});
} catch (SynchronizationException e) {
switch(e.statusCode) {
case HISTORY_TOO_SHALLOW:
default:
context.setResponseContent(CommandResponse.error("Unable to pull, the remote history is shallow."));
}
} catch (MergeConflictsException e) {
String[] refs = refSpec.split(":");
String remoteRef = Ref.REMOTES_PREFIX + remoteName + "/" + refs[0];
Optional<Ref> sourceRef = geogig.command(RefParse.class).setName(remoteRef).call();
String destinationref = "";
if (refs.length == 2) {
destinationref = refs[1];
} else {
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
if (!currHead.isPresent()) {
context.setResponseContent(CommandResponse.error("Repository has no HEAD, can't pull."));
} else if (!(currHead.get() instanceof SymRef)) {
context.setResponseContent(CommandResponse.error("Can't pull from detached HEAD"));
}
final SymRef headRef = (SymRef) currHead.get();
destinationref = headRef.getTarget();
}
Optional<Ref> destRef = geogig.command(RefParse.class).setName(destinationref).call();
final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(sourceRef.get().getObjectId());
final RevCommit ours = context.getGeoGIG().getRepository().getCommit(destRef.get().getObjectId());
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.SynchronizationException in project GeoGig by boundlessgeo.
the class PushWebOp method run.
/**
* Runs the command and builds the appropriate response.
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
final Context geogig = this.getCommandLocator(context);
PushOp command = geogig.command(PushOp.class);
if (refSpec != null) {
command.addRefSpec(refSpec);
}
try {
final TransferSummary dataPushed = command.setAll(pushAll).setRemote(remoteName).call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeElement("Push", "Success");
out.writeElement("dataPushed", String.valueOf(!dataPushed.isEmpty()));
out.finish();
}
});
} catch (SynchronizationException e) {
switch(e.statusCode) {
case REMOTE_HAS_CHANGES:
context.setResponseContent(CommandResponse.error("Push failed: The remote repository has changes that would be lost in the event of a push."));
break;
case HISTORY_TOO_SHALLOW:
context.setResponseContent(CommandResponse.error("Push failed: There is not enough local history to complete the push."));
default:
break;
}
}
}
Aggregations