I merged an external library into my project using the subtree merge strategy. I didn't pass the --squash option to 'git merge', so I now have th开发者_开发问答e entire library history (which is huge) bloating the repository. How can I retroactively squash the merge?
My situation is:
Z--Y--..--B--A
\
D---E---F---G master
I would like to get to:
D---E---F---G master
Where E is the commit containing the merge.
I guess the solution will involve 'git rebase' but I'm not sure how to use it properly in this case.
Remember that if you already published E or later commits in master to remote, then DON'T do rebase on them, as this will break other's code and you'll need to manually fix their repositories too.
Rebase creates new revisions, it can't magically modify existing (that's why it uses SHA1, so you're sure that your commit contain what generated this particular SHA1 and is not modified)
But if you're prepared to it, then proceed with my example.
- First you need to go back to commit right before you merged library, create named branch from there, let's say 'lib-squash'
git merge --squash library
;git commit
git checkout master
git rebase -i -p --onto lib-squash <sha1 old merge commit>
- optionally
git branch -D library
andgit branch -d lib-squash
This leaves you with clean history, but you just rewrote history, you need to push with --force flag, and then every person would need to fix their repository:
git fetch
git checkout master
git reset --hard origin/master
, assuming you don't have other local commits than in remote repository- if you have any local commits, you need to "rebase onto" these commits too.
Unfortunately I haven't found article about detaching historical commits without affecting future commits.
Rebase should help you with it. This article should give you enough pointers to sort it out
精彩评论