I recently needed to extract a feature from a project to its own repo so I could publish as a standalone library:
# from
/some-project/src/some-folder/some-feature/*
# to
/some-package/src/*Additionally, I wanted to retain the history so the new repo would show the full development process.
The Git command to accomplish this would have been filter-branch but it has been depreciated in favour of a Python addon to Git called git filter-repo.
The addon did exactly what I wanted, but took quite a lot of experimentation to crack (mainly because of moving from src to src) so I've outlined the process and steps below so you can see how it is done.
The addon requires Git 2.22.0 as a minimum, so check your version and upgrade if needs be:
git --versionThen install the addon. I found the easiest way was via the Python package installer:
pip3 install git-filter-repoBefore looking the code, let's look at the steps the code takes.
- clone the repo that contains the feature to a new folder
- remove the origin to prevent accidentally changing the original repo
- optionally checkout a branch if you need to
- run
git filter-repoto:- filter the original repo to the feature folder
- reparent the folder to a temp root folder
tmp(because from and to folders are both namedsrc) - rename the temp folder to
src - use the
forceflag because we removed the origin
- optionally rename any checked out branch if you need to
- optionally delete all tags
Here is the code using placeholders so you can understand how it works:
git clone <repo_url> <package_name>
cd <package_name>
git remote rm origin
git checkout <branch name> # optional
git filter-repo \
--path <feature_path> \
--to-subdirectory-filter tmp \
--path-rename tmp/<feature_path>:src \
--force
git branch -m master # optional
git tag | xargs git tag -d #optionalThings to note:
- the folder names
tmpandsrcshould be changed if you need to (because of conflicts, or you want a different structure) - the rename format is
old_name:new_nameso feel free to change this if your use case is different - the slashes allow the code to be written using multiple lines
This is the same code using concrete examples so you can see how it should look:
git clone https://github.com/some-user/some-project.git some-package
cd some-package
git remote rm origin
git checkout some-branch # optional
git filter-repo \
--path src/some-folder/some-feature \
--to-subdirectory-filter tmp \
--path-rename tmp/src/some-folder/some-feature:src \
--force
git branch -m master # optional
git tag | xargs git tag -d #optionalYou should now have a brand new repo with full commit history and a folder structure like so:
+- some-package
+- src
+- *
Add your readmes, bundlers, etc. then you're done!