Managing My Many Hats on GitHub

Like many developers, I contribute to open source projects at home – usually to scratch an itch, learn something new or just to contribute to something I love using myself. However, I work for the open source .NET Foundation which means I have a dream job of getting paid to work on open source. Finally, I’m also still employed by Microsoft and get to make contributions to open source projects on their behalf which is also a pretty good gig.

When I commit to Git, I make sure my email address is set correctly based on what hat I’m wearing. On my work machines I have my work email configured by default and on my home machine I have my personal email configured by default.  To configure your default email address for Git remember from the excellent Git Book that you do:

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

As I use my work machine for work and my personal machine for personal stuff, this usually works well. However sometimes I want to make a quick update to something at work from my personal machine. But that’s fine because Git also provides a way to specify any git config setting per repository.  Once you have cloned down the Git repository, you cd into the repository and then simply type the same command without the -–global parameter, i.e:

git config user.email johndoe@example.com

Which will override the default email address set on your machine but just for that one repository. The repository wide (local) settings are stored in a file called config with-in the .git folder in your repository, the global settings are stored in a file called .gitconfig in your users home directory.

Next, I like to make sure all my contributions come back to my GitHub identity. Luckily, GitHub have an easy mechanism to associate multiple email addresses with one GitHub account.  Simply go to your profile, and make sure all the emails you use to commit to Git are configured.  I have a few different ones listed in mine

image

And that’s it – when commits are pushed to GitHub using either my home, work or .NET Foundation email addresses they all come back to my GitHub profile so people can see what I as an individual am involved with.

New Gig

I'm excited to say that today I started a new job as the Executive Director of the .NET Foundation. The .NET Foundation is an independent non-profit organization set up to foster open development, innovation and collaboration around the Microsoft .NET development framework. It's been going a year now and I've been involved with the team from the beginning, but it's fabulously exciting to be an active part of it now. Also quite scary - the team is fantastic with some of the smartest people on the planet, so my job initially is to figure out how to keep out their way as they do awesome stuff while figuring out what I can do to help unblock more openness and innovation by ensuring that the wider community is always involved along the way.

I'll still be an employee of Microsoft but my job is now to focus 100% of my time on the .NET Foundation helping co-ordinate lots of the day-to-day operations of the non-profit organization but also set the strategy and tone for the future. If folks have ideas then please head over to the .NET Foundation Forums and post your suggestions. You can always reach out to me on Twitter(@martinwoodward) or my new work email address (martin@dotnetfoundation.org).

It's an incredibly exciting time to join the team as they are doing some amazing stuff. .NET as a platform is going through rapid innovation at the moment. But more importantly the project teams are working in the open and are focused heavily on responding to pull requests that come in and taking the platform forward with wider community participation which I see as a very good sign.

The .NET Community has always been a passionate one, and a place in which I have found many of my friends. But it is a friendly one as well. I was always the "Mac guy" or the "Eclipse guy" when it came to .NET User Group meetings yet I never felt an outsider - everyone has always been very welcoming and just keen to learn more from one and other. The MVP and RD communities around .NET contain so many passionate, dedicated and smart people.

It's a fantastic time to be involved in .NET. We're at an inflection point in the platforms history and all signs are that things are heading to some very good places indeed.

Now I just need to not mess up and do what I can to help make sure the .NET Community continues to be a great place to be. Drop me a line if you have any ideas, suggestions or feedback as to what I can do to help.

Over the past couple of weeks I’ve had several people ask me about my dev environment for working with Git on Windows so I decided to write it up here for me to point people to. Of course the first thing that you want is Visual Studio 2013 with the built in Git tooling. While I’m obviously very biased in terms of the Visual Studio tools I’m actually more familiar with the command line workflow – especially coming from the Mac. However the team specifically designed the Visual Studio tools to work well with the command line and compliment them – I find myself swapping more and more between the command line and the UI depending on what’s quickest for me. I NEVER use the command line for merging any more, but I still use if for dealing with multiple remotes (very common in OSS workflows) squashing and rebasing my commits etc. There are some things I actually find myself using Visual Studio for that I never thought I would. For example I quite often find myself swapping my email address around when I’m doing commits for work or if I’m working on a demo or a side project and I’ve noticed I’ve been using the Git settings panel in Team Explorer more and more rather than going to “git config” which surprised me.

So, how do I set up my command line Git experience?

