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:
git checkout feature/1
& make changegit checkout development
git merge --squash feature/1
git commit
git checkout live
git merge --squash development
(adds one commit to live)git commit
git checkout feature/2
& make changegit checkout development
git merge --squash feature/2
git commit
git checkout live
git merge --squash development
(adds two commits to live - bothfeature/1
andfeature/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).