/// <summary> /// Parse the footer lines (e.g. "Signed-off-by") for machine processing. /// <para /> /// 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. /// <para /> /// 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> /// <li>{@code Acked-by} (thinks change looks sane in context)</li> /// <li>{@code Reported-by} (originally found the issue this change fixes)</li> /// <li>{@code Tested-by} (validated change fixes the issue for them)</li> /// <li>{@code CC}, {@code Cc} (copy on all email related to this change)</li> /// <li>{@code Bug} (link to project's bug tracking system)</li> /// </ul> /// </summary> /// <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); var r = new List <FooterLine>(4); Encoding enc = Encoding; while (true) { 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.Add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd)); } r.Reverse(); return(r); }
private static string TextFor(RevCommit cmit) { byte[] raw = cmit.RawBuffer; int b = RawParseUtils.commitMessage(raw, 0); if (b < 0) { return(string.Empty); } return(Constants.CHARSET.GetString(raw, b, raw.Length)); }
/// <summary> /// Parse the complete commit message and decode it to a string. /// <para /> /// This method parses and returns the message portion of the commit buffer, /// After taking the commit's character set into account and decoding the /// buffer using that character set. This method is a fairly expensive /// operation and produces a new string on each invocation. /// </summary> /// <returns> /// Decoded commit message as a string. Never null. /// </returns> public string getFullMessage() { byte[] raw = _buffer; int msgB = RawParseUtils.commitMessage(raw, 0); if (msgB < 0) { return(string.Empty); } Encoding enc = RawParseUtils.parseEncoding(raw); return(RawParseUtils.decode(enc, raw, msgB, raw.Length)); }
/// <summary> /// Parse the commit message and return the first "line" of it. /// <para /> /// The first line is everything up to the first pair of LFs. This is the /// "oneline" format, suitable for output in a single line display. /// <para /> /// This method parses and returns the message portion of the commit buffer, /// after taking the commit's character set into account and decoding the /// buffer using that character set. This method is a fairly expensive /// operation and produces a new string on each invocation. /// </summary> /// <returns> /// Decoded commit message as a string. Never null. The returned /// string does not contain any LFs, even if the first paragraph /// spanned multiple lines. Embedded LFs are converted to spaces. /// </returns> public string getShortMessage() { byte[] raw = _buffer; int msgB = RawParseUtils.commitMessage(raw, 0); if (msgB < 0) { return(string.Empty); } Encoding enc = RawParseUtils.parseEncoding(raw); int msgE = RawParseUtils.endOfParagraph(raw, msgB); string str = RawParseUtils.decode(enc, raw, msgB, msgE); if (hasLF(raw, msgB, msgE)) { str = str.Replace('\n', ' '); } return(str); }