First of all you have to install Git for Windows of course.  I always use the .exe installer from here (ignore the –preview moniker, they are good – at the time of writing the latest is Git-1.8.5.2-preview20131230.exe). Now one of the first mistakes I see people do is go for the default options in the installer which results is people using Git Bash. If you love yourself don’t do that, but make sure Git is added to your path. On the screens that I need to make decisions on, I always follow this path.

For component selection, I generally go for the defaults. I don’t use the shell extensions personally but they don’t hurt.

image

This is the important one being the change to make sure Git is added to your Path. This makes sure that you can go to the command shell or PowerShell and run Git. The Git Bash shell is evil IMHO, I never find myself using it despite using Bash all the time when I’m on *nix.

image

Then I go with the default of setting the CRLF behaviour to normalize as Unix style endings in the commits.  Basically this makes sure a commit generated on Windows is the same as one done on the Mac or on Linux but also that you can still use notepad if you check out a file that was edited in Vim on Linux.

image

 

At this point you now have Git installed. Congratulations!  However, you can do better than that…

Enter PoshGit

The next thing I install is PoshGit. I swear, PoshGit is the main reason to use the PowerShell console (that and also the fact it doesn’t shout at you when you accidentally type “ls” instead of “dir”) Installation of PoshGit can be a bit quirky but Keith’s instructions are pretty good. Basically, after he’s helped you make sure your PowerShell environment is set up correctly, you clone the repo (git clone https://github.com/dahlbyk/posh-git.git), cd into it and then run the install script.

I always use Git over HTTPS rather than SSH so I often don’t have Putty installed with Paegent to handle my keys. Therefore I tend to just comment out the Start-SshAgent -Quiet line in \posh-git\profile.example.ps1. If you are seeing the error “WARNING: Could not find ssh-agent” when you start PowerShell and you don’t need SSH then just open up profile.example.ps1 in notepad, scroll down to the end of the file and make sure it looks like this:

   ...

Enable-GitColors

Pop-Location

# Start-SshAgent -Quiet

 

Remembering Passwords

Next up I install Andrew Nurse’s credential helper, git-credential-winstore. If you are talking to a Git server that requires a username and password, rather than having to type your credentials all the time this nifty little helper will actually store them securely in the Windows Credential Manager.  Note that when installing you’ll see an error if you’ve gone for the middle option when setting your path in Git for Windows because Git.exe isn’t on your path (Git.cmd is).  Therefore you are going to want to:

  1. Download it from CodePlex and save it to your disk
  2. In a command / powershell window, cd into your Downloads folder
  3. Install the credential helper by typing:

git-credential-winstore.exe -I "C:\Program Files (x86)\Git\bin\git.exe"

Combined with with web interface in TFS, Visual Studio 2013 and Eclipse with egit, that’s all I need personally. However if you want a graphical view of your repository then a lot of people use gitk which is installed with Git for Windows (just type “gitk” inside your repo in the command shell / powershell windows).  You can also type “git gui” for the git-gui tools.  Other popular graphical tools you might want to install are GitHub’s free app GitHub for Windows and Atlassian’s free app SourceTree.  GitHub for Windows is very pretty and great for managing your GitHub based repos. Atlassian’s SourceTree is very highly regarded as stand-alone UI for working with Git repos on Windows.

If you want to work with your local Git repositories in some .NET code then LibGit2Sharp is your friend.  It’s the open source library used by the Visual Studio Tools for Git and gives you a very idiomatic way to talk to Git from C# or VB.NET.  I thought it would be worth a quick tutorial post showing how easy it is to get started by querying a repository helping us learn a bit about the library but also learn more about Git itself. As LibGit2Sharp is open source in this example I’m going to point to cloned copy of the repository I have locally already by using the Git tooling in Visual Studio or by typing git clone https://github.com/libgit2/libgit2sharp.git. However you can obviously point to any Git repository you already have locally.

To begin, create a new console project in Visual Studio. We need to add a reference to the Lib2Sharp library and the quickest way to do that is to open the NuGet package manager by right-clicking on your project in Solution Explorer and select Manage NuGet Packages…  Search online for “LibGit2Sharp” and Install.

NPM to install LibGit2Sharp

Then accessing an existing repo is trivial, simply use the LibGit2Sharp.Repository class. A handy way to get a particular commit is by its hash if you know it.

      public static void Main(string[] args)
      {
         
using (var repo = new Repository(@"D:\source\LibGit2Sharp"
))
          {
             
Commit commit = repo.Lookup<Commit>("73b48894238c3e9c37f9f3a696bbd4bffcf45ce5"
);
             
Console.WriteLine("Author: {0}"
, commit.Author.Name);
             
Console.WriteLine("Message: {0}"
, commit.MessageShort);
          }
      }

But what if we just want the commit that’s the latest of the current branch, in Git-speak we want the “Tip” of “Head”. LibGit2Sharp gives you an easy way to get to the Head through the repository object. So we can do the following:

    public static void Main(string[] args)
      {
         
using (var repo = new Repository(@"D:\source\LibGit2Sharp"
))
          {
             
Commit
commit = repo.Head.Tip;
             
Console.WriteLine("Author: {0}"
, commit.Author.Name);
             
Console.WriteLine("Message: {0}"
, commit.MessageShort);
          }
      }

A point in time in the repository is represented by a Commit. Each Commit points to a Tree which you can think of as a directory/folder. A Tree can contain a Blob (i.e. the contents of a file) or another Tree (i.e. a sub-folder).

So if you want to list the contents at the root of the repository then you can do

        foreach(TreeEntry treeEntry in commit.Tree)
        {
           
Console.WriteLine("Path:{0} - Type:{1}"
, treeEntry.Path, treeEntry.TargetType);
        }

That will give you something like the following when against the LibGit2Sharp repository

Path:.gitattributes - Type:Blob
Path:.gitignore - Type:Blob
Path:.gitmodules - Type:Blob
Path:.mailmap - Type:Blob
Path:.travis.yml - Type:Blob
Path:CHANGES.md - Type:Blob
Path:CI-build.msbuild - Type:Blob
Path:LICENSE.md - Type:Blob
Path:Lib - Type:Tree
Path:LibGit2Sharp.Tests - Type:Tree
Path:LibGit2Sharp.sln - Type:Blob
Path:LibGit2Sharp - Type:Tree
Path:README.md - Type:Blob
Path:ResharperSettings.xml - Type:Blob
Path:UpdateLibgit2ToSha.ps1 - Type:Blob
Path:build.libgit2sharp.cmd - Type:Blob
Path:build.libgit2sharp.sh - Type:Blob
Path:build.libgit2sharp.x64.cmd - Type:Blob
Path:libgit2 - Type:GitLink
Path:nuget.package - Type:Tree
Path:square-logo.png - Type:Blob

To see which files changed in a particular commit.  To do that we need to find the diff between the commit and it’s parent. For now let’s just assume that we have a single parent (i.e. we’re not a merge commit). Therefore we can do this

        Tree commitTree = repo.Head.Tip.Tree;
       
Tree
parentCommitTree = repo.Head.Tip.Parents.Single().Tree;

       
TreeChanges
changes = repo.Diff.Compare(parentCommitTree, commitTree);

       
Console.WriteLine("{0} files changed.",changes.Count());

And finally to iterate over the changes to show what files changed in that commit

        foreach(TreeEntryChanges treeEntryChanges in changes)
        {
           
Console.WriteLine("Path:{0} +{1} -{2} "
,
                    treeEntryChanges.Path,
                    treeEntryChanges.LinesAdded,
                    treeEntryChanges.LinesDeleted
                );
        }

That then gives the following output

Author: nulltoken
Message: Release LibGit2Sharp v0.11
3 files changed.
Path:LibGit2Sharp.Tests\DiffTreeToTreeFixture.cs +35 -11
Path:LibGit2Sharp.Tests\LibGit2Sharp.Tests.csproj +1 -0
Path:LibGit2Sharp.Tests\TestHelpers\OdbHelper.cs +17 -0

This post obviously just scratches at the surface of what is possible with LibGit2Sharp. We’re starting the process of trying to flesh out the documentation for the project from the current starting position of none, but it the meantime if you want to see some more examples of using LibGit2Sharp then take a look at the Unit Tests.

Source Code: Commit1.cs

Eclipse Juno Themes on Windows

I’ve been running Eclipse Juno regularly since the M5 milestone.  One of the things I’ve really noticed is that the default theme for Eclipse Juno on Mac OS X blends in better with other Cocoa applications than Juno looks on my Windows machines. Today I just realised that this is because Eclipse is picking up the Eclipse “Windows XP Blue” theme by default. Below is a picture of Juno RC3 with a Windows Explorer window over it for comparison.

Eclipse Juno RC3 on Windows XP Release Preview

To change the theme, go to Window, Preferences, General, Appearance and select Windows 7.  This looks a lot better on my Windows 8 Release Preview machine as shown below.

Eclipse Juno RC3 on Windows XP Release Preview with Windows 7 theme

Now, one of the great things about e4 is that it is skinnable using CSS.  I thought I’d knock up a quick stylesheet to get rid of the gradient in the toolbar and tidy up a few other little things.  It’s also really easy to define a theme as part of the plugin.xml and only have it apply to people running Windows 8 – simply add the following (note the condition on OS version of 6.2):

<extension
point="org.eclipse.e4.ui.css.swt.theme">
   <theme
         basestylesheeturi="css/e4_default_win8.css"
         id="org.eclipse.e4.ui.css.theme.e4_default"
         label="Windows 8 Desktop"
         os="win32"
         os_version="6.2"
>
   </theme>
</extension>

This is what my Windows 8 theme for Juno currently looks like against explorer:

Eclipse Juno RC3 on Windows XP Release Preview with custom theme

Needs a bit of playing with (for example, I’ve noticed that swapping themes in Eclipse works a lot better if you explicitly override things like the background images that have been used previously in themes in that Eclipse session rather than just leaving them not set).  What do you think?  If you are interested the CSS is below but it’s just a subtly changed version of the default win7 theme.

@import url('e4_basestyle.css');
.MTrimmedWindow {
    background-color: #EFF6FE;
}

.MPartStack {
    font-size: 9;
    font-family: 'Segoe UI';
    swt-simple: true;
    swt-mru-visible: false;
}

.MTrimBar {
    background-color: #EFF6FE;
}

.MToolControl.TrimStack {
    frame-image:  url("./win7TSFrame.png");
    handle-image:  url("./win7Handle.png");
}

.MPartStack.active {
    swt-unselected-tabs-color: #F3F9FF #D0DFEE #CEDDED #CEDDED #D2E1F0 #D2E1F0 #FFFFFF 20% 45% 60% 70% 100% 100%;
    swt-outer-keyline-color: #B6BCCC;
}

#PerspectiveSwitcher  {
    background-color: #E1E6F6 #EFF6FE 100%;
}

