I'm hoping someone can help me with this as I'm scratching my head to understand what is going on, and if it can be rectified.
I'm currently working on a project in VSTS and using GIT as the code repository. I have the usual MASTER branch, with a DEVELOPMENT branch coming off that. I then create feature branches off the DEVELOPMENT branch.
When we have finished the changes in the feature branch, I create a Pull Request and can successfully merge the changes into the DEV branch. The DEV branch then shows '0' behind and 'x' ahead of MASTER ... which is correct.
The issue comes when we are ready to merge the changes into MASTER. We create a PULL REQUEST to do this and the changes successfully merge into MASTER ... however ... the DEV branch now says that is 1 behind MASTER and still x ahead of MASTER!! Why is DEV 1 behind MASTER? And why is DEV still x ahead of MASTER? After the PULL REQUEST, shouldn't MASTER and DEV be in sync? That is, DEV should be 0 behind, and 0 ahead of MASTER?
There is a very good chance I'm not understanding GIT properly, but could I have some settings in VSTS wrong ... like a branching policy incorrectly set? The only branch policy I have set on MASTER (at this stage) is "Enforce a merge strategy - Squash merge".
Thanks in advance.
Squash merge is the cause for your misunderstanding.
When you squash merge, all the commits of your development branch are squashed into one single commit. This is the reason why DEV is 1 behind master, since it doesn't has the squashed commit. Also DEV is x ahead of master because DEV has x commits which aren't in master.
Ideally you should only squash merge your feature/topic branches, that will give you one commit per feature. You should not squash your dev branch when you merge into master. So you can change the branch policy on master and put that policy in DEV if you want that. My advice is to let your developers decide when to squash or not. When you complete a PR in VSTS, it gives you an option to squash.
Just to add some more visibility to @harshil-lodhi 's (absolutely correct) answer.
Before you create a pull request, the state of the repository looks like this:
If you look at this repository inside the SourceTree tool, it proves the numbers are correct (1 behind, 3 ahead):
When you merge the pull request enforcing squashing of the commits, the state changes to the following (VSTS):
And SourceTree:
The dev branch still has its 3 separate commits, which is why it is 3 commits ahead of master. On the other hand, master has one more commit, squashed changes that arrived from the dev branch during the merging/squashing. As you can see. the squashed commit is not a merge commit - it doesn't have 2 parents. Although the contents of the dev and master branches are the same, they are still different branches for Git.
It’s caused by the manner for VSTS to deal with fast-forward merge. We can illustrate the details by graphs.
After completing PR to merge
feature
branch intodev
, thedev
branch was 0 behind and x ahead (assume it’s 3 commits ahead here) ofmater
branch, the commit history formaster
anddev
as below:Then after creating the PR to merge
dev
intomaster
and completing the merge, the commit history looks like:That’s because VSTS handle fast-forward merge with
--no-ff
option (git merge --no-ff
).For the default manner (
git merge dev
) to deal with fast-forward merge, it will makemaster
branch point to the same commit withdev
branch (both of them will point to commitE
as above example).But for
--no-ff
merge (git merge --no-ff dev
), git will create a new merge commit even it’s fast-forward merge.So
dev
branch shows there are 1 commit (commitF
) behind, and 3 commits (commitsC
,D
andE
) ahead by comparing withmaster
branch.