Closed oubiwann closed 7 years ago
I ended up using the following script:
#!/bin/bash
# Usage: merge-to-subdir source-repo destination-repo subdir
#
# Merges the history of source-repo into destination-repo as the
# history of the subdirectory subdir.
#
# source-repo can be local or remote.
# destination-repo must be local to the machine.
# subdir can be a relative path, in which case intermediate
# directories are created as necessary.
#
# WARNING: I've only tested it when subdir has not existed within destination-repo.
set -e
function abspath() {
(cd $(dirname $1) && echo $PWD/$(basename $1))
}
from=${1:?from repo not given}
to=$(abspath ${2:?to repo not given})
subdir=${3:?subdir not given}
scratch=$(abspath $(basename $from .git)-scratch)
# Use the name of the subdirectory as the name of the remote when merging
remote=tmp-$subdir
# Create a copy of $from with contents moved to $subdir
rm -rf $scratch
git clone $from $scratch
cd $scratch
git filter-branch -f --prune-empty --tree-filter "
mkdir -p .tmp
mv * .tmp
if [ -f .gitignore ]; then mv .gitignore .tmp; fi
mkdir -p $(dirname $subdir)
mv .tmp $subdir
" -- --all
git gc --aggressive
cd ..
# Merge the copy of $from into $to
cd $to
git remote add $remote $scratch
git fetch $remote
git merge $remote/master
git remote rm $remote
git gc --aggressive
cd ..
# Clean up
rm -rf $scratch
Note that this approach preserved all previous contributions, including those for files that will eventually be deleted.
Part of feature #43