In this brief guide I'll show you how to copy one directory from one repository to another with the hisotry for it intact.
If you are unsure what you are doing then work on clean clones of your source and target repositories.
Let's get the terminology straight now. We will be going from this state:
repo-from
tasty-directory
repo-to
To this state:
repo-from
tasty-directory
repo-to
tasty-directory
Notice that the repositories are on the same directory level.
cd repo-from
git checkout -b source
We are checking in to a new branch because the stuff we are going to do destroys the branch you are currently on. Also, the name of the branch you are checking into will show up in the merge commit.
git filter-branch --prune-empty --subdirectory-filter tasty-directory --
Now we have the whole contents of tasty-directory
in our root directory. You could stop here and just merge te branch in if you want to move the directory to it's own subdirectory. In our case we want to keep the structure intact so we have to reshape the history a bit to suit our needs.
git filter-branch --prune-empty --tree-filter '
if [[ ! -e tasty-directory ]]; then
mkdir -p tasty-directory
git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files tasty-directory
fi' -f
Note that we had to force this command because refs/original/
keeps the state of our branch from before the first filter-branch
.
Now you should see a nice subsection of your repositories history that's concerning only the tasty-directory
.
cd ../repo-to
git remote add repo-from ../repo-from
git fetch repo-from
Now we have access to our shaped branch and all of it's history fetched. All there's left is to merge, push and forget.
git merge repo-from/source
git push
git remote rm repo-from
Sources: