#!/bin/bash # Exit immediately if a command exits with a non-zero status set -euo pipefail # Prevent info disclosure by clearing IFS to a known safe value IFS=$'\n\t' # Functions for echoing error messages to stderr error() { echo >&2 "$1" exit 1 } # Functions for echoing info messages to stdout info() { echo "$1" } # Prevent running script as root user if [[ "$EUID" -eq 0 ]]; then error "Please do not run this script as root or with sudo." fi # Check correct usage if [[ $# -ne 1 ]]; then error "Usage: $0 path_to_repo" fi # Variables REPO_DIR="$1" NEW_EMAIL="$2" BACKUP_DIR="${REPO_DIR}_backup_$(date +%Y%m%d%H%M%S)" # Check if REPO_DIR is a directory if [[ ! -d "$REPO_DIR" ]]; then error "Directory not found: ${REPO_DIR}" fi # Check if the directory is a git repository if [[ ! -d "$REPO_DIR/.git" ]]; then error "This is not a git repository: ${REPO_DIR}" fi # Navigate to the repository directory ensuring it's a safe path cd -- "$REPO_DIR" || error "Failed to navigate to directory: ${REPO_DIR}" # Ensure git-filter-repo is installed if ! command -v git-filter-repo &> /dev/null; then error "git-filter-repo is required but not found on your system. Please install it using your package manager or from https://github.com/newren/git-filter-repo." fi # Backup the repository info "Creating a backup of the repository at ${BACKUP_DIR}..." git clone --mirror "$REPO_DIR" "$BACKUP_DIR" || error "Backup failed." # Filter the repository to change the author email info "Filtering the repository to change the author email..." git filter-repo --commit-callback " import re def update_email(commit): commit.author_email = b'${NEW_EMAIL}' commit.committer_email = b'${NEW_EMAIL}' update_email(commit)" --force || error "Filtering repository failed." # Push changes to the remote repository info "Pushing changes to the remote repository..." if git push --force --all && git push --force --tags; then info "Author email updated and pushed to remote repository" else error "Failed to push changes to the remote repository" fi