diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2023-11-23 19:22:55 +0200 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2024-01-05 12:29:38 +0000 |
commit | c646de371179b6d77d33a6c8e40735174aab042b (patch) | |
tree | 662289e4b2d1d0464ae41fb0ee22fd76663b9e5f /git-hooks/gerrit_commit_msg_hook | |
parent | 40490ad02475c6a550f74b6f53aecb2443114cab (diff) |
Update commit-msg hook from gerrit upstream
Change-Id: I41d1efe4783fd0abef3b4d308f5f6ba1aec69fa5
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'git-hooks/gerrit_commit_msg_hook')
-rwxr-xr-x | git-hooks/gerrit_commit_msg_hook | 252 |
1 files changed, 93 insertions, 159 deletions
diff --git a/git-hooks/gerrit_commit_msg_hook b/git-hooks/gerrit_commit_msg_hook index 3d8e27f..db60939 100755 --- a/git-hooks/gerrit_commit_msg_hook +++ b/git-hooks/gerrit_commit_msg_hook @@ -1,7 +1,7 @@ #!/bin/sh -# From Gerrit Code Review V2.7-117 +# From Gerrit Code Review 3.10.0 # -# Part of Gerrit Code Review (http://code.google.com/p/gerrit/) +# Part of Gerrit Code Review (https://www.gerritcodereview.com/) # # Copyright (C) 2009 The Android Open Source Project # @@ -16,161 +16,95 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# - -unset GREP_OPTIONS - -CHANGE_ID_AFTER="Bug|Issue|Task-number|Fixes|Pick-to|Coverity-Id" -MSG="$1" - -# Check for, and add if missing, a unique Change-Id -# -add_ChangeId() { - clean_message=`sed -e ' - /^diff --git a\/.*/{ - s/// - q - } - /^Signed-off-by:/d - /^#/d - ' "$MSG" | git stripspace` - if test -z "$clean_message" - then - return - fi - - # Does Change-Id: already exist? if so, exit (no change). - if grep -i '^Change-Id:' "$MSG" >/dev/null - then - return - fi - - 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 - - # 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 a/ { - 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 "" - } - - 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` - then - echo "parent $parent" - fi - echo "author `git var GIT_AUTHOR_IDENT`" - echo "committer `git var GIT_COMMITTER_IDENT`" - echo - printf '%s' "$clean_message" -} -_gen_ChangeId() { - _gen_ChangeIdInput | - git hash-object -t commit --stdin -} - -add_ChangeId +set -u + +# avoid [[ which is not POSIX sh. +if test "$#" != 1 ; then + echo "$0 requires an argument." + exit 1 +fi + +if test ! -f "$1" ; then + echo "file does not exist: $1" + exit 1 +fi + +# Do not create a change id if requested +case "$(git config --get gerrit.createChangeId)" in + false) + exit 0 + ;; + always) + ;; + *) + # Do not create a change id for squash/fixup commits. + if head -n1 "$1" | LC_ALL=C grep -q '^[a-z][a-z]*! '; then + exit 0 + fi + ;; +esac + + +if git rev-parse --verify HEAD >/dev/null 2>&1; then + refhash="$(git rev-parse HEAD)" +else + refhash="$(git hash-object -t tree /dev/null)" +fi + +random=$({ git var GIT_COMMITTER_IDENT ; echo "$refhash" ; cat "$1"; } | git hash-object --stdin) +dest="$1.tmp.${random}" + +trap 'rm -f "$dest" "$dest-2"' EXIT + +if ! cat "$1" | sed -e '/>8/q' | git stripspace --strip-comments > "${dest}" ; then + echo "cannot strip comments from $1" + exit 1 +fi + +if test ! -s "${dest}" ; then + echo "file is empty: $1" + exit 1 +fi + +reviewurl="$(git config --get gerrit.reviewUrl)" +if test -n "${reviewurl}" ; then + token="Link" + value="${reviewurl%/}/id/I$random" + pattern=".*/id/I[0-9a-f]\{40\}" +else + token="Change-Id" + value="I$random" + pattern=".*" +fi + +if git interpret-trailers --parse < "$1" | grep -q "^$token: $pattern$" ; then + exit 0 +fi + +# There must be a Signed-off-by trailer for the code below to work. Insert a +# sentinel at the end to make sure there is one. +# Avoid the --in-place option which only appeared in Git 2.8 +if ! git interpret-trailers \ + --trailer "Signed-off-by: SENTINEL" < "$1" > "$dest-2" ; then + echo "cannot insert Signed-off-by sentinel line in $1" + exit 1 +fi + +# Make sure the trailer appears before any Signed-off-by trailers by inserting +# it as if it was a Signed-off-by trailer and then use sed to remove the +# Signed-off-by prefix and the Signed-off-by sentinel line. +# Avoid the --in-place option which only appeared in Git 2.8 +# Avoid the --where option which only appeared in Git 2.15 +if ! git -c trailer.where=before interpret-trailers \ + --trailer "Signed-off-by: $token: $value" < "$dest-2" | + sed -e "s/^Signed-off-by: \($token: \)/\1/" \ + -e "/^Signed-off-by: SENTINEL/d" > "$dest" ; then + echo "cannot insert $token line in $1" + exit 1 +fi + +if ! mv "${dest}" "$1" ; then + echo "cannot mv ${dest} to $1" + exit 1 +fi |