#org-eclipse-ui-editorss {
   swt-tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
   swt-unselected-tabs-color: #F0F0F0 #F0F0F0 #F0F0F0 100% 100%;
   swt-outer-keyline-color: #B4B4B4;
   swt-inner-keyline-color: #F0F0F0;
   swt-tab-outline: #F0F0F0;
   color: #F0F0F0;
   swt-tab-height: 8px;
   padding: 0px 5px 7px;
}

CTabFolder.MArea .MPartStack, CTabFolder.MArea .MPartStack.active {
   swt-shadow-visible: false;
}

CTabFolder Canvas {
  background-color: #F8F8F8;
}


Anyway, lesson from this is to at least change the theme in Juno on Windows 8 from Windows XP Blue to the Windows 7. The jury is still out on my customized stylesheet above – I’m sure someone with some actual design skills could do better.

TFS from the Raspberry Pi

I just got delivery of my shiny new Raspberry Pi.  With-in a few minutes I had it all booted and running a stock Debian “squeeze” image, almost too easy and the performance of the diminutive Raspberry Pi was great. Previously my experiences with Embedded Linux has mostly been when running on hacked router firmwares so running on a chip as powerful as the ARM v11 Broadcoam chip in the Raspberry Pi is a real pleasure.  As getting it up and running was so easy, what should be my first project on my latest (and least expensive ever) computer?  I thought I’d see what it took to talk to TFS from the device :-)

