[Libreoffice-commits] core.git: .git-hooks/commit-msg

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Jan 24 20:06:30 UTC 2020


 .git-hooks/commit-msg |  163 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 118 insertions(+), 45 deletions(-)

New commits:
commit cac5ce6de095fd0595d1fa58e5a8d12aa8ca8b6f
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jan 24 16:27:44 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Jan 24 21:05:58 2020 +0100

    git hooks: update the change-id part of commit-msg
    
    To the up to date version that is set up by e.g. 'git review -s' from
    gerrit.libreoffice.org. Should help with \c in commit messages.
    
    Change-Id: I42508f6f5bbb6fa70357694fcc820ed9a22f3b0e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87347
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    Tested-by: Jan-Marek Glogowski <glogow at fbihome.de>
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/.git-hooks/commit-msg b/.git-hooks/commit-msg
index 2c788fb0f622..027c37510ff6 100755
--- a/.git-hooks/commit-msg
+++ b/.git-hooks/commit-msg
@@ -29,8 +29,8 @@ EOF
 }
 
 test "" = "$(grep '^Signed-off-by: ' "$1" |
-	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
-	abort "$1" "Duplicate Signed-off-by lines."
+         sort | uniq -c | sed -e '/^[         ]*1[         ]/d')" || {
+        abort "$1" "Duplicate Signed-off-by lines."
 }
 
 # Check that the first line exists, and is not an asterisk
@@ -101,7 +101,7 @@ CHANGE_ID_AFTER="Bug|Issue"
 #
 add_ChangeId() {
         clean_message=`sed -e '
-                /^diff --git a\/.*/{
+                /^diff --git .*/{
                         s///
                         q
                 }
@@ -113,58 +113,131 @@ add_ChangeId() {
                 return
         fi
 
-        id=`grep -i '^Change-Id:' "$MSG" | sed -e "s/.*: I//"`
-        temp_msg=`grep -v -i '^Change-Id:' "$MSG"`
-        echo "$temp_msg" > "$MSG"
+        if test "false" = "`git config --bool --get gerrit.createChangeId`"
+        then
+                return
+        fi
 
-        if  test -z "$id"
+        # Does Change-Id: already exist? if so, exit (no change).
+        if grep -i '^Change-Id:' "$MSG" >/dev/null
         then
-            id=`_gen_ChangeId`
+                return
         fi
-        perl -e '
-                $MSG = shift;
-                $id = shift;
-                $CHANGE_ID_AFTER = shift;
-
-                undef $/;
-                open(I, $MSG); $_ = <I>; close I;
-                s|^diff --git a/.*||ms;
-                s|^#.*$||mg;
-                exit unless $_;
-
-                @message = split /\n/;
-                $haveFooter = 0;
-                $startFooter = @message;
-                for($line = @message - 1; $line >= 0; $line--) {
-                        $_ = $message[$line];
-
-                        if (/^[a-zA-Z0-9-]+: /) {
-                                $haveFooter++;
-                                next;
-                        }
-                        next if /^[ []/;
-                        $startFooter = $line if ($haveFooter && /^\r?$/);
-                        last;
-                }
 
-                @footer = @message[$startFooter+1.. at message];
-                @message = @message[0..$startFooter];
-                push(@footer, "") unless @footer;
+        id=`_gen_ChangeId`
+        T="$MSG.tmp.$$"
+        AWK=awk
+        if [ -x /usr/xpg4/bin/awk ]; then
+                # Solaris AWK is just too broken
+                AWK=/usr/xpg4/bin/awk
+        fi
 
-                for ($line = 0; $line < @footer; $line++) {
-                        $_ = $footer[$line];
-                        next if /^($CHANGE_ID_AFTER):/i;
-                        last;
+        # How this works:
+        # - parse the commit message as (textLine+ blankLine*)*
+        # - assume textLine+ to be a footer until proven otherwise
+        # - exception: the first block is not footer (as it is the title)
+        # - read textLine+ into a variable
+        # - then count blankLines
+        # - once the next textLine appears, print textLine+ blankLine* as these
+        #   aren't footer
+        # - in END, the last textLine+ block is available for footer parsing
+        $AWK '
+        BEGIN {
+                # while we start with the assumption that textLine+
+                # is a footer, the first block is not.
+                isFooter = 0
+                footerComment = 0
+                blankLines = 0
+        }
+
+        # Skip lines starting with "#" without any spaces before it.
+        /^#/ { next }
+
+        # Skip the line starting with the diff command and everything after it,
+        # up to the end of the file, assuming it is only patch data.
+        # If more than one line before the diff was empty, strip all but one.
+        /^diff --git / {
+                blankLines = 0
+                while (getline) { }
+                next
+        }
+
+        # Count blank lines outside footer comments
+        /^$/ && (footerComment == 0) {
+                blankLines++
+                next
+        }
+
+        # Catch footer comment
+        /^\[[a-zA-Z0-9-]+:/ && (isFooter == 1) {
+                footerComment = 1
+        }
+
+        /]$/ && (footerComment == 1) {
+                footerComment = 2
+        }
+
+        # We have a non-blank line after blank lines. Handle this.
+        (blankLines > 0) {
+                print lines
+                for (i = 0; i < blankLines; i++) {
+                        print ""
                 }
-                splice(@footer, $line, 0, "Change-Id: I$id");
 
-                $_ = join("\n", @message, @footer);
-                open(O, ">$MSG"); print O; close O;
-        ' "$MSG" "$id" "$CHANGE_ID_AFTER"
+                lines = ""
+                blankLines = 0
+                isFooter = 1
+                footerComment = 0
+        }
+
+        # Detect that the current block is not the footer
+        (footerComment == 0) && (!/^\[?[a-zA-Z0-9-]+:/ || /^[a-zA-Z0-9-]+:\/\//) {
+                isFooter = 0
+        }
+
+        {
+                # We need this information about the current last comment line
+                if (footerComment == 2) {
+                        footerComment = 0
+                }
+                if (lines != "") {
+                        lines = lines "\n";
+                }
+                lines = lines $0
+        }
+
+        # Footer handling:
+        # If the last block is considered a footer, splice in the Change-Id at the
+        # right place.
+        # Look for the right place to inject Change-Id by considering
+        # CHANGE_ID_AFTER. Keys listed in it (case insensitive) come first,
+        # then Change-Id, then everything else (eg. Signed-off-by:).
+        #
+        # Otherwise just print the last block, a new line and the Change-Id as a
+        # block of its own.
+        END {
+                unprinted = 1
+                if (isFooter == 0) {
+                        print lines "\n"
+                        lines = ""
+                }
+                changeIdAfter = "^(" tolower("'"$CHANGE_ID_AFTER"'") "):"
+                numlines = split(lines, footer, "\n")
+                for (line = 1; line <= numlines; line++) {
+                        if (unprinted && match(tolower(footer[line]), changeIdAfter) != 1) {
+                                unprinted = 0
+                                print "Change-Id: I'"$id"'"
+                        }
+                        print footer[line]
+                }
+                if (unprinted) {
+                        print "Change-Id: I'"$id"'"
+                }
+        }' "$MSG" > "$T" && mv "$T" "$MSG" || rm -f "$T"
 }
 _gen_ChangeIdInput() {
         echo "tree `git write-tree`"
-        if parent=`git rev-parse HEAD^0 2>/dev/null`
+        if parent=`git rev-parse "HEAD^0" 2>/dev/null`
         then
                 echo "parent $parent"
         fi


More information about the Libreoffice-commits mailing list