To continue the previous epopee: we shall interactively detect all the occurrences of the missed renames in a given git repo, and let user choose if he wants to make a potential rename into real rename.
#!/bin/bash # Check if correct number of arguments are provided if [ $# -ne 1 ]; then echo "Usage: $0 <repo_path>" exit 1 fi REPO_PATH="$1" # Change to the repository directory cd "$REPO_PATH" || exit 1 # Function to normalize filename normalize_filename() { echo "$1" | tr '[:upper:]' '[:lower:]' | tr -d '_' } # Function to get the list of commits get_commits() { git rev-list HEAD } # Get initial list of commits COMMITS=$(get_commits) needs_repetition=true # Iterate through each commit while [ "$needs_repetition" = true ]; do needs_repetition=false for COMMIT_HASH in $COMMITS; do echo -e "Currently observing commit: $COMMIT_HASH" # Get the next commit hash NEXT_COMMIT_HASH=$(git rev-list "$COMMIT_HASH" | grep -A 1 "$COMMIT_HASH" | tail -n 1) # Get list of added files for the current commit ADDED_FILES=$(git diff-tree --no-commit-id --name-status -r "$COMMIT_HASH" | grep "^A" | cut -f2-) # Remove added files that are seen as renames RENAMED_FILES=$(git diff-tree --no-commit-id --name-status -M -r "$COMMIT_HASH" | grep "^R" | cut -f3-) for renamed_file in $RENAMED_FILES; do ADDED_FILES=$(echo "$ADDED_FILES" | grep -v "^$renamed_file$") done # Get list of deleted files for the current commit DELETED_FILES=$(git diff-tree --no-commit-id --name-status -r "$COMMIT_HASH" | grep "^D" | cut -f2-) # Iterate through added files while IFS= read -r added_file; do [ -z "$added_file" ] && continue added_dir=$(dirname "$added_file") added_name=$(basename "$added_file") added_norm=$(normalize_filename "${added_name%.*}") # Iterate through deleted files while IFS= read -r deleted_file; do [ -z "$deleted_file" ] && continue deleted_dir=$(dirname "$deleted_file") deleted_name=$(basename "$deleted_file") deleted_norm=$(normalize_filename "${deleted_name%.*}") # Check if files are in the same directory and have matching normalized names if [ "$deleted_dir" = "$added_dir" ] && [ "$deleted_norm" = "$added_norm" ]; then echo -e "\e[93mCOMMIT_HASH=$COMMIT_HASH, OLD_FILE=$deleted_file, NEW_FILE=$added_file\e[0m" # Prompt user for confirmation echo -e "\e[94mDo you want to run fix_renames.sh for this match? (Y/N)\e[0m" read -r response < /dev/tty if [[ "$response" =~ ^[Yy]$ ]]; then cd .. ./fix_renames.sh "$REPO_PATH" "$COMMIT_HASH" "$deleted_file" "$added_file" cd "$REPO_PATH" # Recreate the list of commits COMMITS=$(get_commits) # Find the position of the next commit hash NEXT_COMMIT_POSITION=$(echo "$COMMITS" | grep -n "$NEXT_COMMIT_HASH" | cut -d: -f1) # Continue from the commit preceding the next commit COMMITS=$(echo "$COMMITS" | tail -n +"$((NEXT_COMMIT_POSITION - 1))") NEW_COMMIT_HASH=$(echo "$COMMITS" | head -n 1) echo -e "\e[92mThe old commit $COMMIT_HASH now became the new commit $NEW_COMMIT_HASH expected to be followed by $NEXT_COMMIT_HASH.\e[0m" needs_repetition=true break 3 fi fi done <<< "$DELETED_FILES" done <<< "$ADDED_FILES" done if ! $needs_repetition; then break fi done set FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE' -- --branches --tags
No comments:
Post a Comment