Sometimes you’ve been working on a repository and you realize that you want to extract some of its files into a separate repository, e.g. in order to separate the development of one submodule from the main library’s. Of course you could just move the files out of one repository and into another, but if you want to have a clean development history, you’ll want to retain all your commits, and you’ll also want to remove any commits that don’t pertain to the files in your new repository. Here’s how to extract the files in question into a repository of their own while preserving any commits that have touched them and discarding all commits that haven’t.
It’s pretty simple, so I’ll just express it in commented code:
# You want to keep your old repository, so make a clone of the repository # you want to modify $ git clone path/to/my/repo.git # Enter repo $ cd repo # In our scenario we only want to retain files in $DIR_TO_KEEP $ git filter-branch --prune-empty --subdirectory-filter $DIR_TO_KEEP -- --all # Don't forget to tell the repository to not track its old origin, because # that's not its actual origin any more $ git remote rm origin
After you’ve done this, the directory “repo“ will contain only the files in the directory you wanted to keep. All commits that involved them will still be there, and any that did not will no longer be in the repository.
Your “.git“ folder will still be a little bloated with backup files, but they’ve never bugged me. If you want to, there are some black magic commands that will let you remove them, but a much better solution is to just make a clone of the new repository you just made. The clone won’t contain the bloat files, and when you’re done you can delete its origin and be done with it.