#!/bin/bash # # (c) 2012 - 2017 PrydeWorX # Sven Eden, PrydeWorX - Bardowick, Germany # yamakuzure@users.sourceforge.net # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # History and Changelog: # Version Date Maintainer Change(s) # 0.0.1 2017-07-27 sed, PrydeWorX First Design, forked off pwx_git_getter.sh # # Common functions source pwx_git_funcs.sh # Version, please keep this current VERSION="0.0.1" # Global values to be filled in: SINCE_WHEN="" OUTPUT="${HERE}/patches" EXTRA_GIT_OPTS="" # The options for the git format-patch command: GIT_FP_OPTS="-1 -C --find-copies-harder -n" # Options and the corresponding help text OPT_SHORT=ho: OPT_LONG=help,output: HELP_TEXT="Usage: $0 [OPTIONS] Build formatted patches for all commits *after* up to HEAD. OPTIONS: -h|--help Show this help and exit. -o|--output : Path to where to write the patches. The default is to write into the subdirectory 'patches' of the current directory. " # ========================================= # === Use getopt (GNU enhanced version) === # ========================================= # Check the version first, so we do not run into trouble getopt --test > /dev/null if [[ $? -ne 4 ]]; then echo "ERROR: getopt is not the GNU enhanced version." exit 1 fi # Store the output so we can check for errors. OPT_PARSED=$(getopt --options $OPT_SHORT --longoptions $OPT_LONG --name "$0" -- "$@") if [[ $? -ne 0 ]]; then # getopt has already complained about wrong arguments to stdout exit 2 fi # Use eval with "$OPT_PARSED" to properly handle the quoting eval set -- "$OPT_PARSED" # -------------------- # --- Handle input --- # -------------------- while true; do case "$1" in -h|--help) echo "$HELP_TEXT" exit 0 ;; -o|--output) OUTPUT="$2" shift 2 ;; --) shift break ;; *) echo "Something went mysteriously wrong." exit 3 ;; esac done # At this point we must have left if [[ $# -ne 1 ]]; then echo "$HELP_TEXT" exit 4 fi # So these must be it: SINCE_WHEN="$1" # ========================================================== # === The OUTPUT directory must exist and must be empty. === # ========================================================== if [[ -n "$OUTPUT" ]]; then if [[ ! -d "$OUTPUT" ]]; then mkdir -p "$OUTPUT" || die "Can not create $OUTPUT [$?]" fi if [[ -n "$(ls "$OUTPUT"/????-*.patch 2>/dev/null)" ]]; then echo "ERROR: $OUTPUT already contains patches" exit 4 fi else echo "You have set the output directory to be" echo "an empty string. Where should I put the" echo "patches, then?" exit 5 fi # --- Add an error log file to the list of temp files PWX_ERR_LOG="/tmp/pwx_git_getter_$$.log" add_temp "$PWX_ERR_LOG" touch $PWX_ERR_LOG || die "Unable to create $PWX_ERR_LOG" # ========================================= # === Step 1: Build the list of commits === # ========================================= echo -n "Building commit list..." # lst_a is for the list of commits in reverse order lst_a=/tmp/git_list_a_$$.lst touch "$lst_a" || die "Can not create $lst_a" truncate -s 0 $lst_a add_temp "$lst_a" git log ${SINCE_WHEN}..HEAD 2>/dev/null | \ grep -P "^commit\s+" | \ cut -d ' ' -f 2 | \ tac > $lst_a c_cnt=$(wc -l $lst_a | cut -d ' ' -f 1) echo " $c_cnt commits found" # ================================================================ # === Step 2: Now that we have a lst_b file with a list of all === # === relevant commits for all files found in the === # === target, the commit patches can be build. === # ================================================================ echo -n "Creating patches ..." # To be able to apply the patches in the correct order, they need # to be numbered. However, as git will only create one patch at a # time, we have to provide the numbering by ourselves. n=0 for c in $(cut -d ' ' -f 2 $lst_a) ; do n=$((n+1)) n_str="$(printf "%04d" $n)" git format-patch $GIT_FP_OPTS -o $OUTPUT --start-number=$n $c \ 1>/dev/null 2>$PWX_ERR_LOG || die "git format-patch failed on $c" done echo " done" # ======================================== # === Cleanup : Remove temporary files === # ======================================== cleanup echo "All finished"