#!/usr/bin/env bash set -euo pipefail PROGRAM=$0 CURRENT_FILENAME="" DESTINATION_FILENAME="" function usage() { echo 1>&2 "USAGE: ${PROGRAM} CURRENT_FILENAME DESTINATION_FILENAME" } while [[ $# -gt 0 ]] do key="$1" if [[ "$CURRENT_FILENAME" == "" ]]; then CURRENT_FILENAME=$key elif [[ "$DESTINATION_FILENAME" == "" ]]; then DESTINATION_FILENAME=$key else usage exit 30 # Error during arguments parsing fi shift # past argument or value done if [[ "$DESTINATION_FILENAME" == "" ]]; then usage exit 20 # Missing arguments CURRENT_FILENAME elif [[ "$CURRENT_FILENAME" == "" ]]; then usage exit 10 # Missing arguments CURRENT_FILENAME else if [ -e "$DESTINATION_FILENAME" ]; then echo 1>&2 "$DESTINATION_FILENAME already exists." echo 1>&2 "Make sure to remove the destination first." exit 40 fi if [[ "$DESTINATION_FILENAME" == */ ]]; then echo 1>&2 "$DESTINATION_FILENAME is not a file path." exit 80 fi if [[ "$DESTINATION_FILENAME" == */* ]]; then DESTINATION_DIR="${DESTINATION_FILENAME%/*}" if ! mkdir -p "$DESTINATION_DIR"; then echo 1>&2 "Failed to create destination directory: $DESTINATION_DIR" exit 160 fi fi MERGE_OPT= ff=$(git config --get merge.ff || true) if [[ "$ff" == "only" ]]; then MERGE_OPT="--ff" fi echo "Copying $CURRENT_FILENAME into $DESTINATION_FILENAME" INTERMEDIATE_FILENAME="${CURRENT_FILENAME//\//__}-move-to-${DESTINATION_FILENAME//\//__}" # We keep the existing file on the side in a commit git mv "${CURRENT_FILENAME}" "${INTERMEDIATE_FILENAME}" git commit -nm "Keep $CURRENT_FILENAME" # We come back to the previous state and revert that change INTERMEDIATE_SAVED=$(git rev-parse HEAD) git reset --hard HEAD^ # We move the file to its new destination git mv "${CURRENT_FILENAME}" "${DESTINATION_FILENAME}" git commit -nm "Copy $CURRENT_FILENAME into $DESTINATION_FILENAME" # We come back to the previous state and revert that change again DESTINATION_SAVED=$(git rev-parse HEAD) git reset --hard HEAD^ # We keep both files # shellcheck disable=SC2086 git merge $MERGE_OPT "${DESTINATION_SAVED}" "${INTERMEDIATE_SAVED}" -m "Duplicate ${CURRENT_FILENAME} history." # We get back our original name git mv "${INTERMEDIATE_FILENAME}" "${CURRENT_FILENAME}" git commit -nm "Set back ${CURRENT_FILENAME} file" fi