#!/bin/bash # Patchwork - automated patch tracking system # Copyright (C) 2010 martin f. krafft # # SPDX-License-Identifier: GPL-2.0-or-later # Git post-receive hook to update Patchwork patches after Git pushes set -eu PW_DIR=/opt/patchwork/patchwork #TODO: the state map should really live in the repo's git-config STATE_MAP="refs/heads/master:Accepted" # ignore all commits already present in these refs # e.g., # EXCLUDE="refs/heads/upstream refs/heads/other-project" EXCLUDE="" do_exit=0 trap "do_exit=1" INT get_patchwork_hash() { local hash hash=$(git diff "$1~..$1" | python $PW_DIR/hasher.py) echo "$hash" test -n "$hash" } get_patch_id() { local id id=$(pwclient info -h "$1" 2>/dev/null | \ sed -rne 's,- id[[:space:]]*: ,,p') echo "$id" test -n "$id" } set_patch_state() { pwclient update -s "$2" -c "$3" "$1" 2>&1 } update_patches() { local cnt; cnt=0 for rev in $(git rev-parse --not ${EXCLUDE} | git rev-list --stdin --no-merges --reverse "${1}".."${2}"); do if [ "$do_exit" = 1 ]; then echo "I: exiting..." >&2 break fi hash=$(get_patchwork_hash "$rev") if [ -z "$hash" ]; then echo "E: failed to hash rev $rev." >&2 continue fi id=$(get_patch_id "$hash" || true) if [ -z "$id" ]; then echo "E: failed to find patch for rev $rev." >&2 continue fi reason="$(set_patch_state "$id" "$3" "$rev")" if [ -n "$reason" ]; then echo "E: failed to update patch #$id${reason:+: $reason}." >&2 continue fi echo "I: patch #$id updated using rev $rev." >&2 cnt=$((cnt + 1)) done echo "I: $cnt patch(es) updated to state $3." >&2 } while read -r oldrev newrev refname; do found=0 for i in $STATE_MAP; do key="${i%:*}" if [ "$key" = "$refname" ]; then update_patches "$oldrev" "$newrev" ${i#*:} found=1 break fi done if [ $found -eq 0 ]; then echo "E: STATE_MAP has no mapping for branch $refname" >&2 fi done