Partager via


Improved merge conflict handling in TFS2010

Hello,

 It's been a while since my last post - the dust from the RTM release has settled and I hope to get back to blogging regularly. In this post I plan to talk about some of the changes we made to reduce the # of merge conflicts you will get.

1. Rename / Undelete roots are no longer conflicts - in TFS 2005/2008 all renames, undeletes were conservatively marked as conflicts. This is no longer the case. Renames / Undeletes will be merged automatically.

C:\temp_dd\ws\testing>tf rename main\file.cs main\file-rename.cs
main:
file-rename.cs

C:\temp_dd\ws\testing>tf checkin /i
main:
Checking in rename: file-rename.cs

Changeset #66 checked in.

C:\temp_dd\ws\testing>tf merge main feature /r
merge, rename: $/proj/testing/main/file-rename.cs;C66~C66 -> $/proj/testing/feature/file.cs;C65

2. In a previous post I had talked about how a resolution of keep yours / accept merge in 1 direction would result in a conflict in the opposite direction. We have changed the default behavior so these are auto-resolved.

C:\temp_dd\ws\testing>tf merge main feature /r
Conflict (merge, edit): $/proj/testing/main/file-rename.cs;C68~C68 -> $/proj/testing/feature/file-rename.cs;C68

C:\temp_dd\ws\testing>tf resolve /auto:keepyours
Resolved C:\temp_dd\ws\testing\feature\file-rename.cs as KeepYours

C:\temp_dd\ws\testing>tf checkin /i
feature:
Checking in merge: file-rename.cs

Changeset #69 checked in.

C:\temp_dd\ws\testing>tf merge feature main /r
merge, edit: $/proj/testing/feature/file-rename.cs;C68~C69 -> $/proj/testing/main/file-rename.cs;C68

If you want the old behavior, there is a flag to instruct the merge engine to be conservative about resolving such conflicts:

C:\temp_dd\ws\testing>tf merge feature main /r /conservative
Conflict (merge, edit): $/proj/testing/feature/file-rename.cs;C68~C69 -> $/proj/testing/main/file-rename.cs;C68

So that leads to the question, what are the conflict rules for 2010:

a. A file has a change (edit, rename, encoding, delete, undelete) both in the source and target

or

b. The merge is baseless, and you are propagating a change (edit, rename, encoding, delete, undelete)

or

c. You are merging from a point which is not the point of your last merge. An example of this is a cherry pick merge.

C:\temp_dd\ws\testing>echo 44444 >> main\file-rename.cs

C:\temp_dd\ws\testing>tf checkin /i
main:
Checking in edit: file-rename.cs
Changeset #71 checked in.

 C:\temp_dd\ws\testing>echo 5555 >> main\file-rename.cs

C:\temp_dd\ws\testing>tf checkin /i
main:
Checking in edit: file-rename.cs

Changeset #72 checked in.

C:\temp_dd\ws\testing>tf merge main feature /r /version:c72~c72
Conflict (merge, edit): $/proj/testing/main/file-rename.cs;C72~C72 -> $/proj/testing/feature/file-rename.cs;C69

This simple example often throws people off and here is why: The reason is that all content merging in TFS is done on the client, the server only handles simple conflicts, in this case the resolution of the conflict requires creation of new content (i.e. a file without lines 44444 in it and only 5555 in it). The mechanism we have to resolve this is to file a conflict and let the client merge tool handle it.

 Happy Merging,

Chandru