mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
87 lines
2.5 KiB
Bash
Executable file
87 lines
2.5 KiB
Bash
Executable file
#!/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
|