Welcome to MSDN Blogs Sign in | Join | Help


Based upon customer feedback(both external and internal), we have made a number of improvements to the merging experience in Orcas. Below are some of the most significant changes:

1. I described how to handle namespace conflicts while merging in my previous blog (Namespace conflicts while Merging). We have changed the default behavior to automatically perform a baseless merge between items with the same relative name in the trees, which have no merge relationship with any other items in the 2 trees. Therefore in my previous example, 1.txt in trunk will be merged to 1.txt in branch.

merge: $/proj/trunk/1.txt;C13 -> $/proj/branch/1.txt

There will be no conflict during checkin and no need to perform baseless merges at a file level.

2. No conflicts will be filed for baseless merges where the files in the source and the target are the same. We detect this on the server using the file hash, therefore unfortunately for clients which have FIPS enabled this will not work. This should help in reducing the overall number of conflicts filed in baseless merges.

3. Improved the conflict detection algorithm to file conflicts in cases where edits are merged after merging recursive changes (renames, deletes, undeletes) on a parent folder.

4. Enabled merging from a deleted source root item to a related target using the deletionId e.g. The following will be an example for merging a deletion of a file from source to target.

tf merge $/proj/source/a.txt;X20 $/proj/target/a.txt

5. Ability to execute a merge on a child folder and then execute a merge on a parent folder with the merge on the child folder still pending. The server will simply not attempt to remerge the items which have already been merged e.g.

tf merge $/proj/src/folder $/proj/tgt/folder /r /version:C1~C500
.
.
.

tf merge $/proj/src $/proj/tgt /r /version:C1~C500

This will work seamlessly if you have the version range pinned down for botrh merges.

6. Fixed merge bugs, the most notable being:

a. AcceptTheirs does download file at end range of merge when a later changeset has already been merged previously. This occurs when a user merges an edit e.g. changeset 100 (tip) without merging over a previous edit changeset 90. If the user runs a catch up merge to tip and then tries to resolve a conflict as AcceptTheirs it will download the file as of changeset 90 as opposed to changeset 100.


b. User is unable to merge changes to the target branch if there is another deleted branch with the same name and a rename of a file has ocurred in the target. The TF14087: Cannot undelete “insert your file name here” because not all of the deletion is being undeleted error :).

Cheers,

Chandru

 P.S. The usual disclaimer applies that this might change before Orcas ships.

 

In Orcas we have added an additional option to the branch command which gives the user a fast way to create a branch without having to download any of the files or get operations locally. The option is /silent and instructs the server to not send back any get operations. Ofcourse this means you will not see the scrolling list of files and there will be no status until the command completes.

To use it:

D:\temp_dd\ws>tf branch src tgt /silent

D:\temp_dd\ws>tf status
File name Change Local path
--------- ------ --------------------------------------------------------------
$/proj
tgt       branch D:\temp_dd\ws\tgt

$/proj/tgt
1.txt     branch D:\temp_dd\ws\tgt\1.txt

2 change(s)


We have found it very useful for our large devdiv branch creations.

Cheers,

Chandru

P.S. The usual caveat applies that this might change before Orcas ships.

