示例#1
0
文件: RevTag.java 项目: alexkli/jgit
 /**
  * Parse an annotated tag from its canonical format.
  *
  * <p>This method inserts the tag directly into the caller supplied revision pool, making it
  * appear as though the tag exists in the repository, even if it doesn't. The repository under the
  * pool is not affected.
  *
  * @param rw the revision pool to allocate the tag within. The tag's object pointer will be
  *     obtained from this pool.
  * @param raw the canonical formatted tag to be parsed.
  * @return the parsed tag, in an isolated revision pool that is not available to the caller.
  * @throws CorruptObjectException the tag contains a malformed header that cannot be handled.
  */
 public static RevTag parse(RevWalk rw, byte[] raw) throws CorruptObjectException {
   ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
   boolean retain = rw.isRetainBody();
   rw.setRetainBody(true);
   RevTag r = rw.lookupTag(fmt.idFor(Constants.OBJ_TAG, raw));
   r.parseCanonical(rw, raw);
   rw.setRetainBody(retain);
   return r;
 }
示例#2
0
 /**
  * Parse a commit from its canonical format.
  *
  * <p>This method inserts the commit directly into the caller supplied revision pool, making it
  * appear as though the commit exists in the repository, even if it doesn't. The repository under
  * the pool is not affected.
  *
  * @param rw the revision pool to allocate the commit within. The commit's tree and parent
  *     pointers will be obtained from this pool.
  * @param raw the canonical formatted commit to be parsed.
  * @return the parsed commit, in an isolated revision pool that is not available to the caller.
  * @throws IOException in case of RevWalk initialization fails
  */
 public static RevCommit parse(RevWalk rw, byte[] raw) throws IOException {
   ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
   boolean retain = rw.isRetainBody();
   rw.setRetainBody(true);
   RevCommit r = rw.lookupCommit(fmt.idFor(Constants.OBJ_COMMIT, raw));
   r.parseCanonical(rw, raw);
   rw.setRetainBody(retain);
   return r;
 }
示例#3
0
  void parseCanonical(final RevWalk walk, final byte[] raw) throws IOException {
    if (!walk.shallowCommitsInitialized) walk.initializeShallowCommits();

    final MutableObjectId idBuffer = walk.idBuffer;
    idBuffer.fromString(raw, 5);
    tree = walk.lookupTree(idBuffer);

    int ptr = 46;
    if (parents == null) {
      RevCommit[] pList = new RevCommit[1];
      int nParents = 0;
      for (; ; ) {
        if (raw[ptr] != 'p') break;
        idBuffer.fromString(raw, ptr + 7);
        final RevCommit p = walk.lookupCommit(idBuffer);
        if (nParents == 0) pList[nParents++] = p;
        else if (nParents == 1) {
          pList = new RevCommit[] {pList[0], p};
          nParents = 2;
        } else {
          if (pList.length <= nParents) {
            RevCommit[] old = pList;
            pList = new RevCommit[pList.length + 32];
            System.arraycopy(old, 0, pList, 0, nParents);
          }
          pList[nParents++] = p;
        }
        ptr += 48;
      }
      if (nParents != pList.length) {
        RevCommit[] old = pList;
        pList = new RevCommit[nParents];
        System.arraycopy(old, 0, pList, 0, nParents);
      }
      parents = pList;
    }

    // extract time from "committer "
    ptr = RawParseUtils.committer(raw, ptr);
    if (ptr > 0) {
      ptr = RawParseUtils.nextLF(raw, ptr, '>');

      // In 2038 commitTime will overflow unless it is changed to long.
      commitTime = RawParseUtils.parseBase10(raw, ptr, null);
    }

    if (walk.isRetainBody()) buffer = raw;
    flags |= PARSED;
  }
示例#4
0
文件: RevTag.java 项目: alexkli/jgit
  void parseCanonical(final RevWalk walk, final byte[] rawTag) throws CorruptObjectException {
    final MutableInteger pos = new MutableInteger();
    final int oType;

    pos.value = 53; // "object $sha1\ntype "
    oType = Constants.decodeTypeString(this, rawTag, (byte) '\n', pos);
    walk.idBuffer.fromString(rawTag, 7);
    object = walk.lookupAny(walk.idBuffer, oType);

    int p = pos.value += 4; // "tag "
    final int nameEnd = RawParseUtils.nextLF(rawTag, p) - 1;
    tagName = RawParseUtils.decode(Constants.CHARSET, rawTag, p, nameEnd);

    if (walk.isRetainBody()) buffer = rawTag;
    flags |= PARSED;
  }
