Search code examples
gitgit-mergegit-filter-branchgit-squash

Rewriting git history to flatten merge commits


I am moving several related projects into a monorepo, preserving every project's history.

Each of the projects in question had its own repo. Also, each project's development relied heavily on --no-ff merges for reintegration of topic branches into the master branch.

I have experimented with shopsys/monorepo-tools and have succeeded in producing a monorepo with joined histories.

I have also found out that most of the time the topic branches were rather long and contained histories of initial implementation, review fixes, and sometimes master -> topic merges. Naturally, it seems that this info is sort of irrelevant – only changes that made it into master really matter.

So I have been considering rewriting the histories of these projects before merging them all into one repo. I want to achieve rewriting history from this state:

...
|
* Merge branch 'feature/XYZ'
|\
| * feature/XYZ#3 Review fixes part 2
| * feature/XYZ#2 Review fixes
| * feature/XYZ#1 Hack, hack, hack 
|/
* Initial commit

To this state:

...
|
* squashed: feature/XYZ#1 + feature/XYZ#2 + feature/XYZ#3 
|
* Initial commit

I want to repeat this for every merge in history. I think I have to use git filter-branch, but I can't quite wrap my head around its multiple options yet, so I'd be really grateful if someone could nudge me in the right direction.


Solution

  • I would start by doing a specific branch to do this preserving the original state (just in case :) ) then use git rebase :

    # git checkout -b trying_jo_solution
    # git rebase -i <Initial comit sha or tag>
    

    will show:

    pick 11111 Initial commit
    pick 22222 feature/XYZ#1 Hack, hack, hack
    pick 33333 feature/XYZ#2 Review fixes
    pick 44444 feature/XYZ#3 Review fixes part 2
    pick 55555 Merge branch 'feature/XYZ'
    

    change to:

    pick 11111 Initial commit
    r 22222 feature/XYZ#1 Hack, hack, hack
    f 33333 feature/XYZ#2 Review fixes
    f 44444 feature/XYZ#3 Review fixes part 2
    f 55555 Merge branch 'feature/XYZ'
    

    then you will have the chance to reword the comment (on 22222)

    to : squashed: feature/XYZ#1 + feature/XYZ#2 + feature/XYZ#3

    done ! check it look like wat you want

    then you just have to change branch master position

    #git branch -f master
    #git push -f origin master