Beispiel #1
0
  /**
   * Parse the footer lines (e.g. "Signed-off-by") for machine processing.
   *
   * <p>This method splits all of the footer lines out of the last paragraph of the commit message,
   * providing each line as a key-value pair, ordered by the order of the line's appearance in the
   * commit message itself.
   *
   * <p>A footer line's key must match the pattern {@code ^[A-Za-z0-9-]+:}, while the value is
   * free-form, but must not contain an LF. Very common keys seen in the wild are:
   *
   * <ul>
   *   <li>{@code Signed-off-by} (agrees to Developer Certificate of Origin)
   *   <li>{@code Acked-by} (thinks change looks sane in context)
   *   <li>{@code Reported-by} (originally found the issue this change fixes)
   *   <li>{@code Tested-by} (validated change fixes the issue for them)
   *   <li>{@code CC}, {@code Cc} (copy on all email related to this change)
   *   <li>{@code Bug} (link to project's bug tracking system)
   * </ul>
   *
   * @return ordered list of footer lines; empty list if no footers found.
   */
  public final List<FooterLine> getFooterLines() {
    final byte[] raw = buffer;
    int ptr = raw.length - 1;
    while (raw[ptr] == '\n') // trim any trailing LFs, not interesting
    ptr--;

    final int msgB = RawParseUtils.commitMessage(raw, 0);
    final ArrayList<FooterLine> r = new ArrayList<FooterLine>(4);
    final Charset enc = getEncoding();
    for (; ; ) {
      ptr = RawParseUtils.prevLF(raw, ptr);
      if (ptr <= msgB) break; // Don't parse commit headers as footer lines.

      final int keyStart = ptr + 2;
      if (raw[keyStart] == '\n') break; // Stop at first paragraph break, no footers above it.

      final int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart);
      if (keyEnd < 0) continue; // Not a well formed footer line, skip it.

      // Skip over the ': *' at the end of the key before the value.
      //
      int valStart = keyEnd + 1;
      while (valStart < raw.length && raw[valStart] == ' ') valStart++;

      // Value ends at the LF, and does not include it.
      //
      int valEnd = RawParseUtils.nextLF(raw, valStart);
      if (raw[valEnd - 1] == '\n') valEnd--;

      r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
    }
    Collections.reverse(r);
    return r;
  }
Beispiel #2
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;
  }
Beispiel #3
0
  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;
  }