From: John Koleszar Date: Wed, 28 Mar 2012 23:41:16 +0000 (-0700) Subject: FTFY: support wordwrapping commit messages X-Git-Tag: v1.1.0~39^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a46ec1656976da2601f64c729d570145583c6791;p=libvpx FTFY: support wordwrapping commit messages It's common for commit messages to be wrapped at odd places. git-gui is often to blame. Adds support for automatically fixing up these messages if running ftfy --amend, and adds a new option --msg-only for fixing only the commit message. Change-Id: Ia7ea529f8cb7395d34d9b39f1192598e9a1e315b --- diff --git a/tools/ftfy.sh b/tools/ftfy.sh index 05315fb26..de0f0eded 100755 --- a/tools/ftfy.sh +++ b/tools/ftfy.sh @@ -1,5 +1,6 @@ #!/bin/sh self="$0" +dirname_self=$(dirname "$self") usage() { cat <&2 @@ -9,9 +10,13 @@ This script applies a whitespace transformation to the commit at HEAD. If no options are given, then the modified files are left in the working tree. Options: + -h, --help Shows this message -n, --dry-run Shows a diff of the changes to be made. --amend Squashes the changes into the commit at HEAD + This option will also reformat the commit message. --commit Creates a new commit containing only the whitespace changes + --msg-only Reformat the commit message only, ignore the patch itself. + EOF rm -f ${CLEAN_FILES} exit 1 @@ -34,7 +39,7 @@ vpx_style() { apply() { - patch -p1 < "$1" + [ $INTERSECT_RESULT -ne 0 ] && patch -p1 < "$1" } @@ -59,8 +64,28 @@ EOF } +show_commit_msg_diff() { + if [ $DIFF_MSG_RESULT -ne 0 ]; then + log "Modified commit message:" + diff -u "$ORIG_COMMIT_MSG" "$NEW_COMMIT_MSG" | tail -n +3 + fi +} + + amend() { - git commit -a --amend -C HEAD + show_commit_msg_diff + if [ $DIFF_MSG_RESULT -ne 0 ] || [ $INTERSECT_RESULT -ne 0 ]; then + git commit -a --amend -F "$NEW_COMMIT_MSG" + fi +} + + +diff_msg() { + git log -1 --format=%B > "$ORIG_COMMIT_MSG" + "${dirname_self}"/wrap-commit-msg.py \ + < "$ORIG_COMMIT_MSG" > "$NEW_COMMIT_MSG" + cmp -s "$ORIG_COMMIT_MSG" "$NEW_COMMIT_MSG" + DIFF_MSG_RESULT=$? } @@ -68,7 +93,10 @@ amend() { ORIG_DIFF=orig.diff.$$ MODIFIED_DIFF=modified.diff.$$ FINAL_DIFF=final.diff.$$ +ORIG_COMMIT_MSG=orig.commit-msg.$$ +NEW_COMMIT_MSG=new.commit-msg.$$ CLEAN_FILES="${ORIG_DIFF} ${MODIFIED_DIFF} ${FINAL_DIFF}" +CLEAN_FILES="${CLEAN_FILES} ${ORIG_COMMIT_MSG} ${NEW_COMMIT_MSG}" # Preconditions [ $# -lt 2 ] || usage @@ -95,28 +123,30 @@ done git diff --no-color --no-ext-diff > "${MODIFIED_DIFF}" # Intersect the two diffs -$(dirname ${self})/intersect-diffs.py \ +"${dirname_self}"/intersect-diffs.py \ "${ORIG_DIFF}" "${MODIFIED_DIFF}" > "${FINAL_DIFF}" INTERSECT_RESULT=$? git reset --hard >/dev/null -if [ $INTERSECT_RESULT -eq 0 ]; then - # Handle options - if [ -n "$1" ]; then - case "$1" in - -h|--help) usage;; - -n|--dry-run) cat "${FINAL_DIFF}";; - --commit) apply "${FINAL_DIFF}"; commit;; - --amend) apply "${FINAL_DIFF}"; amend;; - *) usage;; - esac - else - apply "${FINAL_DIFF}" - if ! git diff --quiet; then - log "Formatting changes applied, verify and commit." - log "See also: http://www.webmproject.org/code/contribute/conventions/" - git diff --stat - fi +# Fixup the commit message +diff_msg + +# Handle options +if [ -n "$1" ]; then + case "$1" in + -h|--help) usage;; + -n|--dry-run) cat "${FINAL_DIFF}"; show_commit_msg_diff;; + --commit) apply "${FINAL_DIFF}"; commit;; + --amend) apply "${FINAL_DIFF}"; amend;; + --msg-only) amend;; + *) usage;; + esac +else + apply "${FINAL_DIFF}" + if ! git diff --quiet; then + log "Formatting changes applied, verify and commit." + log "See also: http://www.webmproject.org/code/contribute/conventions/" + git diff --stat fi fi diff --git a/tools/intersect-diffs.py b/tools/intersect-diffs.py index fce22891a..be9dea5bb 100755 --- a/tools/intersect-diffs.py +++ b/tools/intersect-diffs.py @@ -182,7 +182,6 @@ def main(): if out_hunks: print FormatDiffHunks(out_hunks) - else: sys.exit(1) if __name__ == "__main__": diff --git a/tools/wrap-commit-msg.py b/tools/wrap-commit-msg.py new file mode 100755 index 000000000..b53926ae1 --- /dev/null +++ b/tools/wrap-commit-msg.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +## Copyright (c) 2012 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## +"""Wraps paragraphs of text, preserving manual formatting + +This is like fold(1), but has the special convention of not modifying lines +that start with whitespace. This allows you to intersperse blocks with +special formatting, like code blocks, with written prose. The prose will +be wordwrapped, and the manual formatting will be preserved. + + * This won't handle the case of a bulleted (or ordered) list specially, so + manual wrapping must be done. + +Occasionally it's useful to put something with explicit formatting that +doesn't look at all like a block of text inline. + + indicator = has_leading_whitespace(line); + if (indicator) + preserve_formatting(line); + +The intent is that this docstring would make it through the transform +and still be legible and presented as it is in the source. If additional +cases are handled, update this doc to describe the effect. +""" + +__author__ = "jkoleszar@google.com" +import textwrap +import sys + +def wrap(text): + if text: + return textwrap.fill(text, break_long_words=False) + '\n' + return "" + + +def main(fileobj): + text = "" + output = "" + while True: + line = fileobj.readline() + if not line: + break + + if line.lstrip() == line: + text += line + else: + output += wrap(text) + text="" + output += line + output += wrap(text) + + # Replace the file or write to stdout. + if fileobj == sys.stdin: + fileobj = sys.stdout + else: + fileobj.truncate(0) + fileobj.write(output) + +if __name__ == "__main__": + if len(sys.argv) > 1: + main(open(sys.argv[1], "r+")) + else: + main(sys.stdin)