TFS source control system has got some strange meaning of “Workspace”. I’ve run into this numerous times and tonight again. This time I’m trying to migrate a project from TFS into git and keep the project name intact. So I’ve renamed my old project in VSTS to be ProjectName.TFS. And created a new one called ProjectName. But was faced with this great error:

The Team Project name ProjectName was previously used and there are still TFVC workspaces referring to this name. Before you can use this name, the owner of each workspace should execute the Get command to update their workspaces. See renaming a team project for more details (https://go.microsoft.com/fwlinkip?Linkld=528893). Found 2 workspace(s) using this name: ws_1_1;b03e2eb0-22aa-1122-b692-30097a2fa824, ws_dd5f57e41;b2345678-98a0-4f29-13692-30097a2fa824

Well, yes. Thanks for letting me know that this project name was used before. And I obviously don’t care about these workspaces – the PC where these were used no longer exist.

Following the link I was advised to execute this command to delete the dead workspaces:

tf workspace /delete [/collection:TeamProjectCollectionUrl] workspacename[;workspaceowner]

Yeah, no problem. Only it took me a while to find tf.exe. It is in the most obvious place in VS2017:

c:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\

And WTF is TeamProjectCollectionUrl? and what about workspacename[;workspaceowner]? took me a while to figure out the correct format expected. Here what worked for me:

.\tf workspace /delete /collection:mycompanyname.visualstudio.com\DefaultCollection “ws_1_1;b03e2eb0-22aa-1122-b692-30097a2fa824”

The last bit is coming from the error message in VSTS: ws_1_1;b03e2eb0-22aa-1122-b692-30097a2fa824, ws_dd5f57e41;b2345678-98a0-4f29-13692-30097a2fa824 Name from the owner is separated by ; and different namespaces are separated by ,.

All that bloody obvious!

I’ve been using TFS for most of my professional career. I mean if it is a paid project – it was on TFS. Surely there was a bit of SVN as well, but not too much. In university I did try CVS. For projects where I picked version control, I tried mercurial and git. But anyway, most of the work I’ve done on .Net was with TFS. And I mean TFS was the source control system – never used it for ticketing and task managing, so can’t comment on that. From now on if I say TFS I mean version control system.

Recently we had time to move from TFS to git. I mean we moved that big-ass mahusive project with over 200K lines of code that was in active development for over 5 years. That was hard work to move it and preserve the history. And to be honest my team-mate has done most of the migration himself, I stood by and made sure I don’t interfere.

And I tell you one thing – moving to git was a good decision. Well worth the time/effort investment. So now I’ll try to explain why I’m so happy with git.

TFS is Horrible

If you don’t believe that TFS as a version control is horrible – Google for it. There will be a lot of articles explaining why you should never touch TFS. Probably most of them are true. I’ll list my reasons why I hate TFS:

  • Need to be connected all the time. Can’t checkout/modify files if your local connection is down. Or TFS server is down.
  • Locks files for read-only (no longer the case in latest TFS, but was in v2010). Makes it almost impossible to change files outside of Visual Studio.
  • Projects need to be mapped to folders on your drive and this is very flaky. Many hours was wasted on this quirk.
  • Really flaky when trying to work with previous check-ins. One of the things I run into was moving files. You can’t do anything with a file in an old check-in if in later check-ins it was moved/renamed/deleted. I mean you are time machine TFS, I want to meddle with history, I don’t care that this file does not exist 20-check-ins later. Nope.
  • SLOW. All the file operations need to go over the network.
  • Workspaces. WTF?
  • Branching is so bad, it really can be written off the table. More on that later.

Git is Horrible

Same as above, if you Google for this, you will get a number of articles explaining why git is horrible. Most of them are true. Probably. I’ve not tasted most of them, here are my gripes with git:

  • Different line endings. It is 2016 for fire-sake! Just bloody ignore them by default. All of you: git, merge tools, editors, etc. I don’t care, I don’t want to know that somebody commited file with different line endings. Just work!
  • Complexity of some commands. Remember your first try of interactive rebase?
  • Hard to learn. I’m learning a lot of new things every time I get stuck with git.
  • Hard to remember commands – I google a lot for stuff I need to do. Can never remember all the options.
  • Git is HARD. But there is always git reset --hard HEAD.

So?

I’ve re-read the description above and seems like we’ve replaced QUIRKY with HARD.

I can’t work with quirky – so much wasted time and effort just to overcome the quirkiness.

I can deal with hard – I’ve completed BSc and MSc courses in Computer Science after all – that was HARD. But git has soooooo many books/tutorials/articles now that I always found an answer to my problem within the first page of Google search results.

Branching

No the biggest benefit (apart from escaping from quirky system) of moving from TFS to git is branching. In TFS branching is so bad it is a write-off. It takes forever to do branching, it must be literally in the other folder, you need to restart VS to switch to another branch. If you have IIS pointing to a web-site inside of your solution, you’ll have to reconfigure IIS to switch to another branch. Basically branching is TOO EXPENSIVE in TFS.

And it is not an issue until you used cheap branching in real life.

If you never used git-branded branching, you are used to not doing branching. So if you have any risky development, you tend to be very careful with it, so it does not spoil the rest of the code. You hide it behind a toggle, you don’t really commit it, you comment out your breaking code before checking in. And use a lot of other dirty tricks to not break your existing stuff. That does not always work well and you tend to be shy with potentially breaking changes. This leads to development stagnation because some changes are so global it is impossible to hide them. And you just don’t do them. That leads either to code quality problems or your product suffers from lack of good features.

Also lack of experimental space kills a lot of innovation. I’ve gone through that recently: “hm… what if I add a generic parameter here.. that will actually propagate into a lot of places in the codebase.. nope, can’t afford to possibly break everything in case this does not work out. Not going to try that”. But if there was cheap branching available you can just make a new branch and break stuff all you like. If it does not work out – just abandon the branch – you have tried.

Cheap Branching

Git is all about branches and makes them really cheap to implement/use. In fact, git is pointless without branches – you might as well use SVN instead.

With availability of cheap branches in git, I found that I’m following through with more risky ideas. A lot of them work out and give me good results. If you have a feature that takes a while to implement, you move the development in a branch and don’t disturb your main release – your customers won’t get half-baked code, you won’t need to hide new stuff behind a feature toggle. You merge it back into the mainstream when it is ready – no magic.

This promotes experiments without a risk of them leaking into your production. If experimental code does not work out – it is still there in a branch, just not merged anywhere – you can come back to it later, no need to delete anything. Experiments lead to a better development cycles and in turn gives you a better product.

Conclusion

If git is not making you more money with a resulting better product, it definitely saves you time when you don’t have to maintain a million of toggle for unfinished features.

Dump TFS, move to the dark side, use git.

Yesterday Nuget server was down for couple hours. That wasn’t nice. I got stuck for a bit, because I blew up my environment and needed to re-download all the packages again. And some of them were not in the local cache. And just the same night Mr. Mark Seemann blogged that auto-restore in Nuget is considered harmful. And I could not disagree with Mark. Amount of time I’ve spent on trouble-shooting missing packages or package restore in the last year mounts to probably a week. Most of that time was spent for package restore on build servers. And just for these little shits I had to dig very deep into TFS build template, modify it, so it can restore packages before attempting to build it. It was not a nice experience.

Anyway, long story short. Today I decided to give that advice a go and check in packages for one medium sized project hosted on TFS. I went to Source Control Explorer, added existing folder of packages, it added a big number of files and then I checked-in.

Build server crunched for a moment and failed the build: references are not found. Strange. Connected to the build server and discovered that TFS by default ignored *.DLL files but included all other crap that comes with nuget packages (xml files, readme.md, source code, etc.). That was strange. After a bit of digging I found that TFS has a list of file-types that it looks for.

Continue reading

Now, as promised my other project is hosted and built on hosted Team Foundation Service and it took me a bit of fiddling before I managed to run NUnit tests on it. However, there is an excellent walk-through how to do that: http://www.mytechfinds.com/articles/software-testing/6-test-automation/72-running-nunit-tests-from-team-foundation-server-2012-continuous-integration-build

Much in the same way you can do xUnit:

  1. Download xunit.runner.visualstudio-x.x.x.vsix from Codeplex.
  2. Change file extension from .vsix to .zip and open with zip archiver.
  3. Copy all xunit.*.dll files to a folder that is mapped to TFS and check them in. I prefer to have these files in /BuildFramework folder

xUnit_VS

  1. Now, pretty much the same as with NUnit set up (If you have not done that before), you need to update settings for Build Controller. In VS go to Team Explorer -> Builds -> Actions -> Manage Build Controllers. And set “Version Control path to custom assemblies” to the folder where you have saved adapters for xUnit:

Build_controller

And you are pretty much done. You can now check in and your xUnit tests will run on hosted TFS (Presuming TFS is set up correctly to run your tests).