Accessing TFS from a Raspberry Pi

First things first, I had to get Java installed.  It sounds like Oracle are working on a version of Java with a proper Hotspot JVM – but I just went with a vanilla OpenJDK build for the device that lacks important features like a JIT etc.  It’s all fully functional, just the performance isn’t great but sticking to the TFS cross-platform command line client (tf) in Team Explorer Everywhere, performance is usable and will only get better as better JVM’s come available for the Raspberry Pi.

To install a JRE you would just do the usual:

sudo apt-get install openjdk-6-jre

However, I needed to do some building on the Raspberry Pi and needed a full JDK so I went with:

sudo apt-get install openjdk-6-jdk

And then set my JAVA_HOME by adding the following to my profile

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/

Now, I like to say that Team Explorer Everywhere is 99.99% Java.  All the code to talk to the TFS webservices is all Java based, however there is a small but very important set of native code that we also ship with our Cross-platform command line client, the Eclipse plug-in and the TFS SDK for Java.  The native code does things that are hard to do otherwise such as see how many columns are available in the current console session, use Key Ring of Keychain for secure credential storage, interface with the platforms native Kerberos libraries if present to allow for single sign-on with TFS etc.  My next step to get tf working on the Raspberry Pi was to compile our native code for the armv6l based chipset.  As mentioned this native code includes Kerberos support so I first had to add the Kerberos libraries (sudo apt-get install libkrb5-dev - note you wouldn’t have to do this if you didn’t need Kerberos support as we also support NTLMv2 out the box without requiring any additional dependencies)