示例#5
0
 @Override
 void parseBody(final RevWalk walk)
     throws MissingObjectException, IncorrectObjectTypeException, IOException {
   if (buffer == null) {
     buffer = walk.getCachedBytes(this);
     if ((flags & PARSED) == 0) parseCanonical(walk, buffer);
   }
 }
示例#6
0
 @Override
 protected void reset(final int retainFlags) {
   super.reset(retainFlags);
   pendingObjects = new BlockObjQueue();
   treeWalk = new CanonicalTreeParser();
   currentTree = null;
   last = null;
 }
示例#7
0
 @Override
 public void dispose() {
   super.dispose();
   pendingObjects = new BlockObjQueue();
   treeWalk = new CanonicalTreeParser();
   currentTree = null;
   last = null;
 }
示例#8
0
  /**
   * Mark an object or commit to start graph traversal from.
   *
   * <p>Callers are encouraged to use {@link RevWalk#parseAny(AnyObjectId)} instead of {@link
   * RevWalk#lookupAny(AnyObjectId, int)}, as this method requires the object to be parsed before it
   * can be added as a root for the traversal.
   *
   * <p>The method will automatically parse an unparsed object, but error handling may be more
   * difficult for the application to explain why a RevObject is not actually valid. The object pool
   * of this walker would also be 'poisoned' by the invalid RevObject.
   *
   * <p>This method will automatically call {@link RevWalk#markStart(RevCommit)} if passed RevCommit
   * instance, or a RevTag that directly (or indirectly) references a RevCommit.
   *
   * @param o the object to start traversing from. The object passed must be from this same revision
   *     walker.
   * @throws MissingObjectException the object supplied is not available from the object database.
   *     This usually indicates the supplied object is invalid, but the reference was constructed
   *     during an earlier invocation to {@link RevWalk#lookupAny(AnyObjectId, int)}.
   * @throws IncorrectObjectTypeException the object was not parsed yet and it was discovered during
   *     parsing that it is not actually the type of the instance passed in. This usually indicates
   *     the caller used the wrong type in a {@link RevWalk#lookupAny(AnyObjectId, int)} call.
   * @throws IOException a pack file or loose object could not be read.
   */
  public void markStart(RevObject o)
      throws MissingObjectException, IncorrectObjectTypeException, IOException {
    while (o instanceof RevTag) {
      addObject(o);
      o = ((RevTag) o).getObject();
      parseHeaders(o);
    }

    if (o instanceof RevCommit) super.markStart((RevCommit) o);
    else addObject(o);
  }
示例#9
0
  /**
   * Mark an object to not produce in the output.
   *
   * <p>Uninteresting objects denote not just themselves but also their entire reachable chain, back
   * until the merge base of an uninteresting commit and an otherwise interesting commit.
   *
   * <p>Callers are encouraged to use {@link RevWalk#parseAny(AnyObjectId)} instead of {@link
   * RevWalk#lookupAny(AnyObjectId, int)}, as this method requires the object to be parsed before it
   * can be added as a root for the traversal.
   *
   * <p>The method will automatically parse an unparsed object, but error handling may be more
   * difficult for the application to explain why a RevObject is not actually valid. The object pool
   * of this walker would also be 'poisoned' by the invalid RevObject.
   *
   * <p>This method will automatically call {@link RevWalk#markStart(RevCommit)} if passed RevCommit
   * instance, or a RevTag that directly (or indirectly) references a RevCommit.
   *
   * @param o the object to start traversing from. The object passed must be
   * @throws MissingObjectException the object supplied is not available from the object database.
   *     This usually indicates the supplied object is invalid, but the reference was constructed
   *     during an earlier invocation to {@link RevWalk#lookupAny(AnyObjectId, int)}.
   * @throws IncorrectObjectTypeException the object was not parsed yet and it was discovered during
   *     parsing that it is not actually the type of the instance passed in. This usually indicates
   *     the caller used the wrong type in a {@link RevWalk#lookupAny(AnyObjectId, int)} call.
   * @throws IOException a pack file or loose object could not be read.
   */
  public void markUninteresting(RevObject o)
      throws MissingObjectException, IncorrectObjectTypeException, IOException {
    while (o instanceof RevTag) {
      o.flags |= UNINTERESTING;
      if (hasRevSort(RevSort.BOUNDARY)) addObject(o);
      o = ((RevTag) o).getObject();
      parseHeaders(o);
    }

    if (o instanceof RevCommit) super.markUninteresting((RevCommit) o);
    else if (o instanceof RevTree) markTreeUninteresting((RevTree) o);
    else o.flags |= UNINTERESTING;

    if (o.getType() != Constants.OBJ_COMMIT && hasRevSort(RevSort.BOUNDARY)) {
      addObject(o);
    }
  }
