/** * Push all new objects from the specified {@link Ref} to the remote. * * @param ref the local ref that points to new commit data * @param refspec the remote branch to push to */ @Override public void pushNewData(Ref ref, String refspec, ProgressListener progress) throws SynchronizationException { Optional<Ref> remoteRef = HttpUtils.getRemoteRef(repositoryURL, refspec); checkPush(ref, remoteRef); beginPush(); progress.setDescription("Uploading objects to " + refspec); progress.setProgress(0); CommitTraverser traverser = getPushTraverser(remoteRef); traverser.traverse(ref.getObjectId()); List<ObjectId> toSend = new LinkedList<ObjectId>(traverser.commits); Collections.reverse(toSend); Set<ObjectId> have = new HashSet<ObjectId>(traverser.have); Deduplicator deduplicator = deduplicationService.createDeduplicator(); try { sendPackedObjects(toSend, have, deduplicator, progress); } finally { deduplicator.release(); } ObjectId originalRemoteRefValue = ObjectId.NULL; if (remoteRef.isPresent()) { originalRemoteRefValue = remoteRef.get().getObjectId(); } String nameToSet = remoteRef.isPresent() ? remoteRef.get().getName() : Ref.HEADS_PREFIX + refspec; endPush(nameToSet, ref.getObjectId(), originalRemoteRefValue.toString()); }
/** * Stages the object addressed by {@code pathFilter}, or all unstaged objects if {@code pathFilter * == null} to be added, if it is/they are marked as an unstaged change. Does nothing otherwise. * * <p>To stage changes not yet staged, a diff tree walk is performed using the current staged * {@link RevTree} as the old object and the current unstaged {@link RevTree} as the new object. * Then all the differences are traversed and the staged tree is updated with the changes reported * by the diff walk (neat). * * @param progress the progress listener for this process * @param pathFilter the filter to use */ public void stage(final ProgressListener progress, final @Nullable String pathFilter) { // short cut for the case where the index is empty and we're staging all changes in the // working tree, so it's just a matter of updating the index ref to working tree RevTree id if (null == pathFilter && !index().getStaged(null).hasNext() && !updateOnly && index().countConflicted(null) == 0) { progress.started(); Optional<ObjectId> workHead = command(RevParse.class).setRefSpec(Ref.WORK_HEAD).call(); if (workHead.isPresent()) { command(UpdateRef.class).setName(Ref.STAGE_HEAD).setNewValue(workHead.get()).call(); } progress.setProgress(100f); progress.complete(); return; } final long numChanges = workingTree().countUnstaged(pathFilter).count(); Iterator<DiffEntry> unstaged = workingTree().getUnstaged(pathFilter); if (updateOnly) { unstaged = Iterators.filter( unstaged, new Predicate<DiffEntry>() { @Override public boolean apply(@Nullable DiffEntry input) { // HACK: avoid reporting changed trees if (input.isChange() && input.getOldObject().getType().equals(TYPE.TREE)) { return false; } return input.getOldObject() != null; } }); } index().stage(progress, unstaged, numChanges); List<Conflict> conflicts = index().getConflicted(pathFilter); ConflictsDatabase conflictsDatabase = conflictsDatabase(); for (Conflict conflict : conflicts) { // if we are staging unmerged files, the conflict should get solved. However, if the // working index object is the same as the staging area one (for instance, after running // checkout --ours), it will not be reported by the getUnstaged method. We solve that // here. conflictsDatabase.removeConflict(null, conflict.getPath()); } }
/** * Fetch all new objects from the specified {@link Ref} from the remote. * * @param ref the remote ref that points to new commit data * @param fetchLimit the maximum depth to fetch */ @Override public void fetchNewData(Ref ref, Optional<Integer> fetchLimit, ProgressListener progress) { CommitTraverser traverser = getFetchTraverser(fetchLimit); try { progress.setDescription("Fetching objects from " + ref.getName()); traverser.traverse(ref.getObjectId()); List<ObjectId> want = new LinkedList<ObjectId>(); want.addAll(traverser.commits); Collections.reverse(want); Set<ObjectId> have = new HashSet<ObjectId>(); have.addAll(traverser.have); while (!want.isEmpty()) { progress.setProgress(0); fetchMoreData(want, have, progress); } } catch (Exception e) { Throwables.propagate(e); } }