Cover image for The Great Azure DevOps Migration - Part 3: Clean

The Great Azure DevOps Migration - Part 3: Clean

timothymcgrath profile image Timothy McGrath ・4 min read

Before migrating the TFS data into Azure DevOps, it's a good idea to eliminate any data that you don't need to move into the new service. Ten years of TFS has accumulated a huge amount of code, and I really only need to bring my latest repos forward.

This part will show which data to eliminate and the quickest way to do it.

If you missed the earlier posts, start here.

I highly recommend Microsoft’s Azure DevOps Service Migration Guide.

Team Projects

In my case, I had about 50 Team Project Collections. Team Project Collections each contain their own project template, code repository, and work items.

I had about 50 of these because we imported from SourceSafe over 10 years ago and the import process set it up this way. We actually only use one of these projects on an ongoing basis. Over the last 10 years, we migrated the code for active projects into this main project so we could share work items and project templates.

Because of this, I have about 50 extra projects that are old projects that are rarely (if ever) worked on. None of them have their own work items. I don't want to bring any of these projects into the Azure DevOps service.

The future plan is that if we need to access the code for one of these projects, we'll import it as a new GIT repository into our Azure DevOps Service project.

Delete Team Projects

So, for Step 1, delete the unnecessary Team Projects. This is most easily done through the Web UI for TFS.

Make sure you are on the Staging TFS Web UI!

In the Web UI, you need to access the Collection's Settings. In the breadcrumb trail, at the top of the UI, click the root (mine is DefaultCollection). Then click Admin Settings at the bottom left corner. This will show you the full list of projects in your collection. Click the ellipsis next to each project (except for the ones you want to keep) and click Delete.

If any of these projects have a large code-base, this will take a long time. One of my big ones took over an hour, so be prepared to wait.

Team Foundation Version Control

Before GIT, we had TFVC. TFVC was the only source control that TFS supported in the beginning, so if you've been using it for long, you probably have lingering TFVC repositories.

We now exclusively use GIT, so I don't want to migrate any of the TFVC repositories to Azure DevOps Service. If you are using TFVC, you can migrate these repositories... but I recommend you move to GIT anyway because it's awesome.

My current project that I'm migrating contains both GIT and TFVC, so I want to purge the TFVC before migration. You can't actually destroy the TFVC repository, it is there forever... but you can clear everything inside of it.

Delete Workspaces

First, delete all the workspaces. TFS won't let you delete the code until the attached workspaces are gone.

The best way I found to do this was using a blast from the past: TFS Sidekicks!

TFS Sidekicks is a handy tool for TFVC but has fallen away as GIT has taken over. However, it still works in Azure DevOps Server 2019.

Install it onto your staging server and run it. Go to the Workspaces tab, and highlight and delete all the workspaces. Easy!

Delete Code

Now for the code. The best way to delete the code from the database for good is with a command line "tf destroy". This will eliminate the code completely from the database.

It is also very important that you include the /startcleanup parameter as that will tell the database to remove it immediately. Otherwise, it can take up to five days to be removed.

There is one caveat, that the tf destroy command will fail if it takes too long to run. So, if you have an enormous amount of code, you will need to do it in smaller chunks.

I had a ton of branches persisted in TFVC, so I had to do it one branch at a time. It took a while, so maybe put on a TV show while you do this...

The tf destroy command needs to be run from the Developer Command Prompt for Visual Studio. Type that into Start to find it.

Then run *tf destroy $/[REPOSITORY]/[FOLDER] /startcleanup

If your repository is small enough, skip [FOLDER] and attempt to destroy it all in one run.


Your old data is cleaned out! This may seem unnecessary, but there are two reasons to do this.

  1. We really want to be under 30 GB before migration to have the simplest migration possible. More on this later...
  2. This is a great opportunity to cut loose clutter that you no longer need. If you think you will need this code in the future, keep it. But in my case, I'm 99% sure I will never need it again. And if I do need it again, I want to migrate it to GIT anyway.

What's Next?

In the next post, we begin the Validation.

Posted on by:

timothymcgrath profile

Timothy McGrath


i'm a .net dev that loves learning new things


markdown guide

Great series. I have a quick question, what about shelvesets? Do they migrate over as well? Is it good strategy to keep those around or check-in everything before migration?


Good question. I ended up purging all shelvesets to make the import size smaller, especially since I wasn't importing the VSTS code base. However, I imagine it will import the Shelvesets as long as they are stored on the server (which I think they have to be).