How can I move a single directory from a git repository to a new repository whilst maintaining the history?

GitGit Submodules

Git Problem Overview


I have inherited a git repository containing multiple projects in separate directories. I'd like to split the repository into new individual repositories, one for each project and then have the master repository contain the projects as submodules. I'd like to do all this whilst maintaining the revision history of the individual projects if possible.

I could clone the repository for each project and remove all the other projects each time, but it there a better way to avoid having the cloned history in each new project repository?

Git Solutions


Solution 1 - Git

You can use git filter-branch to rewrite the history of a project. From the documentation:

> To rewrite the repository to look as > if foodir/ had been its project root, > and discard all other history: > > git filter-branch --subdirectory-filter foodir -- --all

Make several copies of your repo, do that for each subdirectory you want to split out, and you should wind up with what you're looking for.

Solution 2 - Git

To export a folder as a new repository you need:

  1. To clone the repository where the folder you want to export is.

  2. To create a empty repository on your hosting provider as GitHub, to store the exported folder.

  3. Open the cloned repository folder and run this command:

     git subtree push --prefix=YourFolderNameToExport https://github.com/YourUserName/YourNewCleanRepoName master
    

Solution 3 - Git

The point of git is that the history is embodied in each commit by hashing the parent commit. You could "replay" the commits (this is essentially how the svn-importer works) into a new repository and only keeping each sub-project. This, however, would destroy the meaning of the commit hashes. If you have no problem with that then so be it.

In the past I've just cloned it and moved on. This makes things larger but disk space is cheap; my time is expensive.

I also don't know of any tools to splice out a directory. I suppose you could git-log on the directory to find all commits on it then replay the commits with something like git-fast-export?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncideredView Question on Stackoverflow
Solution 1 - GitBrian CampbellView Answer on Stackoverflow
Solution 2 - GituserView Answer on Stackoverflow
Solution 3 - GitColin BurnettView Answer on Stackoverflow