From 31716686586c9fd1454fa867f350379c8de810fb Mon Sep 17 00:00:00 2001 From: Carmelo Messina Date: Thu, 19 Feb 2026 12:59:30 +0100 Subject: [PATCH] TOOLS: auto-commit.sh - Add script to group modified files by last commit and generate fixup commands This script analyzes modified files in the repository, retrieves their commit history, and groups them by the most relevant commit message. Files with no history or more than two commits are classified separately. The output suggests corresponding git add, git rm, and git commit commands to create organized fixup commits, ordered by commit date. Useful for simplifying the fixup after each rebase --- tools/auto-commit.sh | 185 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 tools/auto-commit.sh diff --git a/tools/auto-commit.sh b/tools/auto-commit.sh new file mode 100644 index 00000000..084838f9 --- /dev/null +++ b/tools/auto-commit.sh @@ -0,0 +1,185 @@ +#!/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 "$@"