#!/usr/bin/env bash set -euo pipefail ####################################### # Globals ####################################### declare -A commitmsg_to_files declare -A commitmsg_to_date declare -A file_status MAX_FILES=0 # 0 = nessun limite ####################################### # Logging ####################################### log_info() { echo "$*"; } log_warn() { echo "[WARN] $*" >&2; } log_error() { echo "[ERROR] $*" >&2; } usage() { cat <2 commits → classified as MULTIPLE_COMMITS" fi # popula commitmsg_to_date se necessario if [[ -z "${commitmsg_to_date[$commit_msg]:-}" ]]; then commitmsg_to_date["$commit_msg"]="$commit_ts" fi commitmsg_to_files["$commit_msg"]+="$file"$'\n' } ####################################### # Output ####################################### print_results() { log_info "Generate final output..." # ordinamento per timestamp mapfile -t ordered_msgs < <( for msg in "${!commitmsg_to_date[@]}"; do echo "${commitmsg_to_date[$msg]}|$msg" done | sort -nr | cut -d'|' -f2- ) for msg in "${ordered_msgs[@]}"; do log_info "----------------------------------------" log_info "" log_info "Commit group: $msg" log_info "Files:" while IFS= read -r file; do [[ -z "$file" ]] && continue log_info " $file" done <<< "${commitmsg_to_files[$msg]}" add_files=() rm_files=() while IFS= read -r file; do [[ -z "$file" ]] && continue status="${file_status[$file]}" if [[ "${status:0:1}" == "D" || "${status:1:1}" == "D" ]]; then rm_files+=("$file") else add_files+=("$file") fi done <<< "${commitmsg_to_files[$msg]}" if (( ${#add_files[@]} )); then log_info " git add ${add_files[*]}" fi if (( ${#rm_files[@]} )); then log_info " git rm ${rm_files[*]}" fi log_info " git commit -m \"$msg (fixup)\"" done } ####################################### # Main ####################################### main() { while getopts ":n:h" opt; do case "$opt" in n) MAX_FILES="$OPTARG" [[ "$MAX_FILES" =~ ^[0-9]+$ ]] || { log_error "-n requires a numeric argument" exit 1 } ;; h) usage exit 0 ;; *) usage exit 1 ;; esac done log_info "Detection of modified files..." mapfile -t entries < <(get_modified_files) if (( MAX_FILES > 0 && ${#entries[@]} > MAX_FILES )); then entries=( "${entries[@]:0:MAX_FILES}" ) log_info "Limiting analysis to first $MAX_FILES files" fi log_info "Analysing ${#entries[@]} files" for entry in "${entries[@]}"; do status="${entry%%|*}" file="${entry#*|}" process_file "$status" "$file" done print_results log_info "Completed." } main "$@"