Git: Get a subfolder from a repository to a new on

2019-05-20 16:04发布

I have a git repository of an application with multiple branches. The source tree consists of several directories. E.g:

main_folder
|--> .git
|--> dir0
|--> dir1
|--> dir2

Unfortunately, from the beginning of the development I didn't use git-submodules nor git-subtree. Now I want to move one of the directories, e.g dir0 to a new repository as a new stand-alone application, Of course if possible, I want to keep both history and branches of the corresponding directory.

So I have two questions:

  1. The first and obvious one is how I can do this?
  2. Also for the old repository, what would be the best practice? Just delete the folder and commit the changes, or something else?

4条回答
Fickle 薄情
2楼-- · 2019-05-20 16:31

I ended using the git filter-branch approach, also mentioned by Github.

The procedure is the following.

  1. Clone the repository into a new directory
  2. cd to the new directory
  3. Assuming that we want to create a new repository containing only dir0 of branch master the corresponding git command should be:

    git filter-branch --prune-empty --subdirectory-filter dir0 master

  4. This will remove all other files and directories except dir0. Furthermore, it will remove commits that were not related with 'dir0', which is very handy.

  5. At the original repository, just remove the directory dir0 and commit.

查看更多
Melony?
3楼-- · 2019-05-20 16:32
  1. Yes it is definitely possible!
    However having the history related to dir0 in the new repository is not possible (or not easy). However the history will be there in the main project.

What you can do!
a. Delete dir1 and commit.
b. Create a new repository for dir1.
c. Add it as a sub-module to the main project and it will be available for you as a sub-module.

  1. Yes!
Edit-1
Giving your usecase I would suggest sub-module is the way to do it! You can use git log --pretty="%H" dir-1 | xargs -n 1 git format-patch -1 to create patches of commits that make changes to your "stand-alone application" in dir-1.

Now create a new repository with an initial repository with an empty-commit. You can clone something like it using git clone git://github.com/mudassirazvi/EMPTY_COMMIT, then apply the patches one by one in order. (You can see the order by giving gitk dir1 or git log --oneline dir1.
Now that your repo is ready with history, add it as a sub-module

PS: This is straight-forward if your commits don't multiple dirs in same commit. If any of the commits do so then use git rebase -i to edit those commits to make all commits of "dir1" stand alone.
查看更多
4楼-- · 2019-05-20 16:36

use git splits

it basically use your same git filter-branch approach but has an easier interface.

  1. install git splits. I created it as a git extension, based on jkeating's solution.
  2. Split the directories into a local branch #change into your repo's directory cd /path/to/repo #checkout the branch git checkout MyOldBranch #split directory or directories into new branch git splits -b MyNewBranch dir1 dir2 dir2...

Stop here (you're done) if all you want is the directories copied with their history to the new MyNewBranch branch.


If you want the new branch pushed to a standalone repo

  1. Create an empty repo somewhere. We'll assume we've created an empty repo called new_repo on GitHub that has path : git@github.com:simpliwp/new_repo.git

  2. Push to the new repo. #add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_new_repo git@github.com:simpliwp/new_repo.git #push the branch to the new repo's master branch git push origin_new_repo new_repo:master

  3. Clone the newly created remote repo into a new local directory
    #change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone git@github.com:simpliwp/new_repo.git

查看更多
地球回转人心会变
5楼-- · 2019-05-20 16:43

Try git subtree split. This can split up a subfolder and keep the history.

Refer to the man pages on how to use it.

查看更多
登录 后发表回答