Cloning a TFS branch to Git in three simple steps

So it’s pretty straightforward to transfer TFS code, with history, into Git. This post shows a simple way to ‘clone’ TFS into a new Git repo.

1) Install Chocolatey

@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin

2) Use Chocolatey to install GitTfs. Close Visual Studio first, though.

cinst tfsgit

Then restart the command window.

3) Choose a branch and get cloning;

git tfs clone http://tfsserver:8080/tfs/TfsInstanceName $/TeamProjectName/Path/To/Branch

That should sort you out. 

Advertisements

TypeScript, Knockout, TypeLite; strongly typed knockout development

TypeScript’s a great environment for development, and the strong typing is a real benefit, but in an MVC app it’d be good to integrate things between the server side and the client side. Let’s say you’ve got a data transfer object  defined in the server side, in C#, like so;

// C# Data Transfer Object
namespace TypeLiteDemo.ViewModels
{
  public class MyListItem
  {
    public int Id { get; set; }
    public string Title { get; set; }
  }
}

It would be great to request them from the server as JSON, and then on the client-side deal with it in a strongly-typed way with TypeScript. We want a matching declaration like this when dealing with objects from the server;

// TypeScript Data Transfer Object
declare module TypeLiteDemo.ViewModels {
  interface MyListItem {
    Id: number;
    Title: string;
  }
}

So that we can do this;

$.getJSON('MyListItems', function(data: TypeLiteDemo.ViewModels.MyListItem[]) {
  // do something with strongly-typed data from the server
});

Even better, it would be great, if you’re using knockout mapping, to have the mapping viewmodel version, too;

declare module TypeLiteDemo.ViewModels {
  interface MyListItemViewModel {
    Id: KnockoutObservable<number>;
    Title: KnockoutObservable<string>;
  }
}

So that you can do this;

$.getJSON('MyListItems', function(data: TypeLiteDemo.ViewModels.MyListItem[]) {
  // convert to knockout viewmodels;
  var vms = <TypeLiteDemo.ViewModels.MyListItemViewModel[]>ko.mapping(data);
  // now do something with the viewmodels;
  _.each(vms, function(vm) { /* extend the view models here */ }
});

Well, it should be no shock to learn that this blog post introduces a way of doing just that.

First, you’ll want to install TypeLite using NuGet. This gets you a default T4 template for generating the TypeScript definitions, but I’ll provide an alternative version below which generates the knockout viewmodels, too.

Copy and paste the code below into the TypeLite.tt file, modify the line that starts ‘var definitions’, and save. When you save, it’ll scan your assembly for the DTOs you mention, and produce two parallel sets of TypeScript defintions — one set for the DTOs, one for Knockout viewmodels.

<#@ template debug="false" hostspecific="True" language="C#" #>
<#@ assembly name="$(TargetDir)TypeLite.dll" #>
<#@ assembly name="$(TargetDir)TypeLite.Net4.dll" #>
<#@ assembly name="$(TargetDir)$(TargetFileName)" #>
<#@ import namespace="TypeLite" #> 
<#@ import namespace="TypeLite.Net4" #> 
<#@ import namespace="TypeLite.TsModels" #> 
<#@output extension=".d.ts"#>
<# 
 bool generateKnockoutFiles = true;
 var definitions = TypeScript.Definitions().For<TypeLiteDemo.ViewModels.MyListItem>();
#>
///<reference path='typings/knockout/knockout.d.ts' />
///<reference path='typings/knockout.mapping/knockout.mapping.d.ts' /><#= definitions #>
<# if (generateKnockoutFiles) { #>
<#= definitions
 .WithFormatter(KnockoutTypeConverter)
 .WithFormatter(KnockoutMemberTypeConverter)
 .WithFormatter(KnockoutMemberIdentifierConverter) #>
<# } #>
<#+
public string KnockoutTypeConverter(TsType type, ITsTypeFormatter formatter)
{
  return type.ClrType.Name + "ViewModel";
}

public string KnockoutMemberTypeConverter(string memberTypeName, bool isMemberCollection)
{ 
  if (isMemberCollection)
  {
    return string.Format("KnockoutObservableArray<{0}>", memberTypeName);
  }
  else
  {
    return string.Format("KnockoutObservable<{0}>", memberTypeName);
  }
}

public string KnockoutMemberIdentifierConverter(IMemberIdentifier identifier)
{
  return identifier.Name;
}
#>