git move directory to another repository while keeping the history

I can’t help you with git subtree, but with filter-branch it’s possible.

First you need to create a common repository that will contain both source and destination branches. This can be done by adding a new “remote” beside “origin” and fetching from the new remote.

Use filter-branch on the source branch to rm -rf all directories except dir-to-move. After that you’ll have a commit history that can be cleanly rebased or merged into the destination branch. I think the easiest way is to cherry-pick all non-empty commits from the source branch. The list of these commits can be obtained by running git rev-list --reverse source-branch -- dir-to-move

Of course, if the history of dir-to-move is non-linear (already contains merge commits), then it won’t be preserved by cherry-pick, so git merge can be used instead.

Example create common repo:

cd repo-2
git remote add source ../repo-1
git fetch source

Example filter branch

cd repo-2
git checkout -b source-master source/master
CMD="rm -rf dir1 dir2 dir3 dir5"
git filter-branch --tree-filter "$CMD"

Example cherry-pick into destination master

cd repo-2
git checkout master
git cherry-pick `git rev-list --reverse source-master -- dir-to-move`

Leave a Comment