示例#10
0
 @Override
 void parseHeaders(final RevWalk walk)
     throws MissingObjectException, IncorrectObjectTypeException, IOException {
   parseCanonical(walk, walk.getCachedBytes(this));
 }
示例#11
0
  @Override
  RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException {
    Generator g;

    final RevWalk w = walker;
    RevFilter rf = w.getRevFilter();
    final TreeFilter tf = w.getTreeFilter();
    AbstractRevQueue q = walker.queue;

    if (rf == RevFilter.MERGE_BASE) {
      // Computing for merge bases is a special case and does not
      // use the bulk of the generator pipeline.
      //
      if (tf != TreeFilter.ALL)
        throw new IllegalStateException(
            "Cannot combine TreeFilter " + tf + " with RevFilter " + rf + ".");

      final MergeBaseGenerator mbg = new MergeBaseGenerator(w);
      walker.pending = mbg;
      walker.queue = AbstractRevQueue.EMPTY_QUEUE;
      mbg.init(q);
      return mbg.next();
    }

    final boolean uninteresting = q.anybodyHasFlag(RevWalk.UNINTERESTING);
    boolean boundary = walker.hasRevSort(RevSort.BOUNDARY);

    if (!boundary && walker instanceof ObjectWalk) {
      // The object walker requires boundary support to color
      // trees and blobs at the boundary uninteresting so it
      // does not produce those in the result.
      //
      boundary = true;
    }
    if (boundary && !uninteresting) {
      // If we were not fed uninteresting commits we will never
      // construct a boundary. There is no reason to include the
      // extra overhead associated with that in our pipeline.
      //
      boundary = false;
    }

    final DateRevQueue pending;
    int pendingOutputType = 0;
    if (q instanceof DateRevQueue) pending = (DateRevQueue) q;
    else pending = new DateRevQueue(q);
    if (tf != TreeFilter.ALL) {
      rf = AndRevFilter.create(rf, new RewriteTreeFilter(w, tf));
      pendingOutputType |= HAS_REWRITE | NEEDS_REWRITE;
    }

    walker.queue = q;
    g = new PendingGenerator(w, pending, rf, pendingOutputType);

    if (boundary) {
      // Because the boundary generator may produce uninteresting
      // commits we cannot allow the pending generator to dispose
      // of them early.
      //
      ((PendingGenerator) g).canDispose = false;
    }

    if ((g.outputType() & NEEDS_REWRITE) != 0) {
      // Correction for an upstream NEEDS_REWRITE is to buffer
      // fully and then apply a rewrite generator that can
      // pull through the rewrite chain and produce a dense
      // output graph.
      //
      g = new FIFORevQueue(g);
      g = new RewriteGenerator(g);
    }

    if (walker.hasRevSort(RevSort.TOPO) && (g.outputType() & SORT_TOPO) == 0)
      g = new TopoSortGenerator(g);
    if (walker.hasRevSort(RevSort.REVERSE)) g = new LIFORevQueue(g);
    if (boundary) g = new BoundaryGenerator(w, g);
    else if (uninteresting) {
      // Try to protect ourselves from uninteresting commits producing
      // due to clock skew in the commit time stamps. Delay such that
      // we have a chance at coloring enough of the graph correctly,
      // and then strip any UNINTERESTING nodes that may have leaked
      // through early.
      //
      if (pending.peek() != null) g = new DelayRevQueue(g);
      g = new FixUninterestingGenerator(g);
    }

    w.pending = g;
    return g.next();
  }