PSS #3: Using PS to help get a list of changes from TFS

My PowerShell Snippet this time comes from a little frustration I had with TFS this week.  I wanted to find a list of all the files that had changed within a branch.  Through the UI I couldn’t find out how to get that list easily.  I could go to the top level folder in the source control window for the project I was interested in and get the history, but it would show me a list of all the changesets.  To get the actual files modified I would have had to open each changeset and get the list of files.  This would have been tedious since I would have had to go through MANY changesets (that’s what checking in changes often will get you ;) ).

Mike Shields (resident TFS guru at the client I’m at) suggested looking at the command line tf.exe.  So, since the GUI makes you weak (and apparently can’t do the task anyway) I switched to the command line tool and was able to pull the following command line together:

tf history *.* /noprompt /format:detailed /recursive

Note that I ran this from the VS 2008 Command Prompt tool so that the TF executable was in the path.  I added the /noprompt so that the results would be output to the console.  If you don’t do that then the actual window will appear (which seems counter-intuitive that it is an opt-out model to not show a window when a command is called from the command line, shouldn’t it be an opt-in model instead?).  I also had to include the /recursive switch and set the /format parameter to detailed.  Only the detailed format will show you the list of changed files, otherwise you get just the changeset name and comments.

This produced somewhat of what I wanted, but there was a lot of extraneous text that didn’t need to be included.  Also, it got ALL the history (which I expected), but that included the branch changeset where the code was branched so EVERY file in the branch was listed.  I needed a list of all files that had just been altered since the branch.  This is where PowerShell came in.

tf history *.* /noprompt /format:detailed /recursive | Where-Object { $_ -match "[edit|add|delete]\W*\$.*$" } | sort -u > c:\temp\filesthatchanged.txt

This time I opened PowerShell and ran the command from there.  You’ll need to make sure that tf.exe is in the PATH or express the full path to it on the command line.  I use the same call as I did before, but this time I’m piping the results to a Where-Object cmdlet that uses a Regular Expression (the -match switch) that looks for a line that starts with edit, add or delete (which filters out the extraneous text and the branch), followed by some whitespace, followed by something that starts with a dollar sign.  That Where-Object cmdlet is going to get me my list of files from all the text the tf.exe history command is generating.  I then pipe that to a sort cmdlet with a unique switch to get only the unique file names that changed.  I then use a redirector to push that out to a text file.

SWEET!  This saved me quite a bit of time from copying this list out of the UI.


I will point out that VSS had this feature to get a list of all files changed by project, user and/or date range.  Not that I’m advocating using VSS, but I’d like “newer, faster, better” tools to not take away features I had previously.