问题
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:
- The first and obvious one is how I can do this?
- Also for the old repository, what would be the best practice? Just delete the folder and commit the changes, or something else?
回答1:
use git splits
it basically use your same git filter-branch
approach but has an easier interface.
- install git splits. I created it as a git extension, based on jkeating's solution.
- 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
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
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
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
回答2:
Try git subtree split
. This can split up a subfolder and keep the history.
Refer to the man pages on how to use it.
回答3:
I ended using the git filter-branch
approach, also mentioned by Github.
The procedure is the following.
- Clone the repository into a new directory
cd
to the new directoryAssuming that we want to create a new repository containing only
dir0
of branchmaster
the correspondinggit
command should be:git filter-branch --prune-empty --subdirectory-filter dir0 master
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.At the original repository, just remove the directory
dir0
and commit.
回答4:
- 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.
- Yes!
Edit-1
Giving your usecase I would suggest sub-module is the way to do it! You can usegit 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 usinggit clone git://github.com/mudassirazvi/EMPTY_COMMIT
, then apply the patches one by one in order. (You can see the order by givinggitk dir1
orgit 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 usegit rebase -i
to edit those commits to make all commits of "dir1" stand alone.
来源:https://stackoverflow.com/questions/28583470/git-get-a-subfolder-from-a-repository-to-a-new-one-without-losing-history