diff --git a/git/README.MD b/git/README.MD new file mode 100644 index 0000000..7b8a55c --- /dev/null +++ b/git/README.MD @@ -0,0 +1,5 @@ +# Tools + +| Name | Description | Usage | File | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | ---- | +| git_rewrite_author | **USE WITH CAUTION!!!**

This script will rewrite the entire history of the remote end and set the author email to the provided one.

**This is NOT reversable!** | `./git_rewrite_author.sh "/path/to/repo" "new.mail@address.com"` | \ No newline at end of file diff --git a/git/git_rewrite_author.sh b/git/git_rewrite_author.sh new file mode 100755 index 0000000..e844079 --- /dev/null +++ b/git/git_rewrite_author.sh @@ -0,0 +1,72 @@ +#!/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 \ No newline at end of file