问题
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