mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
102 lines
2.5 KiB
Bash
Executable file
102 lines
2.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
# Usage function
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: git rename-file [OPTIONS] <source> <destination>
|
|
|
|
Description:
|
|
Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
|
It combines the functionality of the "mv" command and "git mv". This is particularly useful for renaming files or directories
|
|
to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
|
|
|
Options:
|
|
-h, --help Show this help message and exit.
|
|
|
|
Examples:
|
|
git rename-file old_filename new_filename
|
|
git rename-file old_directory new_directory
|
|
EOF
|
|
}
|
|
|
|
# Check for help option
|
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
# Check for correct number of arguments
|
|
if [ "$#" -ne 2 ]; then
|
|
echo "Error: Incorrect number of arguments."
|
|
echo ""
|
|
usage >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Assign variables
|
|
SOURCE="$1"
|
|
DESTINATION="$2"
|
|
TEMP_NAME="${SOURCE}.temp"
|
|
|
|
# Function to check if a file or directory exists in a case-sensitive manner
|
|
check_case_sensitive_exists() {
|
|
local path="$1"
|
|
local dir
|
|
local base
|
|
|
|
dir=$(dirname "$path")
|
|
base=$(basename "$path")
|
|
|
|
if [ -e "$dir" ]; then
|
|
if (cd "$dir" && find . -maxdepth 1 -name "$base" | grep -q "$base"); then
|
|
return 0
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Check if source exists and is under version control
|
|
if ! check_case_sensitive_exists "$SOURCE"; then
|
|
echo "Error: Source '$SOURCE' does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
if ! git ls-files --error-unmatch "$SOURCE" > /dev/null 2>&1; then
|
|
echo "Error: Source '$SOURCE' is not under version control. If file or directory is new, it must at least be staged."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if destination already exists
|
|
if check_case_sensitive_exists "$DESTINATION"; then
|
|
echo "Error: Destination '$DESTINATION' already exists."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if the destination directory exists
|
|
DEST_DIR=$(dirname "$DESTINATION")
|
|
if ! check_case_sensitive_exists "$DEST_DIR"; then
|
|
echo "Error: Destination directory '$DEST_DIR' does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
# Create a rollback function
|
|
rollback() {
|
|
echo "Rolling back changes..."
|
|
if [ -e "$TEMP_NAME" ]; then
|
|
git mv -f "$TEMP_NAME" "$SOURCE"
|
|
fi
|
|
}
|
|
|
|
# Trap errors to trigger rollback
|
|
trap 'rollback' ERR
|
|
|
|
# Move the file to a temporary name within the Git repository
|
|
git mv "$SOURCE" "$TEMP_NAME"
|
|
|
|
# Move the temporary file to the desired destination
|
|
git mv "$TEMP_NAME" "$DESTINATION"
|
|
|
|
echo "Successfully renamed '$SOURCE' to '$DESTINATION'."
|