git history-move
The snippet can be accessed without any authentication.
Authored by
Ingo Meyer
Usage: git history-move [-d] [-r file regex] <target-directory> [<rev-list options>]
A helper script for `git filter-branch` for moving selected files to another directory in Git history.
positional arguments:
<target-directory> The target directory the selected files will be moved to.
<rev-list options> Arguments for `git rev-list`. All positive refs included by these options are rewritten.
See `man git-filter-branch` for more details.
optional arguments:
-d Dry run, only print files that would be moved.
-r Regex filter for files being moved, defaults to '.*' (matches every string).
Hint: By default the regex will match every substring of a given file path,
use '^{regex}$' to match the complete string instead.
git-history-move.sh 2.68 KiB
#!/bin/bash
print_usage () {
echo "Usage: git history-move [-d] [-r file regex] <target-directory> [<rev-list options>]"
echo
echo "A helper script for \`git filter-branch\` for moving selected files to another directory in Git history."
echo
echo "positional arguments:"
echo " <target-directory> The target directory the selected files will be moved to."
echo " <rev-list options> Arguments for \`git rev-list\`. All positive refs included by these options are rewritten."
echo " See \`man git-filter-branch\` for more details."
echo
echo "optional arguments:"
echo " -d Dry run, only print files that would be moved."
echo " -r Regex filter for files being moved, defaults to '.*' (matches every string)."
echo " Hint: By default the regex will match every substring of a given file path,"
echo " use '^{regex}$' to match the complete string instead."
}
parse_options () {
DRY_RUN=0
FILE_REGEX=".*"
while getopts ":dr:" opt; do
case ${opt} in
d)
DRY_RUN=1
;;
r)
FILE_REGEX="${OPTARG}"
;;
:)
>&2 echo "Option '-${OPTARG}' requires an argument."
exit 1
;;
\?)
>&2 echo "Invalid option: '-${OPTARG}'"
print_usage
exit 1
;;
*)
print_usage
exit 1
;;
esac
done
shift $((OPTIND-1))
TARGET_DIR="$1"
if [[ "${TARGET_DIR}" == "" ]]; then
>&2 echo "Please specify a target directory!"
print_usage
exit 1
fi
shift
REMAINING_ARGS=( "$@" )
}
filter_git_repository () {
local TMP_SCRIPT_DIR RETURN_CODE
TMP_SCRIPT_DIR="$(mktemp -d)" || return 1
cat <<- EOF > "${TMP_SCRIPT_DIR}/filter.sh"
#!/bin/bash
if (( ${DRY_RUN} )); then
echo
fi
git ls-tree --name-only "\${GIT_COMMIT}" | while read -r FILE; do
if [[ ! "\${FILE}" =~ ${FILE_REGEX} ]]; then
continue
fi
if (( ${DRY_RUN} )); then
echo " -> Would move \${FILE} to ${TARGET_DIR}/"
else
if [[ ! -d "${TARGET_DIR}" ]]; then
mkdir -p "${TARGET_DIR}"
fi
mv "\${FILE}" "${TARGET_DIR}/"
fi
done
EOF
chmod +x "${TMP_SCRIPT_DIR}/filter.sh" && \
git filter-branch --prune-empty --tree-filter "${TMP_SCRIPT_DIR}/filter.sh" "${REMAINING_ARGS[@]}"
RETURN_CODE="$?"
rm -rf "${TMP_SCRIPT_DIR}"
return "${RETURN_CODE}"
}
main () {
parse_options "$@" && \
filter_git_repository
}
main "$@"
Please register or sign in to comment