Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TFS How does merging work?

I have a release branch (RB, starting at C5) and a changeset on trunk (C10) that I now want to merge onto RB.

The file has changes at C3 (common to both), one in CS 7 on RB, and one in C9 (trunk) and one in C10). So the history for my changed file looks like this:

    RB:       C5 -> C7
Trunk: C3 ->             C9 -> C10

When I merge C10 from trunk to RB, I'd expect to see a merge window showing me C10 | C3 | C7 since C3 is the common ancestor revision and C10 and C7 are the tips of my two branches respectively. However, my merge tool shows me C10 | C9 | C7.

My merge tool is configured to show %1(OriginalFile)|%3(BaseFile)|%2(Modified File), so this tells me TFS chose C9 as the base revision.

This is totally unexpected and completely contrary to the way I'm used to merges working in Mercurial or Git. Did I get something wrong or is TFS trying to drive me nuts with merging?

Is this the default TFS Merge behavior? If so, can you provide insight into why they chose to implement it this way?

I'm using TFS 2008 with VS2010 as a Client.

like image 899
Johannes Rudolph Avatar asked Feb 14 '11 18:02

Johannes Rudolph


People also ask

How does TFS merge work?

Merging allows to combines two different branches into one. Once more source branch and target branch are required and changes are incorporated from source branch into target branch. Merging can be done via TFS Source Control or from the command line using “tf merge” command.

Does Merging affect both branches?

No, merging does only affect one branch.


1 Answers

I had some similar initial struggles with TFS branching and merging (We have dev, integration, and main branches).

Short version is that you cannot merge directly back from a tip to a common ancestor.

So if C3 was branched to C5, then C7 was branched to C9, what the tool is providing makes sense within the context of how TFS works. You essentially need to go from C10/C9 to C7 then from C7 to C3.

To put it a different way with a more concrete example, here's how we handle multi-level branching and merging in our projects.

We start with trunk/main.

We then branch to an integration branch.

We then (and this is key) branch from integration into our individual dev branches so we can work on upcoming releases.

As changes are complete in a dev branch, we first reverse integrate by merging from integration to our dev branch (so we pick up everyone else's changes). We then forward integrate by going from our individual dev branch to the shared integration branch.

Once integration passes QA, we then reverse integrate by merging trunk to integration (just in case there are any hotfixes in main), then forward integrate all of the combined changes in integration down to main.

On release day, we do one last branch from main into a new release branch which we then deploy.

Basically, in TFS you always have to go up and down the branching/merging tree from trunk to limb to branch to leaf - you cannot at any time bypass any step in the branch heirarchy.

Metaphorically, TFS branch and merge is more like as sloth crawling up a tree and slowly down to the end of a branch without ever letting lose it's grip vs. a monkey hopping between branches ;)

Takes a bit of getting used to, but once done (and especially once you're used to the forward integrate/reverse integrate paradigm) it works a treat, especially when you have several folks all doing development and you need to wrap up everyone's changes without having things stomped over.

Hope that helps!

like image 107
Bob Palmer Avatar answered Dec 12 '22 01:12

Bob Palmer