Example #1
0
        /// <summary>Parse the footer lines (e.g.</summary>
        /// <remarks>
        /// 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-]+:</code>
        /// , 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</code>
        /// (agrees to Developer Certificate of Origin)
        /// <li>
        /// <code>Acked-by</code>
        /// (thinks change looks sane in context)
        /// <li>
        /// <code>Reported-by</code>
        /// (originally found the issue this change fixes)
        /// <li>
        /// <code>Tested-by</code>
        /// (validated change fixes the issue for them)
        /// <li>
        /// <code>CC</code>
        /// ,
        /// <code>Cc</code>
        /// (copy on all email related to this change)
        /// <li>
        /// <code>Bug</code>
        /// (link to project's bug tracking system)
        /// </ul>
        /// </remarks>
        /// <returns>ordered list of footer lines; empty list if no footers found.</returns>
        public IList <FooterLine> GetFooterLines()
        {
            byte[] raw = buffer;
            int    ptr = raw.Length - 1;

            while (raw[ptr] == '\n')
            {
                // trim any trailing LFs, not interesting
                ptr--;
            }
            int msgB             = RawParseUtils.CommitMessage(raw, 0);
            AList <FooterLine> r = new AList <FooterLine>(4);

            System.Text.Encoding enc = Encoding;
            for (; ;)
            {
                ptr = RawParseUtils.PrevLF(raw, ptr);
                if (ptr <= msgB)
                {
                    break;
                }
                // Don't parse commit headers as footer lines.
                int keyStart = ptr + 2;
                if (raw[keyStart] == '\n')
                {
                    break;
                }
                // Stop at first paragraph break, no footers above it.
                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.AddItem(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
            }
            Sharpen.Collections.Reverse(r);
            return(r);
        }