VSTS and Git: Why does squashing my DEV branch whi

2019-04-27 13:22发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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 into dev, the dev branch was 0 behind and x ahead (assume it’s 3 commits ahead here) of mater branch, the commit history for master and dev as below:

...---A----B       master
            \
             C---D---E   dev

Then after creating the PR to merge dev into master and completing the merge, the commit history looks like:

...---A----B-----------F   master
            \         /
             C---D---E  dev

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 make master branch point to the same commit with dev branch (both of them will point to commit E 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 (commit F) behind, and 3 commits (commits C, D and E) ahead by comparing with master branch.