#!/bin/bash set -eu SUBDIR="" CLEAN=1 fail() { printf "%s\n" "$1" >>/dev/stderr exit 32 } while getopts "cd:" opt; do case $opt in c) CLEAN=0 ;; d) SUBDIR="$(readlink -f "${OPTARG}")" ;; \?) echo "Invalid option: -$OPTARG" exit 1 ;; :) echo "Option -$OPTARG requires an argument." exit 1 ;; esac done # Shift past the last option parsed by getopts shift $((OPTIND-1)) if [ "$#" -lt 1 ] ; then INTEREST="HEAD~..HEAD" elif [[ ! "$1" =~ '..' ]] ; then INTEREST="$1..HEAD" else INTEREST="$1" fi [ $CLEAN -eq 1 ] && [ -n "$SUBDIR" ] && rm -fv "$SUBDIR/*.patch" IDSstr="$(git log --format="%H" "$INTEREST" 2>/dev/null | tac)" mapfile -t IDS <<< "$IDSstr" for id in "${IDS[@]}" ; do PATCH="$(git format-patch -1 --stdout "${id}")" TRAILERS="$(echo "$PATCH" | git interpret-trailers --parse)" FN="$(echo "$TRAILERS" | awk '/^Patch: / {print $2}')" [ -z "$FN" ] && fail "Patch filename not defined" if [ -n "$SUBDIR" ] ; then FFN="$(readlink -f "$SUBDIR"/"$FN")" else FFN="$FN" fi printf "%s\n" "$PATCH" > "$FFN" printf "%s\n" "$FN" done