Team Foundation Version Control provides an extensible check-in policy framework to configure and run validation rules before checking in source code. There are many posts that explain how to configure built-in policies as well as install custom ones (refer, for example, http://www.edwardbakker.nl/PermaLink,guid,8600ae36-f9c9-4e1f-b91e-63a469b6346e.aspx and http://www.codeplex.com/VSTSGuidance/Wiki/View.aspx?title=How%20to%20create%20a%20custom%20check-in%20policy&referringTitle=Source%20Control%20Practices%20at%20a%20Glance).

 

I recently helped an internal user with policy compatibility issues between Whidbey and Orcas, and felt that this information may be of interest to others. Check-in policies configured on a Team Project having a mix of Whidbey and Orcas Visual Studio (VS) projects will work cleanly with Whidbey and Orcas clients. The complete information is presented below. A quick recap of how check-in policies function will aid in understanding what follows. Check-in policies are configured on a Team Project basis on the server. The configuration information stored on the server includes the policy type and name of the assembly that implements the policy. But it does not include the path to this assembly on the client machine, which is client specific information. This is obtained from the registry. The Whidbey client locates the assembly path from the 8.0 registry hive (Software\Microsoft\Visual Studio\8.0\Team Foundation\Source Control\Checkin Policies), while the Orcas client locates it from the 9.0 hive.

 

Check-in policies are source compatible but not binary compatible. Hence for Orcas they will have to be recompiled against the 9.0 version of Team Foundation Client (TFC) assemblies. The 8.0 version will only work with Whidbey and the 9.0 version with Orcas. Installing an 8.0 compiled policy with Orcas and trying to load it will result in the error Unable to cast object of type ‘XXXX’ to type ‘Microsoft.TeamFoundation.VersionControl.Client.IPolicyDefinition’. There are several blogs about this VS error, which occurs when an assembly that is being loaded is linked to an older version of a dependent assembly than what VS is linked to.

 

At the same time, even though the policy has to be recompiled with the 9.0 TFC assemblies and installed on the client, it does not have to be configured again on the same Team Project. As stated earlier, the policy configuration information stored on the server includes the policy type and assembly name which must match. But the path to the assemblies on the client will be obtained from the registry. The Whidbey client will locate the 8.0 policy from the 8.0 registry path, while the Orcas client will locate the 9.0 policy from the 9.0 hive.

 

So in summary, (i) recompile Whidbey policies for Orcas, making sure that the assembly name is the same, (ii) install the assembly by copying it to a location different from the 8.0 version and setting the 9.0 registry accordingly.

Team Foundation Server utilizes a Proxy to improve performance by caching copies of source control files. The Proxy is situated in a remote location, local to the developer needing the files but away from the main server. The remote office is typically connected to the main server through a slow link. The Proxy helps each user avoid a costly download of the files to their workspace across the slower connection by caching files. When a requested file is not in the local cache, the file is downloaded by the proxy to its local cache from Team Foundation Server, before returning the files to the client. Refer to http://msdn2.microsoft.com/en-us/library/ms252490(VS.80).aspx  for a more detailed description of the Proxy operation.

In this blog I will describe an improvement that has been implemented in the Orcas Beta 1 release for authenticating users with the proxy in the extranet scenario, where clients and proxy are located in one user domain, while the main server is in a different, non-trusted domain.

Team Foundation Server Proxy uses a pre-authenticated ticket scheme for determining whether a requesting user is authorized to access the requested file. In this scheme, the user’s client contacts the main source control server and if the user is authorized, the client is provided a digitally signed ticket that contains the details of the file being requested. The client then presents this download ticket to the proxy server. The only requirement for clients to receive files from the Proxy is IIS authentication (using NTLM). The proxy treats a valid download ticket from the client as evidence in itself that the client is authorized to receive the file(s).

From the perspective of authentication there are essentially 4 deployment scenarios, tabulated below (we do not distinguish here between multiple trusted domains in the intranet).

Scenario

Domain A

Domain B (non-trusted)

I

Client, proxy, server

 

II

Client

Proxy, server

III

Client, proxy

Server

IV

Client, server

Proxy

 

The proxy adds little value in Scenario IV and this scenario will not be discussed further.  The key restriction until now was that the client used the same credentials to connect to the main server and to the proxy.  This can either be the user’s logon credentials (referred to as default credentials), or alternate credentials supplied in the command line or through the UI prompt when connecting to the main server (referred to as TFS credentials). This works well for scenarios I and II, but not with scenario III. The workaround required until now was to create local accounts on Proxy that matches the alternate TFS credentials. This is a feasible workaround for small shops (say 5-10 users), but introduces maintenance overhead if there are many users at the remote site.

 

DCR Implementation in Orcas release

A possible fix for scenario III is to use the original, default credentials instead of alternate TFS credentials when connecting from TFS client(s) to Proxy.  This has been implemented in Orcas Beta 1. The exact sequence is as follows.

1.       Version Control client file downloader attempts to connect to proxy server with same credentials used to connect to the main server (TFS credentials).

2.       Upon receiving an authentication failure, the proxy download will be retried once with default credentials.

3.       If this succeeds, the session will subsequently always use default credentials when connecting to the proxy.

This exchange happens only once per session, which is the running lifetime for Visual Studio. For command line, it is each invocation of tf.exe. Thus the overhead is minimal for VS or even for large sync operations using command line. We should note that this fix introduces no penalty with scenarios I or II.

As a point of clarification for scenario III, we still require a local account on the main server that matches Proxy service account credentials, for the main server to authenticate the proxy when the latter connects to download files during a cache miss. This workaround is much less annoying than the one described earlier per user.

 Vasu

I thought I would talk about namespace conflicts while merging. A namespace conflict occurs when 2 items try to occupy the same slot in the tree. The main reasons for namespace conflicts during merge are:

- Items with the same name are created in 2 branches without a merge relationship established between them, below is an example which involves a baseless merge.
tf merge /baseless branch branch2 /r (if file.txt was added in branch, it gets branched to branch2)
tf checkin /i
tf merge branch trunk /r (file.text gets branched up to trunk)
tf checkin /i
tf merge branch2 trunk /r (since there is no merge relationship for file.txt in trunk, it gets branched to trunk)

- Another example would be if the same file was added and checked into 2 related branches.

Now that this has occurred how would you go about resolving a namespace conflict:

(assume 1.txt was added and checked in both to trunk and branch):

D:\temp_Dd\ws113>tf merge trunk branch /r 
merge, branch: $/proj/trunk/1.txt;C13 -> $/proj/branch/1.txt

D:\temp_Dd\ws113>tf checkin /i
branch:
Checking in merge, branch: 1.txt
Conflict: The item $/proj/branch/1.txt already exists.

TF10141: No files checked in: resolve the conflicts and try again.

1. If the 2 items are not related, you have the option to keep your changes and rename the file in the branch out of the way. This basically moves the existing item out of the way:

D:\temp_Dd\ws113>tf resolve branch\1.txt /auto:AcceptYoursRenameTheirs /newname:branch\2.txt
Resolved D:\temp_Dd\ws113\branch\1.txt as AcceptYoursRenameTheirs
D:\temp_Dd\ws113\branch:
Getting 2.txt

D:\temp_Dd\ws113>tf status
File name Change        Local path
--------- ------------- -------------------------------------------------------
$/proj/branch
1.txt     merge, branch D:\temp_Dd\ws113\branch\1.txt
2.txt     rename        D:\temp_Dd\ws113\branch\2.txt

2 change(s)

2. If the 2 items are related - your best option would be to undo the change and establish a relationship using /baseless. This will ensure that future merges will proceed smoothly:

D:\temp_Dd\ws113>tf merge trunk branch /r /baseless

I hope to blog soon about some improvements we have made in Orcas to improve the experience around this case.

Chandru

Brian Harry mentioned the new Destroy feature in his TFS roadmap post. I thought I would go into a little bit more detail on how destroy works in Orcas. Please do keep in mind that any of this might change / be removed before Orcas ships - so there are no guarantees.

Destroy gives you the ability to permanently delete version control files/folders from TFS.  It can also be used to destroy the file contents while preserving the change set history. Destroy can only be invoked from the command line and here is the syntax for the command line:

tf destroy [/keephistory] <filespec1>[;<VersionSpec>]  <filespec2 ... filespec3> [/stopat:<VersionSpec>] [/preview] [/StartCleanup] [/i]

All filespecs must be server paths. Local file paths aren’t allowed. Destroy is a very dangerous operation, so removing all possible ambiguity about which items will be destroyed is a good idea. Additionally, the user must posess the AdminProjectRights permission in order to destroy items.

If /keephistory is specified then /stopat becomes optional. /stopat is not allowed if /keephistory is not specified. /stopat is the version including and after that destroy will preserve the file contents for. /stopat defaults to tip (the latest version checked in of an item). The command line does not support version ranges and does support DeletionId version specs (‘X’). When /preview is specified the destroy is not actually committed but the output is displayed any way. /stopat is not allowed to take label or workspace version specs.

TFS stores versioned file content orthogonally from the versioned item histories. Destroy removes all of the non-content data when it is invoked. If you immediately want to have the content garbage collected then you should use the /StartCleanup option to destroy. If /StartCleanup is not specified then the content garbage collection will occur when the TFS database maintenance job runs. The job is scheduled to run one once per day by default.

 

If you have any additional questions about Destroy, feel free to ask. 

Bill

 

Labels are an interesting part of version control system. In version 1 of TFS Version Control, labels do not contain deleted items. 

Here's an example sequence of commands that shows this behavior: 

mkdir dir
echo dir\a.cs > dir\a.cs
echo dir\b.cs > dir\b.cs
tf add dir /r
tf checkin /i
tf delete dir\a.cs
tf checkin /i
tf label label1 $/;T /r
tf lables label1 /format:detailed

The labels command returns this data:

Label  : label1
Scope  : $/
Owner  : bill
Date   : Thursday, March 22, 2007 4:04:34 PM
Comment:

Changeset Item
---------     ------------------
1              $/
2              $/1
3              $/1/dir
3              $/1/dir/b.cs

As you can see $/1/dir/a.cs;X1 is not returned from the label. There is an ambiguity when you compare the items in a label against another version specification (changeset, label, etc...) When you do the comparison it is not possible to determine if an item is missing from the label because it was deleted, or because the item was deliberately excluded.

Merging with a label will not merge file/folder deletes into the target tree.

Here is an example that shows you what I mean:

mkdir src
echo src\a.cs > src\a.cs
echo src\b.cs > src\b.cs
tf add src /r
tf checkin /i
tf branch src tgt
tf checkin /i
tf delete src\a.cs
tf checkin /i
tf label label2 $/;T /r
tf merge src tgt /r /version:Llabel2

The merge command will report correctly that there is nothing to merge because src\a.cs does not exist in label2. 

Team Build runs into the same issue when it computes the changesets that are new with the current build. In order to do this Team Build compares the label for the last successful build and the label for the current buld. A heuristic is used to determine what it treats as deletes when comparing two labels. If an item is in the first label and not in the second label then the version control server is asked if the item's path exists at the latest changeset in a non-deleted state. (VersionControlServer.ServerItemExists) If the item doesn't exist then it is reported as deleted. If the item does exist then it isn't reported as a difference at all. If you currently merge using labels you could implement the same heuristic in order to ensure that deletes get merged. You would probably want to review the suggested deletes manually before checking in the merge.

Bill

Team Foundation Server provides an event notification mechanism via SOAP or email delivery. My post below discusses a SOAP subscription that uses just a TCP socket listener and does not require a web service implementation. This is convenient for client applications such as test automation.

http://blogs.msdn.com/mrod/archive/2006/09/18/761174.aspx

 Vasu Sankaran

 

I thought I would give you an overview of the workspace mapping improvements which Brian Harry mentioned in his TFS roadmap post. Please do keep in mind that any of this might change / be removed before Orcas ships - so there are no guarantees.

History: In DevDiv our branches are enormous ,  a developer typically maps only portions of the tree they need to work on. Upon analysis we determined an average workspace had 100+ mappings. To reduce the performance and maintenance overhead of a large number of mappings we are introducing the following features.

 1. Mappings under Cloaks

This will allow you to cloak a top level folder and map individual folders beneath it.

e.g. Cloak $/proj/privatedirs

      Map   $/proj/privatedirs/johndoe     d:\dd\privatedirs\johndoe

2. One Level Mappings

This will allow you to map all immediate child items of a folder (any sub folders & items will not be mapped locally)

e.g.

$/proj/dir/

$/proj/dir/file1.txt

$/proj/dir/file2.txt

$/proj/dir/dir2

$/proj/dir/dir2/file2.txt

A one level mapping, will end up getting only the items under $/proj/dir (i.e. file1.txt, file2.txt, dir2 will be created - but no items below it will be downloaded)

Map $/proj/dir/*    d:\dd\dir

These features will allow for more complex workspace definition, and allow users to cloak out larger portions of the tree they do not need (improving get performance)

Cheers,

Chandru

 

 

 

 
Page view tracker