There's now a very detailed article on MSDN describing how to install VSTS on Virtual PCs.
I wrote a post for the Team Foundation blog providing an Overview of Branching, Merging, and Shelving.
Adarsh Khare, who is a tester for the .NET networking classes, has useful blog. Recent posts include the new NetworkInformation namespace that includes things like network availability events and a reference to an MSDN article on running ASMX without IIS.
Someone posted this question recently in the newsgroups.
I have a question concerning promotion processes using Source Control. Due to requirements from Sarbanes-Oxley (SOX), we will need to have tight controls on source code that is being checked into UAT and Production such that it will pass an audit showing that is being tightly controlled by the properly authorized personell. This, of course, is different from the requirements in the normal day-to-day development process.How will/should scenarios such as this be handled?
Doug Neumann, the Hatteras PM, responded with the following.
This is actually a really involved question and the answer ultimately depends on the tool you are using for source control. I'm a program manager for Team Foundation, so let me explain to you how we advocate users do this. Just in case you aren't familiar with Team Foundation, you can read more at http://msdn.microsoft.com/vstudio/teamsystem.With Team Foundation, we advocate that users model promotion levels with branches. Effectively, successive levels of promotion are handled in different branches of the source code. Developers typically do their work in the branch corresponding with the lowest promotion level. Changes are merged to higher levels of promotion when they are ready. Following each promotion, there may be a period of stabilization in the target branch when developers can check in to that branch directly in order to address bugs that weren't caught before promotion. With Team Foundation, we even have the ability to cherry-pick specific bug fixes when merging between branches, so you don't have to take unwanted changes from the source branch, even if they exist in the same file.With Team Foundation, as with VSS, we create branches in the path space of the repository. To the user, the branch operation looks like a copy operation, but we maintain a lot of state about the relationship between files that makes it possible for us to handle merging changes in an intelligent fashion. One nice thing about path-space branching is that we can use normal file system ACLs to manager access rights. Where this comes into play with promotion modeling is that you can lock down each branch so that only authorized users are allowed to check in to them.So to get the SOX compliance you're looking for, we'd advise you to create at least 2 promotion levels. The first would be the dev branch where day to day work is performed. The second is the approved branch where approved changes are merged. You would then lock down that second branch so that only the authorized personnel could check into it. Because your source is in version control, you'll always have the audit trail of who changed what to prove that only authorized people have been making changes in that branch.
[Update] Fixed formatting.
The docs are now on MSDN.
Command Line Reference (Visual Studio Team Foundation)
Command line summary for tf.exe. This was put together by Rob Caron.
You may also want to see the full Team Foundation Version Control Command Line Reference as well.
This is pre-release documentation and is subject to change in future releases.
Command
Usage
Add
tf Add itemspec [lock:none|checkin|checkout] [/type:filetype] [/noprompt] [/recursive]
Branch
tf Branch olditem newitem [/version:versionspec] [/noget] [/lock] [/noprompt] [/recursive]
Branches
tf branches [/s:servername] itemspec
Changeset
tf Changeset [/comment:comment|@commentfile] /s:servername [/notes:(“NoteFieldName”=”NoteFieldValue”|@notefile)] [/noprompt] ([/latest]|changesetnumber)
Checkin
tf checkin [/author:authorname] [/comment:("comment"|@commentfile)] [/noprompt] [/notes:(“Note Name”=”note text”|@notefile)] [/override:reason|@reason] [/recursive] filespec …]
Checkout
tf checkout [/lock:(none|checkin|checkout)] [/recursive] [/type:encoding] itemspec
Delete
tf delete [/lock:(none|checkin|checkout)] [/recursive] itemspec
Difference
tf difference itemspec [/version:versionspec] [/type:filetype] [/format:(visual|unix|ss)] [/ignorespace] [/ignoreeol] [/ignorecase] [/recursive] [/options:"options"]
tf difference itemspec itemspec2 [/type:filetype] [/format:(visual|unix|ss)] [/ignorespace] [/ignoreeol] [/ignorecase] [/recursive] [/options:"options"]
tf difference [/shelveset:shelvesetname;[shelvesetowner]] shelveset_itemspec [/server:serverURL] [/type:filetype] [/format:(visual|unix|ss)] [/ignorespace] [/ignoreeol] [/ignorecase] [/recursive] [/options:"options"]
Dir
tf dir [/s:servername] itemspec [/version:versionspec] [/recursive] [/folders] [/deleted]
Get
tf get itemspec [/version:versionspec] [/all] [/overwrite] [/force] [/preview] [/recursive] [/noprompt]
Help
tf help commandname
History
tf history [/s:servername] itemspec [/version:versionspec] [/stopafter:number] [/recursive] [/user:username] [/format:(brief|detailed)] [/slotmode]
Label
Option Set 1:
tf label [/s:servername] labelname@scope [/owner:ownername] itemspec [/version:versionspec] [/comment:("comment"|@commentfile)] [/child:(replace|merge)] [/recursive]
Option Set 2:
tf label [/s:servername] [/delete] labelname@scope [/owner:ownername] itemspec [/version:versionspec] [/recursive]
Labels
tf labels [/owner:ownername] [/format:(brief|detailed)] [/s:servername] [labelname]
Lock
tf lock itemspec /lock:(none|checkout|checkin) [/workspace:workspacename] [/server:serverURL] [/recursive] [/noprompt]
Merge
tf merge [/recursive] [/force] [/candidate] [/discard] [/version:versionspec] [/lock:none|checkin|checkout] [/preview] [/baseless] [/nosummary] source destination
Merges
tf merges [/s:servername] [source] destination [/recursive]
Permission
tf permission [/allow:(* |perm1[,perm2,…]] [/deny:(* |perm1[,perm2,…])] [/remove:(* |perm1[,perm2,…])] [/inherit:yes|no] [/user:username1[,username2,…]] [/recursive] [/group:groupname1[,groupname2,…]] [/server:servername] itemspec
Properties
tf properties [/recursive] itemspec
Rename
tf rename [/lock:(none|checkout|checkin)] olditem newitem
Resolve
tf Resolve itemspec [auto:(AcceptMerge|AcceptTheirs|AcceptYours)] [/preview] [(/overridetype:overridetype | /converttotype:converttype)] [/recursive]
Shelve
tf shelve [/move] [/replace] [/comment:(@commentfile|"comment")] [/recursive] shelvesetname[;owner] filespec
tf shelve /delete [/server:serverURL] shelvesetname[;owner]
Shelvesets
tf shelvesets [/owner:ownername] [/format:(brief|detailed)] [/server:serverURL] shelvesetname
Status
tf status itemspec [/s:servername] ([/workspace:workspacename[;workspaceowner]] | [/shelveset:shelvesetname[;shelvesetowner]]) [/format:(brief|detailed)] [/recursive] [/user:(*|username)]
Undelete
tf undelete [/noget] [/lock:(none|checkin|checkout)] [/newname:name] [/recursive] itemspec[;deletionID]
Undo
tf undo [/workspace:workspacename[;workspaceowner]] [/s:servername] [/recursive] itemspec
Unlabel
tf unlabel [/s:servername] [/recursive] labelname itemspec
Unshelve
tf unshelve [/move] [shelvesetname[;username]] itemspec
View
tf view [/s:servername] [/console] [/noprompt] itemspec [/version:versionspec]
WorkFold
tf workfold localfolder
tf workfold [/workspace: workspacename]
tf workfold [/s:servername] [/workspace: workspacename] repositoryfolder
tf workfold [/map] [/s:servername] [/workspace: workspacename] repositoryfolder|localfolder
tf workfold /unmap [/s:servername] [/workspace: workspacename] [/recursive] (repositoryfolder|localfolder)
tf workfold /cloak (repositoryfolder|localfolder) [/workspace: workspacename] [/s:servername]
tf workfold /decloak (repositoryfolder|localfolder) [/workspace: workspacename] [/s:servername]
Workspace
Option Set #1--Create New Workspace:
tf workspace /new [/noprompt] [/template:workspacename[;workspaceowner]]
[/computer:computername] [/comment:(“comment”|@commentfile)] [/s:servername]
Option Set #2--Delete Workspace:
tf workspace /delete [/s:servername] workspacename[;workspaceowner]
Option Set #3--Edit Existing Workspace:
tf workspace [/s:servername] [/comment:comment] [/newname:workspacename] workspacename[;workspaceowner]
Workspaces
tf workspaces [/owner:ownername] [/computer:computername] [/s:servername] [/format:(brief|detailed)] [/updateUserName:oldUserName] [/updateComputerName:oldComputerName] workspacename
tf workspaces /remove:(*|workspace1[,workspace2,...]) /server:(*|server)
Tim, who worked on IE among other things in his career at Microsoft and now works on Hatteras, showed me tonight that you can set the home page in Internet Explorer by dragging the link from the Address bar to the Home icon on the toolbar. I had no idea. I burst out laughing. It's a neat trick once you know it, but it never occurred to me. Perhaps it's because I don't change my home page.
Someone's going to tell me that it's obvious, and I'm the only who didn't know about it. Right. It's an example of something that's really convenient, if you need that sort of thing, but not very discoverable (unless you often drag things over toolbar buttons just to see what happens).
Last summer I wrote several posts on using HttpWebRequest and SOAP proxies. Recently I was working on code that needed to handle requests that could take a really long time for the server to process. The client would give up and close the network connection long before the request completed.
The code had tried to control that using the HttpWebRequest.Timeout property. That helped, but it didn't solve the problem. Without changing the Timeout property, the client gave up after 100 seconds, which is the default value for that property as stated in the docs. The Timeout property was set to infinite, but the client gave up after five minutes. Below is the doc for the Timeout property.
Return Value The number of milliseconds to wait before the request times out. The default is 100000 milliseconds (100 seconds). Remarks Timeout is the number of milliseconds that a synchronous request made with the GetResponse method waits for a response, and the GetRequestStream method waits for a stream. If the resource is not returned within the time-out period, the request throws a WebException with the Status property set to Timeout. The Timeout property has no effect on asynchronous requests made with the BeginGetResponse or BeginGetRequestStream methods. Caution In the case of asynchronous requests, it is the responsibility of the client application to implement its own timeout mechanism. Refer to the example in the BeginGetResponse method. To specify the amount of time to wait before a read or write operation times out, use the ReadWriteTimeout property.
Return Value
The number of milliseconds to wait before the request times out. The default is 100000 milliseconds (100 seconds).
Remarks
Timeout is the number of milliseconds that a synchronous request made with the GetResponse method waits for a response, and the GetRequestStream method waits for a stream. If the resource is not returned within the time-out period, the request throws a WebException with the Status property set to Timeout.
The Timeout property has no effect on asynchronous requests made with the BeginGetResponse or BeginGetRequestStream methods.
To specify the amount of time to wait before a read or write operation times out, use the ReadWriteTimeout property.
At the end of that, notice that they mention another timeout value, the HttpWebRequest.ReadWriteTimeout property. Here's the doc for that.
The number of milliseconds before the writing or reading times out. Its default value is 300000 milliseconds (5 minutes). Remarks
The number of milliseconds before the writing or reading times out. Its default value is 300000 milliseconds (5 minutes).
The ReadWriteTimeout is used when writing to the stream returned by GetRequestStream or reading from the stream returned by GetResponseStream. Specifically, the ReadWriteTimeout property controls the time-out for the Read method, which is used to read the stream returned by the GetResponseStream method, and for the Write method, which is used to write to the stream returned by GetRequestStream method. To specify the amount of time to wait for the request to complete, use the Timeout property.
The ReadWriteTimeout is used when writing to the stream returned by GetRequestStream or reading from the stream returned by GetResponseStream.
Specifically, the ReadWriteTimeout property controls the time-out for the Read method, which is used to read the stream returned by the GetResponseStream method, and for the Write method, which is used to write to the stream returned by GetRequestStream method.
To specify the amount of time to wait for the request to complete, use the Timeout property.
Well, there's the five minute timeout. If you want to wait for a long request, which is greater than five minutes for the HttpWebRequest, you need to set both properties. Using the information in the post from the summer, you can add code to your override of GetWebRequest() in your SOAP proxy to set the timeout to an hour, for example, using request.Timeout = 3600 * 1000 and request.ReadWriteTimeout = 3600 * 1000.
You may also notice that the Timeout property doesn't apply to asynchronous calls that use the Begin/End call pattern. For those, only the ReadWriteTimeout applies.