* @throws SynchronizationException
*/
protected void checkPush(Ref ref, Optional<Ref> remoteRef) throws SynchronizationException {
if (remoteRef.isPresent()) {
if (remoteRef.get() instanceof SymRef) {
throw new SynchronizationException(StatusCode.CANNOT_PUSH_TO_SYMBOLIC_REF);
}
ObjectId mappedId = localRepository.graphDatabase().getMapping(
remoteRef.get().getObjectId());
if (mappedId.equals(ref.getObjectId())) {
// The branches are equal, no need to push.
throw new SynchronizationException(StatusCode.NOTHING_TO_PUSH);
} else if (localRepository.blobExists(mappedId)) {
Optional<ObjectId> ancestor = localRepository.command(FindCommonAncestor.class)
.setLeftId(mappedId).setRightId(ref.getObjectId()).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(ref.getObjectId())) {
// 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(mappedId)) {
// The remote branch's latest commit is not my ancestor, a push will cause a
// loss of history.
throw new SynchronizationException(StatusCode.REMOTE_HAS_CHANGES);
}
} else {
// The remote has data that I do not, a push will cause this data to be lost.
throw new SynchronizationException(StatusCode.REMOTE_HAS_CHANGES);
}
}
}