Reputation: 32567
I would like to move several directories from one git project into another one preserving their histories. The problem is, all the examples I'm seeing seem to be showing how to do extract a directory into it's own git project, preserving the history using git filter-branch
. Is it possible to move these directories from one repository to another, keeping their history, if the destination repository already has other versioned files (not conflicting with the ones to be moved in any way)...?
Could somebody please show me an example of how to do this? Thanks!
Upvotes: 7
Views: 2750
Reputation: 3238
You can do this with git subtree split
and git subtree add/merge
. Say your source repository is at ~/source and you want to move ~/source/subdir into ~/target at some (possibly the same) location in that git repository:
cd ~/source
git subtree split -P subdir -b split/subdir
cd ~/target
git remote add source ../source
git fetch source split/subdir
git subtree add source/split/subdir -P new_subdir
Later on, if the source has updated stuff you can do the exact same steps again except the final step, which becomes git subtree merge
rather than git subtree add
(with the same parameters).
The split and add/merge command don't need to be used together. You can merge in a whole repository that wasn't first split, and you can also just take the split branch and turn it into a repository, by cloning from that branch:
cd ~
git clone source/ -b split/subdir subdir
cd subdir
g remote add [email protected]/Me/MyNewProject
etc.
Upvotes: 0
Reputation: 32567
Answering my own question with this little script I knocked up in bash (make sure you read it first and have backed up your files):
#!/bin/bash
gitURL=$1
project=$2
srcProjectBaseDir=$3
destProjectBaseDir=$4
# Remove stale checkouts in order to do a clean clone
rm -rf ${srcProjectBaseDir}
git clone --no-hardlinks $gitURL ${srcProjectBaseDir}
cd ${srcProjectBaseDir}
git remote rm origin
# These make sure your extracted module is called as the directory's name.
# If this is of no interest to you, comment out these three lines and you
# should be alright.
mkdir temp
git add temp
git mv ${project}/ temp/
git commit -m "Refactoring: Isolated files for filter-branch."
git filter-branch --subdirectory-filter temp HEAD
git add .
git commit -m "Refactoring: Filter branched."
if [ ! -d ${destProjectBaseDir} ]; then
mkdir ${destProjectBaseDir}
cd ${destProjectBaseDir}
git init
cd ..
fi
cd ${destProjectBaseDir}
git remote add repositoryAbranch ${srcProjectBaseDir}
git pull repositoryAbranch master
git remote rm repositoryAbranch
This script is based on most of the instructions seen here (with a few additions).
Upvotes: 1