use of org.locationtech.geogig.api.porcelain.TransferSummary.ChangedRef in project GeoGig by boundlessgeo.
the class ResponseWriter method writeFetchResponse.
public void writeFetchResponse(TransferSummary result) throws XMLStreamException {
out.writeStartElement("Fetch");
if (result.getChangedRefs().entrySet().size() > 0) {
for (Entry<String, Collection<ChangedRef>> entry : result.getChangedRefs().entrySet()) {
out.writeStartElement("Remote");
writeElement("remoteName", entry.getKey());
for (ChangedRef ref : entry.getValue()) {
out.writeStartElement("Branch");
writeElement("changeType", ref.getType().toString());
if (ref.getOldRef() != null) {
writeElement("name", ref.getOldRef().localName());
writeElement("oldValue", ref.getOldRef().getObjectId().toString());
}
if (ref.getNewRef() != null) {
if (ref.getOldRef() == null) {
writeElement("name", ref.getNewRef().localName());
}
writeElement("newValue", ref.getNewRef().getObjectId().toString());
}
out.writeEndElement();
}
out.writeEndElement();
}
}
out.writeEndElement();
}
use of org.locationtech.geogig.api.porcelain.TransferSummary.ChangedRef in project GeoGig by boundlessgeo.
the class SendPack method callInternal.
private TransferSummary callInternal(IRemoteRepo remoteRepo) {
final Remote remote = this.remote;
@Nullable String localRefSpec;
@Nullable String remoteRefSpec;
boolean force;
TransferSummary result = new TransferSummary();
for (TransferableRef ref : this.refsToPush) {
localRefSpec = ref.getLocalRef();
remoteRefSpec = ref.getRemoteRef();
force = ref.isForceUpdate();
if (ref.isDelete()) {
Optional<Ref> deleted = remoteRepo.deleteRef(remoteRefSpec);
if (deleted.isPresent()) {
ChangedRef deleteResult = new ChangedRef(deleted.get(), null, REMOVED_REF);
result.add(remote.getPushURL(), deleteResult);
}
} else {
Optional<Ref> localRef = refParse(localRefSpec);
checkState(localRef.isPresent(), "RefSpec %s does not exist", localRefSpec);
Optional<Ref> newRef = push(remoteRepo, remote, localRef.get(), remoteRefSpec);
if (newRef.isPresent()) {
ChangeTypes changeType = remoteRefSpec == null ? ADDED_REF : CHANGED_REF;
ChangedRef deleteResult = new ChangedRef(localRef.get(), newRef.get(), changeType);
result.add(remote.getPushURL(), deleteResult);
}
}
}
return result;
}
use of org.locationtech.geogig.api.porcelain.TransferSummary.ChangedRef in project GeoGig by boundlessgeo.
the class FetchOp method _call.
/**
* Executes the fetch operation.
*
* @return {@code null}
* @see org.locationtech.geogig.api.AbstractGeoGigOp#call()
*/
@Override
protected TransferSummary _call() {
if (all) {
// Add all remotes to list.
ImmutableList<Remote> localRemotes = command(RemoteListOp.class).call();
for (Remote remote : localRemotes) {
if (!remotes.contains(remote)) {
remotes.add(remote);
}
}
} else if (remotes.size() == 0) {
// If no remotes are specified, default to the origin remote
addRemote("origin");
}
final ProgressListener progressListener = getProgressListener();
progressListener.started();
Optional<Integer> repoDepth = repository().getDepth();
if (repoDepth.isPresent()) {
if (fullDepth) {
depth = Optional.of(Integer.MAX_VALUE);
}
if (depth.isPresent()) {
if (depth.get() > repoDepth.get()) {
command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName(Repository.DEPTH_CONFIG_KEY).setValue(depth.get().toString()).call();
repoDepth = depth;
}
}
} else if (depth.isPresent() || fullDepth) {
// Ignore depth, this is a full repository
depth = Optional.absent();
fullDepth = false;
}
TransferSummary result = new TransferSummary();
for (Remote remote : remotes) {
final ImmutableSet<Ref> remoteRemoteRefs = command(LsRemote.class).setRemote(Suppliers.ofInstance(Optional.of(remote))).retrieveTags(!remote.getMapped() && (!repoDepth.isPresent() || fullDepth)).call();
final ImmutableSet<Ref> localRemoteRefs = command(LsRemote.class).retrieveLocalRefs(true).setRemote(Suppliers.ofInstance(Optional.of(remote))).call();
// If we have specified a depth to pull, we may have more history to pull from existing
// refs.
List<ChangedRef> needUpdate = findOutdatedRefs(remote, remoteRemoteRefs, localRemoteRefs, depth);
if (prune) {
// Delete local refs that aren't in the remote
List<Ref> locals = new ArrayList<Ref>();
// provided a tag so it makes sense not to prune them anyway.
for (Ref remoteRef : remoteRemoteRefs) {
Optional<Ref> localRef = findLocal(remoteRef, localRemoteRefs);
if (localRef.isPresent()) {
locals.add(localRef.get());
}
}
for (Ref localRef : localRemoteRefs) {
if (!locals.contains(localRef)) {
// Delete the ref
ChangedRef changedRef = new ChangedRef(localRef, null, ChangeTypes.REMOVED_REF);
needUpdate.add(changedRef);
command(UpdateRef.class).setDelete(true).setName(localRef.getName()).call();
}
}
}
Optional<IRemoteRepo> remoteRepo = getRemoteRepo(remote, repository().deduplicationService());
Preconditions.checkState(remoteRepo.isPresent(), "Failed to connect to the remote.");
IRemoteRepo remoteRepoInstance = remoteRepo.get();
try {
remoteRepoInstance.open();
} catch (IOException e) {
Throwables.propagate(e);
}
try {
int refCount = 0;
for (ChangedRef ref : needUpdate) {
if (ref.getType() != ChangeTypes.REMOVED_REF) {
refCount++;
Optional<Integer> newFetchLimit = depth;
// fetch limit to the current repository depth.
if (!newFetchLimit.isPresent() && repoDepth.isPresent() && ref.getType() == ChangeTypes.ADDED_REF) {
newFetchLimit = repoDepth;
}
// Fetch updated data from this ref
Ref newRef = ref.getNewRef();
remoteRepoInstance.fetchNewData(newRef, newFetchLimit, progressListener);
if (repoDepth.isPresent() && !fullDepth) {
// Update the repository depth if it is deeper than before.
int newDepth;
try {
newDepth = repository().graphDatabase().getDepth(newRef.getObjectId());
} catch (IllegalStateException e) {
throw new RuntimeException(ref.toString(), e);
}
if (newDepth > repoDepth.get()) {
command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName(Repository.DEPTH_CONFIG_KEY).setValue(Integer.toString(newDepth)).call();
repoDepth = Optional.of(newDepth);
}
}
// Update the ref
Ref updatedRef = updateLocalRef(newRef, remote, localRemoteRefs);
ref.setNewRef(updatedRef);
}
}
if (needUpdate.size() > 0) {
result.addAll(remote.getFetchURL(), needUpdate);
}
// Update HEAD ref
if (!remote.getMapped()) {
Ref remoteHead = remoteRepoInstance.headRef();
if (remoteHead != null) {
updateLocalRef(remoteHead, remote, localRemoteRefs);
}
}
} finally {
try {
remoteRepoInstance.close();
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
if (fullDepth) {
// The full history was fetched, this is no longer a shallow clone
command(ConfigOp.class).setAction(ConfigAction.CONFIG_UNSET).setScope(ConfigScope.LOCAL).setName(Repository.DEPTH_CONFIG_KEY).call();
}
progressListener.complete();
return result;
}
use of org.locationtech.geogig.api.porcelain.TransferSummary.ChangedRef in project GeoGig by boundlessgeo.
the class FetchOp method findOutdatedRefs.
/**
* Filters the remote references for the given remote that are not present or outdated in the
* local repository
*/
private List<ChangedRef> findOutdatedRefs(Remote remote, ImmutableSet<Ref> remoteRefs, ImmutableSet<Ref> localRemoteRefs, Optional<Integer> depth) {
List<ChangedRef> changedRefs = Lists.newLinkedList();
for (Ref remoteRef : remoteRefs) {
// tags yet
if (remote.getMapped() && !remoteRef.localName().equals(Ref.localName(remote.getMappedBranch()))) {
// for a mapped remote, we are only interested in the branch we are mapped to
continue;
}
Optional<Ref> local = findLocal(remoteRef, localRemoteRefs);
if (local.isPresent()) {
if (!local.get().getObjectId().equals(remoteRef.getObjectId())) {
ChangedRef changedRef = new ChangedRef(local.get(), remoteRef, ChangeTypes.CHANGED_REF);
changedRefs.add(changedRef);
} else if (depth.isPresent()) {
int commitDepth = graphDatabase().getDepth(local.get().getObjectId());
if (depth.get() > commitDepth) {
ChangedRef changedRef = new ChangedRef(local.get(), remoteRef, ChangeTypes.DEEPENED_REF);
changedRefs.add(changedRef);
}
}
} else {
ChangedRef changedRef = new ChangedRef(null, remoteRef, ChangeTypes.ADDED_REF);
changedRefs.add(changedRef);
}
}
return changedRefs;
}
use of org.locationtech.geogig.api.porcelain.TransferSummary.ChangedRef in project GeoGig by boundlessgeo.
the class FetchResultPrinter method print.
public static void print(TransferSummary result, ConsoleReader console) throws IOException {
for (Entry<String, Collection<ChangedRef>> entry : result.getChangedRefs().entrySet()) {
console.println("From " + entry.getKey());
for (ChangedRef ref : entry.getValue()) {
String line;
if (ref.getType() == ChangeTypes.CHANGED_REF) {
line = " " + ref.getOldRef().getObjectId().toString().substring(0, 7) + ".." + ref.getNewRef().getObjectId().toString().substring(0, 7) + " " + ref.getOldRef().localName() + " -> " + ref.getOldRef().getName();
} else if (ref.getType() == ChangeTypes.ADDED_REF) {
String reftype = (ref.getNewRef().getName().startsWith(Ref.TAGS_PREFIX)) ? "tag" : "branch";
line = " * [new " + reftype + "] " + ref.getNewRef().localName() + " -> " + ref.getNewRef().getName();
} else if (ref.getType() == ChangeTypes.REMOVED_REF) {
line = " x [deleted] (none) -> " + ref.getOldRef().getName();
} else {
line = " [deepened] " + ref.getNewRef().localName();
}
console.println(line);
}
}
}
Aggregations