Question

This question is very related to git rebase interactive: squash merge commits together.

Suppose you are writing a new feature for a certain project. You start from a certain branch, say devel, and you build a branch for your feature, feature/X. From time to time you also find some issues in the project, so you decide to build a second branch, called fixes, starting from devel.

Since you need to apply the fixes as feature/X goes on, you keep doing git merge fixes from time to time, so you end up in the following situation:

      a --- b --- M --- c --- M --- d ---- e --- M (feature)
     /           /           /                  /
    /           /           /                  /
devel ----- fix1 ------ fix2 ------------- fix3 (fixes)

Since this was never pushed (so I don't break anyone else's history), I would like to factorize together all the merges into one, obtaining the following:

      a ---------------------- M --- b --- c --- d --- e (feature)
     /                        /
    /                        /
devel -- fix1 -- fix2 -- fix3 (fixes)

A way of obtaining this result would be

git co -b feature2 devel
git merge --no-ff fixes
git rebase featur2 feature

This actually does the job, but forces me to create a further branch feature2, which later will appear in the commit message of the merge. Besides, try doing it when you are working on more than two branches!

Is there a more elegant way of doing this? It seems an operation which is worth a convenient command, so I assume there's some shortcut.

Thanks for your help

Was it helpful?

Solution

You probably want to use the --preserve-merges option of git rebase --interactive, reorder the commits so the merges are first, and then squash all the merges together. If I were you, I would do two rebases, one to reorder, and another one to squash, that way it would be simpler to resolve the conflicts.

However, your solution using 'feature2' seems good enough, you can edit the merge commit message, so the name 'feature2' is not a problem, and also, you don't need to create a branch, you can work on a detached head:

git checkout devel^0
git merge --no-ff --edit fixes
git rebase HEAD feature

OTHER TIPS

If you can live with a slightly different history, namely

                               + --- a' --- b' --- c' --- d' --- e' (feature)
                              /
                             /
devel -- fix1 -- fix2 -- fix3 (fixes)

then you can do it in a single command.

$ git rebase fixes feature

Is there something special about your history that makes you want to keep the parent links from the merge commits on feature when that pedigree is already present in fixes?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top