Reputation: 21764
I have a large git repository with a folder structure like so:
/A
/B
/C
/D
...
I would like to extract the /A and /B folders into their own repo while maintaining history (I only care about the master branch). Thus, the new repo would look like:
/A
/B
How can I do this? I found git filter-branch which helps with the history re-write, but I'm not sure how to use it for keeping around multiple subdirectories.
Upvotes: 5
Views: 608
Reputation: 3252
git clone initial final
cd final
git filter-branch --tree-filter 'rm -rf <list of folders separated by space>' HEAD
Above commands will remove any folders mentioned in the list but your original commit history will be maintained.
git filter-branch -f --prune-empty
Can then be used to remove any empty commits that might show up from your list of deleted folders.
Alternately, if you have a large repository which has significantly long history, this could take a while. In that case, you could take a slightly different approach -
Start by creating separate repositories for each folder you want to migrate. This can be done using filter-branch command as follows
git filter-branch –prune-empty –subdirectory-filter A/ master
git filter-branch –prune-empty –subdirectory-filter B/ master
Each one will have the contents of the respective folders along with all their history. You can then push these as temp repositories on remote. ( these will also act as checkpoints in case you need to re-do the process)
Next, create your new repository
git clone <remote path> NewRepo
cd NewRepo
# add a readme file
touch Readme.md
git add .
git commit -am "Adding ReadMe file"
You can then merge your individual folders (A and B repos) into NewRepo
# Merge Repo A
git remote add -f A <remote path for A>
git merge -s ours --no-commit A/master
git read-tree --prefix=A/ -u A/master
git commit -m "Merge A into NewRepo"
git remote remove A
# Merge Repo B
git remote add -f B <remote path for B>
git merge -s ours --no-commit B/master
git read-tree --prefix=B/ -u B/master
git commit -m "Merge B into NewRepo"
git remote remove B
Next you can confirm that your origin is set to point to the NewRepo and push code
git remote add origin <remote path for NewRepo>
git push origin master
NewRepo should now contain both the folders and all their history.
Upvotes: 5
Reputation: 404
The filter-branch may take a while to run, but I would try duplicating the repository locally and using it for tests.
git clone repoA repoB
cd repoB
git filter-branch --tree-filter 'rm -rf C D <other files you DON'T want>' HEAD
Again, that may take a long time to run, but I think it will do what you're looking for.
Upvotes: 0