Home > OS >  Squash merging in git keeps including previously-merged branches
Squash merging in git keeps including previously-merged branches

Time:03-10

I'm using Github, with branches for development, live and various feature & bug branches.

When I merge a feature or bugfix into development, I typically do a squash merge (usually through the GH website, although it's equivalent to git merge --squash branchname).

Then when I update live from development, I squash merge dev into live.

The benefit of this is the commit message is automatically populated with the list of commits (which, because these were also squashed, is a list of PRs).

The problem I'm having is that when even immediately after merge dev into live, the live branch is still listed as behind development - so next time I merge the two, it includes commits that I know are already merged.

I think what I'm doing is the equivalent to:

  1. git checkout feature/1 & make change
  2. git checkout development
  3. git merge --squash feature/1
  4. git commit
  5. git checkout live
  6. git merge --squash development (adds one commit to live)
  7. git commit
  8. git checkout feature/2 & make change
  9. git checkout development
  10. git merge --squash feature/2
  11. git commit
  12. git checkout live
  13. git merge --squash development (adds two commits to live - both feature/1 and feature/2)

Why is it not 'completing' the merge and drawing a line under it after step 6?

CodePudding user response:

A "squash merge" is not really a merge. It essentially says "create a patch from these changes, and apply that patch to the target branch". Importantly, it does not record any relationship with the original commits.

So, as far as git is concerned, your repository contains three completely unrelated commits:

  • The original commit on feature/1 (possibly garbage collected if you delete that branch)
  • The commit created on development with your first "squash merge"
  • The commit created on live with your next "squash merge"

As a general rule, you shouldn't carry on using a branch after you've "squash merged" the changes from it - the history on it now represents an "alternative reality" which will never match the target branch. This is probably fine for the original feature branch - you can delete it once it's merged. For development, you would have to delete it and then recreate it from live; or, equivalently, hard reset it to point at the same commit as live.

The straight-forward solution is just not to use a squash merge from development to live. Either use a true merge (create a merge commit, which records the relationship between the merged commits), or a fast-forward merge (re-point live at the existing commit in development, without creating any new commits at all).

  • Related