You're posting a screenshot of the 3-way merge tool - and I suspect you're attributing to many smarts to it. TFS uses any 3-way merge tool for conflict resolution - by default, it includes the one pictured, however you can configure it to use any 3-way merge tool of your choice.
When a conflict is detected by TFS (in this case, a merge conflict, where the files were edited in both branches and then merged), it will attempt to automerge the contents of the files. If an automerge is impossible, it will require you to use the configured 3-way merge tool to resolve the conflict. TFS simply hands that tool 3 paths: "source" (the file in the branch that is the source of the merge), "target" (the file in the branch that is the target of the merge) and the "base" or common ancestor.
The common ancestor is the last version of the file that was merged between the two branches. If no merge has been performed, the common ancestor is the changeset that the file was branched at. This will remain the case until the first time you merge changes from the source to the target. For example, consider $/Main/A.txt
is branched to $/Branch/A.txt
at changeset 2. If an edit occurs on $/Main/A.txt
(as changeset 3), and an edit occurs on $/Branch/A.txt
(as changeset 4) then when you try to merge $/Branch
to $/Main
, you will have a merge conflict on A.txt
. The common ancestor in this case will be changeset 2 (the version that was branched.)
If you were to then resolve that conflict in your merge tool and check in the result (as changeset 5), then the next time you merge from $/Branch
to $/Main
, the common ancestor of A.txt
will be changeset 5. (Indeed, if you invoke "compare source to base" or "compare target to base" during TFS conflict resolution, you should be able to see the common ancestor as well as its version information.)
In any case, once the merge tool is invoked, it's ultimately the tool's responsibility to prompt you to deal with those changes. The workflow is tool-dependent, but a typical merge tool will compare the files line-by-line and will identify each line as one of the following:
- Unchanged: lines that are unchanged in the source and target from the ancestor
- Common: lines that have been changed from the common ancestor, but identically so
- Conflicting: lines that have been changed in both the source and target and have different content
- Source only: lines that have only changed in the source (the target is identical to the common ancestor)
- Target only: lines that have only changed in the target (the source is identical to the common ancestor)
If there exist no conflicting lines, then an "automerge" can be performed, meaning that the common ancestor is modified by taking the source-only lines from the source, the target-only lines from the target and the common lines from either file to produce the merge output. (TFS will offer this as the "automerge" option, if it's possible.)
Note that just because an automerge is possible (and typically works in practice) that it's exactly as naive as taking lines and no syntax checking is performed so it's possible that your automerged output is not really what you want.
Some 3-way merge tools may offer a mode in which they do a partial automerge - either by default upon opening or after some interaction - taking the common, source-only and target-only lines and then requiring you to resolve the conflicts manually.
The merge tool in your screen shot is the default tool bundled with Visual Studio ALM. The tool in TFS 2012 is significantly improved over that version. Regardless, you may have a better experience with a third-party merge tool.
Note that despite the labels, the merge tool doesn't actually have any idea which file is newer chronologically. (TFS provides the labels to the merge tool to provide you some context about those files, the merge tool just treats them as opaque strings.) Nor is "newer chronologically" necessarily the best merge strategy in all branching strategies. (I work on a team that uses a feature branch strategy - my feature branch has a relatively high velocity and I merge in changes from a main branch that takes well-tested changes from all the feature branches at a comparatively slower cadence. In this case, chronology is fairly unimportant and I need to merge my conflicts regardless.