В Git есть команда git mv, но нет команды git cp.
Чтобы скопировать файл с сохранением истории в Git (например, когда нужно разделить файл на два), можно использоват следующий хак. Например, нужно скопировать файл foo в bar:
git mv foo bar
git commit -n
SAVED=`git rev-parse HEAD`
git reset --hard HEAD^
git mv foo foo-magic
git commit -n
git merge $SAVED # This will generate conflicts
git commit -a -n # Trivially resolved like this
git mv foo-magic foo
git commit -n
В итоге получится два файла с одинаковым содержимым и историей. Дальше можно удалить из них лишее, тем самым, разделив один файл пополам.
ORIG_HEAD
/ \
SAVED ALTERNATE
\ /
MERGED
|
RESTORED
Можно использовать следующий шелл-скрипт git-split.sh:
#!/bin/sh
if [[ $# -ne 2 ]] ; then
echo "Usage: git-split.sh original copy"
exit 0
fi
git mv "$1" "$2"
git commit -n -m "Split history $1 to $2 - rename file to target-name"
REV=`git rev-parse HEAD`
git reset --hard HEAD^
git mv "$1" temp
git commit -n -m "Split history $1 to $2 - rename source-file to temp"
git merge $REV
git commit -a -n -m "Split history $1 to $2 - resolve conflict and keep both files"
git mv temp "$1"
git commit -n -m "Split history $1 to $2 - restore name of source-file"