Dislamer: it is probably good to push both repositories to a remote host like GitHub or BitBucket before attempting. I just tried locally and all went well, but no guarantees.
This is a multi-step process, and it may not be a perfect solution. Starting with 2 local repositories, Project A
and Project B
. They may have some overlapping files and both may have some history. The end goal is to merge Project A
into Project B
, keep the history, but completely remove select files from the final repo.
Start by merging Project A
into Project B
. To do this, we will have add Project A
as a remote branch to Project B
.
git remote add old /path/to/project_a # old is the remote name
git fetch old <branch> # fetch history from Project A (can specify single branch after)
git merge old/<branch> # merge the Project A branch into your working tree (most likely master)
Now you will have a merged Project A
and Project B
in Project B
's working tree. You may have merge conflicts to resolve (if so, commit after this).
Next step is to remove our unwanted files (or directories) from this combined repository. git filter-branch
will be used to do this historically. Note: this will rewrite history, so if someone is working off of Project B
there will be major conflicts and is not recommended (instead, just remove the files normally and make an extra commit..this will keep history sane).
git filter-branch --tree-filter 'rm -rf path/to/unwanted/dirs' HEAD
git filter-branch --tree-filter 'rm -f unwanted_file' HEAD
This translates to run this command in every commit of this tree (branch) up until the HEAD
(working copy). You can also specify a range by replacing it HEAD
with a1b2c3...HEAD
. The -r
in the first command is needed to recursively remove files from an unwanted directory. The -f
is needed in both commands to ignore non-existent files (some commits may not have the file you want to remove, since the commits come from 2 repositories).
Finally you can cleanup by removing the link between Project B
and the old Project A
.
git remote rm old # or whatever you named this branch