Retroactive crushing of subtree merge

I integrated the external library into my project using the subtree merge strategy . I did not pass the -squash parameter to 'git merge', so now I have the whole history of the library (which is huge), inflating the repository. How can I retroactively squash a merge?

My situation:

Z--Y--..--B--A \ D---E---F---G master 

I would like to:

  D---E---F---G master 

Where E is a commit containing a merge.

I assume the solution will include 'git rebase', but I'm not sure how to use it properly in this case.

+4
source share
2 answers

Remember that if you already published E or later, write to master on remote, then DO NOT rebase on them, as this will break other code, and you will also have to manually fix your repositories.

Rebase creates new versions, it cannot magically modify existing ones (therefore, it uses SHA1, so you are sure that your commit contains what generated this SHA1 and does not change)

But if you are ready for this, go on to my example.

  • First you need to go back to commit right before merging the library, create a named branch there, say 'lib-squash'
  • git merge --squash library ; git commit
  • git checkout master
  • git rebase -i -p --onto lib-squash <sha1 old merge commit>
  • optional git branch -D library and git branch -d lib-squash

This leaves you with a clean history, but you just rewrote the history, you need to click with the -force flag, and then each person will have to fix their repository:

  • git fetch
  • git checkout master
  • git reset --hard origin/master , assuming you have no other local commits than in the remote repository
  • If you have any local commits, you also need to β€œreset” these commits.

Unfortunately, I did not find an article about canceling historical commits without affecting future commits.

+2
source

Rebase should help you with this. This article should give you enough pointers to sort it.

+1
source

All Articles