I ran the native build process, and amazingly all the unit tests passed!  I then checked the Linux/Arm natives back into TFS, waiting for the CI build to finish and then downloaded a new TFS-CLC.zip from the build server.  Unzipped the standard CLC into my users ~/Bin directory and it just worked!

I can now happily talk to my local TFS server from my $25 Raspberry Pi.  With local workspaces and transparent execute bit support in TFS 2012 it’s a really good experience. I just use vim to edit files, do a quick “tf status” to see what's changed and then a “tf checkin” to add the files to source control.

I’ve actually added the Linux on Arm natives into the main build of TEE so they might appear in the RTM version of Team Explorer Everywhere if I don’t find any major bugs.  It definitely wouldn’t be classed as a supported platform or anything, but it certainly “works on my machine”.  Possibly more useful is that if the Arm natives also ship in our TFS SDK for Java it would mean any Java applications coded on the Raspberry Pi in the future would have full access to the same TFS API that we use to create the command line client and the Eclipse plug-ins.

Picture of the Raspberry Pi running TEE against my ID badge for scaleUpdate: I was getting some questions on Twitter, so just to explain how small this device is here is a picture of it against my Microsoft ID Card (which is credit card sized).  The Raspberry PI is almost exactly the same size.  The ARM CPU on it is about the size of a thumbnail – much smaller than the HDMI and Ethernet connection it is attached to.  Really nice piece of kit for $25 if you can get hold of one.

All this was anti-climatically easy. I’m going to have to figure out what to do as my next Raspberry Pi project.  Now that I have an API I can use for TFS, I’m thinking about doing a Wallboard display application to display stats from my TFS server (such as latest build status, latest check-ins and work item assignments etc) from the device onto a cheap HDMI TV set in my office – but if anyone has any other ideas let me know.

If you are looking to extend Team Foundation Build using workflow activities, then the first thing you should do it take a look at the latest stable release of the Community TFS Build Extensions over on CodePlex.  This is a collection of around 100 activities that can provide many commonly requested functions incluing running CodeMetrics and NUnit tests, creating a Zip archive, wrapping RoboCopy for deployment, updating AssemblyInfo files, running StyleCop, merging assemblies with ILMerge etc etc.  Basically most of the building blocks for major common customization already done for you.  Also – as it’s an open source project ran by the MVP community you have access to a bunch of great code that shows you how to create your own activity should you want to do something that has yet to be done (don’t forget to contribute it back if you can)

Great job to the team of folks contributingg to the community build extensions (many of which I am proud to call my friends) – I’m looking forward to seeing the project go from strength to strength now that they have their first stable release out the door.

Archives

Recent Comments

  • Klas: Do you know how to grant access to a single read more
  • Mike Parks: If you have Visual Studio 2010 w/TFS 2010, check out read more
  • Chris: Occasionally, GMail loses its marbles and offers a Basic HTML read more
  • Martin Woodward: Ryan - yes, we still provide a complimentary CodePlex license. read more
  • ryan: will 'codeplex only' licenses still exist for TEE like they read more
  • Sarah: @Ethan & @bString ... and maybe all those asking the read more
  • mohan: I am not able to run build using the read more
  • Frank: Cool! Thanks for this tip! Finally my over 2000 unread read more
  • mahesh: HELLO SIR, I'm new at .net I want to create read more
  • stuart: saved my morning! google notifier was displaying thousands of unread read more
Creative Commons License
This blog is licensed under a Creative Commons License.