如何在保持历史记录的同时将单个目录从 git 存储库移动到新的存储库?

我继承了一个 git 存储库,它在单独的目录中包含多个项目。我希望将存储库分割成新的单独存储库,每个存储库对应一个项目,然后让主存储库将项目作为子模块包含在内。如果可能的话,我想在做这些的同时保持每个项目的修订历史。

我可以为每个项目克隆存储库并每次删除所有其他项目,但是有没有更好的方法来避免在每个新的项目存储库中出现克隆的历史?

21190 次浏览

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?

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.

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