Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Tools/gittools/git-commit-subsystems
Views: 1798
#!/usr/bin/env 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 <<EOF Usage: git commit-subsystems [OPTIONS] Ardupilot's git extension. Create a different commit for each ardupilot's subsystem (vehicles, libraries and folders in the project's root). The items in OPTIONS are passed down to the original git commit command with exception of options --message and --file (and their short versions). Boths are related to the commit message: commit-subsystems will treat the commit message from one of those two options as a template such that occurrences of \$subsystem are replaced with the subsystem being currently committed. If neither --message or --file are passed, then the first commit's message will be used as a template for the other messages and option --edit will be used for the next commits. To avoid that behavior use --naive. Another custom option is --raw: don't use commit message as a template. EOF } MSG_FILE="$GIT_DIR/COMMIT_SUBSYSTEM_MSG" extra_options= process_msg() { local subsystem=$1 local prev_subsystem=$2 if [[ -n "$option_m" || -n "$option_F" ]]; then if [[ $option_F == - ]]; then echo "Please, type the commits message template:" option_F="$GIT_DIR/COMMIT_SUBSYSTEM_TEMPLATE" cat - > "$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