From fea8299ff30517dcbd42f5a4587fef1cb0fe8d7b Mon Sep 17 00:00:00 2001 From: Gustavo Jose de Sousa Date: Thu, 3 Sep 2015 19:15:58 -0300 Subject: [PATCH] Tools: gittools: add git-commit-subsystems A git extension for committing multiple subsystems. --- Tools/gittools/git-commit-subsystems | 202 +++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100755 Tools/gittools/git-commit-subsystems diff --git a/Tools/gittools/git-commit-subsystems b/Tools/gittools/git-commit-subsystems new file mode 100755 index 0000000000..4ef3805996 --- /dev/null +++ b/Tools/gittools/git-commit-subsystems @@ -0,0 +1,202 @@ +#!/bin/bash + +SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +GIT_DIR=$(git rev-parse --git-dir) +GIT_ROOT=$(git rev-parse --show-toplevel) + +usage() { + cat >&$1 < "$option_F" + fi + + if [[ -n "$option_m" ]]; then + echo "$option_m" + else + cat "$option_F" + fi | if $option_raw; then + cat + else + sed "s,\$subsystem,$cur_subsystem,g" + fi > "$MSG_FILE" + + + extra_options=(-F "$MSG_FILE") + elif [[ -n $prev_subsystem ]] && ! $option_naive; then # try to be "smart" + cat $GIT_DIR/COMMIT_EDITMSG \ + | sed -e "/^\s*#/d" \ + -e "s/.*\<$prev_subsystem\>.*/\0\n#\0/" \ + | sed "/^[^#]/ s/\<$prev_subsystem\>/$subsystem/g" > "$MSG_FILE" + echo >> "$MSG_FILE" + echo "# This commit message was adapted by commit-subsystems" >> "$MSG_FILE" + extra_options=(-F "$MSG_FILE" --edit) + fi +} + +commit_subsystem() { + local subsystem=$1 + local prev_subsystem=$2 + shift 2 + process_msg $subsystem $prev_subsystem + if ! git commit ${extra_options[*]} "$@"; then + echo "Couldn't commit subsystem $subsystem, aborting..." >&2 + exit 1 + fi +} + +args=() + +option_m= +option_F= +option_naive=false +option_raw=false + +while [[ -n "$1" ]]; do + opt="$1" + case "$opt" in + -h|--help) + usage 1 + exit 0 + ;; + -m|--message) + shift + if [[ -z "$1" ]]; then + echo "Option $opt requires a commit message." >&2 + exit 1 + fi + option_m="$1" + ;; + -F|--file) + shift + if [[ -z "$1" ]]; then + echo "Option $opt requires a file name." >&2 + exit 1 + fi + option_F="$1" + ;; + --naive) + option_naive=true + ;; + --raw) + option_raw=true + ;; + *) + args+=("$1") + ;; + esac + shift +done + +if [[ -n $option_m && -n $option_F ]]; then + echo "Options -m and -F can't be combined." >&2 + exit 1 +fi + +set -- "${args[@]}" + +LIST=$GIT_DIR/COMMIT_SUBSYSTEMS_LIST + +git diff --name-only --staged | $SCRIPT_DIR/path-libraries.sh -p > $LIST +git diff --name-only --staged | $SCRIPT_DIR/path-nonlibraries.sh -p >> $LIST + +if [[ $(cat "$LIST" | wc -l) -eq 0 ]]; then + echo "Nothing to commit." >&2 + exit 1 +fi + +echo "Reseting changes in order to add files separately..." +git reset >/dev/null + +# head before commits - for recovery +RECOVERY_HEAD=$(git log -n 1 --format=%H) +exit_hook() { + local last_error=$? + + set +e + + [[ -a /dev/fd/3 ]] && exec 3<&- + + [[ $last_error -eq 0 ]] && return 0 + + echo + echo "Program interrupted or finished with error(s), reseting head..." >&2 + git reset $RECOVERY_HEAD >/dev/null + echo "Trying to re-add files..." >&2 + if [[ ! -f $LIST ]]; then + echo "File with list of added files not found..." >&2 + else + error=false + cat $LIST | while read subsystem path; do + if ! git add -- "$GIT_ROOT/$path"; then + echo "Couldn't add \"$path\"..." >&2 + error=true + fi + done + + if $error; then + echo "This is embarrassing, couldn't re-add all files. Sorry." >&2 + else + echo "Files re-added." >&2 + fi + fi + + return 1 +} + +set -e +trap "exit 1" SIGINT +trap exit_hook EXIT + +echo "Adding and committing subsystems..." +exec 3< $LIST +cur_subsystem= +prev_subsystem= +empty=true +while read -u 3 subsystem path; do + empty=false + if [[ $cur_subsystem != $subsystem ]]; then + if [[ -n $cur_subsystem ]]; then + commit_subsystem "$cur_subsystem" "$prev_subsystem" "$@" + echo + fi + prev_subsystem=$cur_subsystem + cur_subsystem=$subsystem + fi + if ! git add -- "$GIT_ROOT/$path"; then + echo "Couldn't add \"$path\", aborting..." >&2 + exit 1 + fi +done + +# the last one +commit_subsystem "$cur_subsystem" "$prev_subsystem" "$@" +echo