Split a Git Repository Into Two

柔情痞子 提交于 2019-12-12 01:53:15

问题


I have a git repository with several branches, and I would like to split it in two repositories.

Imagine that I list all commits made to that repository, and the result is something like:

Commit #1 to branch master
Commit #2 to branch master
Commit #3 to branch fixing_bugs
Commit #4 to branch master
Commit #5 to branch fixing_bugs
Commit #6 to branch master
Commit #7 to branch adding_sexy_french_girls_to_the_code
Commit #8 to branch adding_sexy_french_girls_to_the_code
Commit #9 to branch master

So in total, this repository has 3 branches: master, fixing_bugs and adding_sexy_french_girls_to_the_code.

Now I want to split this repository in two, using commit #6. So I would have two repositories like the following:

Repository 1

Commit #1 to branch master
Commit #2 to branch master
Commit #3 to branch fixing_bugs
Commit #4 to branch master
Commit #5 to branch fixing_bugs

Having branches master, fixing_bugs.

Repository 2

Commit #6 to branch master
Commit #7 to branch adding_sexy_french_girls_to_the_code
Commit #8 to branch adding_sexy_french_girls_to_the_code
Commit #9 to branch master

Having branches master, adding_sexy_french_girls_to_the_code.

I understand this may be technically challenging, but I believe it is not impossible to do with Git (le hope).

How can I do this?

Thank you.


回答1:


Create your 2nd branch from your master with

git checkout -b <your_new_branch>

I would suggest you to start with the same code in each branch and the rewrite the history by rebasing with :

git rebase HEAD~9 -i

And then you can easily delete the lines you want for each branch.

Because you are rewriting your history you will have to push force the changes :

git push origin <your_branch> --force

[UPDATE] I saw the last comments then you will have to squash your commits on repository 2 in order to replace each pick by s for squash with your last commit #6.

After git rebase HEAD~9 -i on Repository 1:

pick #1 to branch master
pick #2 to branch master
pick #3 to branch fixing_bugs
pick #4 to branch master
pick #5 to branch fixing_bugs
pick #6 to branch master
pick #7 to branch adding_sexy_french_girls_to_the_code
pick #8 to branch adding_sexy_french_girls_to_the_code
pick #9 to branch master 

you should have :

pick #1 to branch master
pick #2 to branch master
pick #3 to branch fixing_bugs
pick #4 to branch master
pick #5 to branch fixing_bugs

(type dd on vim to delete the lines)

After git rebase HEAD~9 -i on Repository 2:

pick #1 to branch master
pick #2 to branch master
pick #3 to branch fixing_bugs
pick #4 to branch master
pick #5 to branch fixing_bugs
pick #6 to branch master
pick #7 to branch adding_sexy_french_girls_to_the_code
pick #8 to branch adding_sexy_french_girls_to_the_code
pick #9 to branch master 

you should have :

s #1 to branch master
s #2 to branch master
s #3 to branch fixing_bugs
s #4 to branch master
s #5 to branch fixing_bugs
pick #6 to branch master
pick #7 to branch adding_sexy_french_girls_to_the_code
pick #8 to branch adding_sexy_french_girls_to_the_code
pick #9 to branch master 

(edit the lines and the first 5 lines will be squashed with #6)




回答2:


You can make use of git format-patch and git am to copy commits from your existing repository to the new one, follow by a git reset to remove the copied commits from the existing repository.

Try these commands to copy the commits to the new repository:

$ cd /path/to/new_repo_folder # don't forget to run git init if this is a new folder
$ git --git-dir=/path/to/existing_repo_folder/.git format-patch --stdout sha1_of_commit5..sha1_of_commit_9 | git am

So essentially, the git format-patch command creates one patch file for each of your commit, from commit 6 to commit 9. If the --stdout option is not provided, these patch files will be saved in your existing_repo_folder. Subsequently, the git am command applies the history of commit 6 to commit 9 in your new_repo_folder. Now when you run git log in your new_repo_folder, you will see the history of commit 6 to 9.

Finally, if commit 9 is your HEAD, then you can run git reset --hard HEAD~3 in your existing_repo_folder to set the position of HEAD to commit 5, which is 3 commits before, and that's what that ~3 represents.

Of course, you are essentially rewriting the history of your repository. If you are sharing your codes with other people, make sure you have their consensus. Otherwise, your next git push -f is going to cause everyone a lot of grief.



来源:https://stackoverflow.com/questions/27849797/split-a-git-repository-into-two

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!