Пример #1
0
  /**
   * This function takes all of the changes introduced by a commit on the sparse repository and
   * creates a new commit on the full repository with those changes.
   *
   * @param commitId the commit id of commit from the sparse repository
   * @param from the sparse repository
   * @param to the full repository
   */
  protected void pushSparseCommit(ObjectId commitId) {
    Repository from = localRepository;
    Repository to = remoteGeoGit.getRepository();
    Optional<RevObject> object = from.command(RevObjectParse.class).setObjectId(commitId).call();
    if (object.isPresent() && object.get().getType().equals(TYPE.COMMIT)) {
      RevCommit commit = (RevCommit) object.get();
      ObjectId parent = ObjectId.NULL;
      List<ObjectId> newParents = new LinkedList<ObjectId>();
      for (int i = 0; i < commit.getParentIds().size(); i++) {
        ObjectId parentId = commit.getParentIds().get(i);
        if (i != 0) {
          Optional<ObjectId> commonAncestor =
              from.getGraphDatabase()
                  .findLowestCommonAncestor(commit.getParentIds().get(0), parentId);
          if (commonAncestor.isPresent()) {
            if (from.getGraphDatabase().isSparsePath(parentId, commonAncestor.get())) {
              // This should be the base commit to preserve the sparse changes that
              // were filtered
              // out.
              newParents.add(0, from.getGraphDatabase().getMapping(parentId));
              continue;
            }
          }
        }
        newParents.add(from.getGraphDatabase().getMapping(parentId));
      }
      if (newParents.size() > 0) {
        parent = from.getGraphDatabase().getMapping(newParents.get(0));
      }
      Iterator<DiffEntry> diffIter =
          from.command(DiffOp.class)
              .setNewVersion(commitId)
              .setOldVersion(parent)
              .setReportTrees(true)
              .call();

      LocalCopyingDiffIterator changes = new LocalCopyingDiffIterator(diffIter, from, to);

      RevTree rootTree = RevTree.EMPTY;

      if (newParents.size() > 0) {
        ObjectId mappedCommit = newParents.get(0);

        Optional<ObjectId> treeId =
            to.command(ResolveTreeish.class).setTreeish(mappedCommit).call();
        if (treeId.isPresent()) {
          rootTree = to.getTree(treeId.get());
        }
      }

      // Create new commit
      ObjectId newTreeId =
          to.command(WriteTree.class)
              .setOldRoot(Suppliers.ofInstance(rootTree))
              .setDiffSupplier(Suppliers.ofInstance((Iterator<DiffEntry>) changes))
              .call();

      CommitBuilder builder = new CommitBuilder(commit);
      builder.setParentIds(newParents);
      builder.setTreeId(newTreeId);

      RevCommit mapped = builder.build();
      to.getObjectDatabase().put(mapped);

      from.getGraphDatabase().map(commit.getId(), mapped.getId());
      from.getGraphDatabase().map(mapped.getId(), commit.getId());
    }
  }