social coding management comments edit

On Tuesday, November 8, 2016 I’ll be giving a talk entitled “Social Coding for Effective Teams and Products” at QCon SF as part of the “Soft Skills” track. If you happen to be in San Francisco at that time, come check it out.

In anticipation of this talk, I recorded a podcast for InfoQ where I pointed out the irony of using the term “soft skills” to describe the track as these are often the most challenging skills we deal with day to day. They are indeed the hard skills of being a software developer.

In the podcast, we also cover what it was like in the early days of ASP.NET MVC as we went from closed source to open source and how far Microsoft has come since then in the open source space.

Afterwards, we talked a bit about Atom and Electron and the community around those products. And to finish the podcast, we gabbed about my transition into management at GitHub, which is something I wrote about recently.

So if you don’t mind hearing my nasally voice, take a listen and let me know what you thought here.

github csharp dotnet scientist comments edit

In the beginning of the year I announced a .NET Port of GitHub’s Scientist library. Since then I and several contributors from the community (kudos to them all!) have been hard at work getting this library to 1.0 status. Ok, maybe not that hard considering how long it’s taken. This has been a side project labor of love for me and the others.

Today I released an official 1.0 version of Scientist.NET with a snazzy new logo from the GitHub creative team. It’s feature complete and used in production by some of the contributors.

Scientist logo with two test tubes slightly unbalanced

You can install it via NuGet.

Install-Package scientist

I transferred the repository to the github organization to make it all official and not just some side-project of mine. So if you want to get involved by logging issues, contributing code, whatever, it’s now located at

You’ll note that the actual package version is 1.0.1 and not 1.0.0. Why did I increment the patch version for the very first release? A while back I made a mistake and uploaded an early pre-release as 1.0.0 on accident. And NuGet doesn’t let you overwrite an existing version. Who’s fault is that? Well, partly mine. When we first built NuGet, we didn’t want people to be able to replace a known good package to help ensure repeatable builds. So while this decision bit me in the butt, I still stand by that decision.


management github hiring comments edit

I’m coming on five years at GitHub (in December) and I thought I’d write a bit about what I’ve been up to lately and the fact that several of my teams are hiring. Five years passes by so quickly, right? I still get emails for feature requests on ASP.NET MVC. I always reply that the team would be happy to implement all of the suggestions and to just check the repository in a week’s time. I’m sure the team loves me for that.

If you don’t give a rat’s ass about what I’m up to, but are interested in our open positions, feel free to skip to the job postings at the bottom. By the way, even if you do give a rat’s ass, please keep it to yourself. What I’ve been up to does not include collecting rodent derrières.

I still don’t know why that’s a phrase we use, but I’m sure Mark Twain is involved…that rapscallion. But as usual, I digress.

What inspires me

When I think about the work we do at GitHub, the Story of Anna comes to mind. Building software is a great creator of opportunities for those from all walks of life. I get a kick out of writing software for people like Anna, or my friend Noah, or NASA and many others who are using it to build great things.

In a recent Octotale video, Desert Horse-Grant, the Director of Strategic Planning and Operations at Fred Hutch Cancer Research Center noted that “cancer will be solved on a computer.” At GitHub, we’re not solving cancer, but I like to think we build the tools for those who will. And that’s what gets me inspired every day.

My new position

Several months ago, I took a new position as an Engineering Director at GitHub. It’s not clear to a lot of people that GitHub has managers much less directors now. When I started, we had around fifty employees and a flat corporate structure. Two years ago, we introduced management.

Several months ago, we introduced directors, a position that’s also new to me. What this means is that I now manage managers. I guess this is what happens to people who like to blog about blogging, they end up managing managers. I enjoy the meta.

At GitHub, engineering managers are very hands on technically. They are technical leaders who help coach teams to greater success. Kind of like Pete Rose who was a player-manager when he broke the all-time hit record set by the irascible Ty Cobb.

Directors, on the other hand tend to focus more on people and management issues. We’re much less hands on technically, though I try to keep my hands dirty with code here and there. Instead, we try and focus on what will equip the managers and their teams to be more successful. How can I help my managers be better? What systems can I put in place so the people they manage work well together and grow in their careers and as teams. Sometimes I make mistakes, but I try hard to learn from them and then incorporate that learning into the systems and culture at work so they’re less likely to happen again.

When I do spend time on technical work, it is focused on strategic and big picture issues. Every engineer should be thinking this way, but I have the “benefit” of not having a primary responsibility to write production code which means I can dedicate more time to this sort of work. And note that we’re constantly iterating on how we work so this is how I see things today, but it’s always open to improvement tomorrow.

The four teams that I work with are Atom, Electron, Desktop, and Editor Tools (the team responsible for the GitHub extension for Visual Studio). I am incredibly lucky to get to work with such a talented group of people. I’ve been really stretched in a technical sense as these teams use a wide variety of technology.

Open positions on my teams

So that leads me to the topic at hand. Several of these teams are hiring. Here are the job postings.

If building tools for this and the next generation of developers inspires you, take a look. We’re looking for software engineers who thrive as part of a team in a supportive environment. The New York Times recently published an article about what Google learned in its quest to build a perfect team. The lessons they learned about what people think makes a great team and what actually works are very interesting. We want to be a place that embodies that sort of team.

As our Jobs page mentions, we’re focused on building a diverse and inclusive workplace. We have a nice benefits package that includes a generous parental leave policy. We have flexible work schedules and a generous vacation policy.

I believe the reason we provide all this is because we’re focused on building a sustainable environment for people to do great work. We don’t want to bring a person in just to wring out as much code as possible from them because people bring so much more than just the code they can write to the table.

If that all sounds appealing to you, click on the big blue “Apply for a Job” button in those job postings.

management personal comments edit

Last week my family and I went on a cruise to Alaska with four other families and we didn’t die. Not that we should expect to die on a cruise, but being confined with a bunch of kids on a giant hunk of steel has a way of making one consider one’s mortality.

Cruise ship parking lot

Not only did we not die, but I learned a thing or two. For example, it’s common knowledge that the constant wave like motion of a ship can make one queasy. I learned that I could counteract that effect. Drink just the right amount of alcohol and its effect cancels out the queasiness in a process called phase cancellation. Look it up, it’s SCIENCE.


We went on a Holland America cruise to Alaska in part because a family friend is a Senior VP at the cruise line and they convinced us it’d be a good idea. The cruise tends to cater to an older crowd than something like Disney Cruises. Even so, it worked pretty well for us. It meant that the pool was never too crowded.

I used to live in Anchorage, Alaska. This ensured I was ready with the puns for our first port, Juneau.

Me: Where’s our first stop?
Friend: Juneau Alaska.
Me: Yes, I know Alaska. But what city?
Friend: Juneau.
Me: If I knew, I wouldn’t ask.

This was when I wisely ducked away.

But since you like puns, here’s a couple of other Alaska related puns as told by my coworker, Kerry Miller:

Hey pal, Alaska the questions here
I really do appreciate the way Alaska survived the 2008 financial crisis. Their secret? Fairbanks.

Lesson here, puns are awesome.


Back to the cruise. Our friend arranged a couple behind the scenes tours. One was below deck where we got to see the galley where all the food is made and the storage facilities. I was particularly excited to tour the room where they stock all the liquor.

The logistics of stocking a ship of two thousand passengers and one thousand crew is mind boggling. They take a very data driven approach tracking every meal ordered so they can predict what supplies they need given the specific trip, time of year, and audience.

One thing we noticed while touring the storage was they stocked expensive premium sticky rice for the crew that was different from the rice they usually served to customers. We noticed this because we’re Asian and good rice is important.

It turns out that the crew is predominantly Filipino and Indonesian and our friend noted that if they tried to cut costs with cheaper rice, they’d face a revolt. They know this because they’ve seen how much of a hit to morale cheaper rice was on other cruise lines. He fought hard to keep the quality rice because it’s important to keep the crew’s morale high. Not just with rice, but also by enlisting and empowering the crew itself to notice when conditions could be better and to do something about it.

Lesson here, foster a culture where people are empowered to find and fix problems rather than always looking to you to fix it and things actually will improve.

And we noticed the impact of high morale. We were really impressed with the quality of service. The crew always seemed genuinely happy and friendly. Perhaps it’s years of practice in the service industry, but I’ve been to nice hotels where everyone is nice, but you get the sense they don’t really care about you. I really got the sense the crew cared.

So the lesson here is to stock the good rice. Happy people do better work in every way.

Alaska Raptor Center

Another port we stopped in was beautiful Sitka. We took a tour of the Alaska Raptor Center where they rehabilitate injured raptors such as eagles and owls and release them into the wild when they’re strong enough fliers to be on their own.

Our second tour was of the bridge where the Dutch captain showed us the navigation systems and the controller for the ship. The view from the bridge was quite spectacular. We asked the captain whether he’d been on any trips where anyone fell overboard. No, but there was one trip where a very drunk passenger dropped anchor while they were out to sea. At the next port, the passenger tried to sneak off but they had the authorities waiting and they had camera footage of the incident.

Lesson here, phase cancellation only works when the wavelengths are equivalent amplitude. In other words, don’t overdo the drinking.

The ship had a place for kids called “Club Hal” where you could drop kids off for a few hours at a time and go enjoy some Pina Coladas (to help with motion sickness of course). They had a lot of structured activities and a few X-boxes set up. Naturally, since this was convenient for us, my kids hated it. Over time, they warmed up to it a little as the kids at Club Hal held a revolt and demanded more kids choice activities and got their way.

Lesson here, it’s important to balance a bit of structure with letting kids choose what they want to do.

Now I’m back home and back to work and after a few days, the ground has stopped moving, so all in all, a successful trip. We didn’t have internet access for most of the time and I think that was a huge factor in me feeling refreshed by the end. I definitely recommend when you take vacation, fully disconnect from work and even the internet. It’ll do you a lot of good and the tire fire on Twitter will still be there when you get back.

Lesson here, take a vacation now and then, eh?

nuget comments edit

The tagline for the Atom text editor is “A hackable text editor for the 21st Century”. As a Haack, this is a goal I can get behind.

It accomplishes this hackability by building on Electron, a platform for building cross-platform desktop applications with web technology (HTML, CSS, and JavaScript). The ability to leverage these skills in order to extend your text editor is really powerful.

I thought I’d put this to the test by building a simple extension for Atom. I decided to port the Encourage extension for Visual Studio I wrote a while back. For a lot of developers, this image rings true every day.

How to program

Who needs that negativity?! The Encourage extension for Atom displays a small bit of encouragement (“Way to go!”, “You rock!”, “People like you!”) every time you save your document. Maybe it’s true that nobody loves you, but your editor will, if you let it.

Encourage screenshot

Writing the extension

The Atom Flight Manual has a great guide to creating and publishing an Atom package. The guide walks through using an Atom package that generates a simple package you can use as a starting point for your own package.

One tricky aspect though is that the documentation still assumes that the generated package is CoffeeScript. But all new Atom development (including the actual generated package) uses the latest version of JavaScript - ES6 (or ES2015 depending on who you ask).

I won’t go into every detail about the package. You can see the code on GitHub yourself. I’ll just highlight a few gotchas I encountered.

By default, the “Generate Package” command creates a package that is activated via a command. Until you invoke the command, the package isn’t activated. This confused me for a while because I wanted my package to be active when Atom starts up since it passively listens for the onDidSave event.

The trick here is to simply remove the activationCommands section from the package.json file.

"activationCommands": {
  "atom-workspace": "my-package:toggle"

Then, the activation happens when the package is loaded. Many thanks to @binarymuse for that tip!

When you make changes to your extension, you can reload Atom by invoking CTRL + ALT + R. That’ll save you from closing and reopening Atom all the time.

You can invoke the Developer Tools with the CTRL + ALT + I shortcut (similar to CTRL + SHIFT + I for Google Chrome). That’ll allow you to step through the package code with the debugger.

Be sure to check out the Atom API documentation for details about the extensibility points provided by Atom. One of the challenges with Atom is there are so many different ways to extend it it’s hard to know what the best approach is. Over time, I hope we start to gather these best practices.

For example, my package abuses the Panel class slightly by hacking the DOM element created to render the Panel. Panels tend to be a bar that’s docked to the top, bottom, or side of the editor pane. The current API doesn’t support resizing or fading out the Panel. I ended up using a mix of CSS and JavaScript to bend the Panel to my will and create the effect you get when you use this extension.

Maybe there’s a better way, but I love that I had the ability to get this to work. I’ll iterate on the package over time and make it better.

Building and Testing the extension

By default, the extension comes with a few specs. You can run the specs by invoking CTRL + ALT + P. I set up continuous integration (CI) for the package with AppVeyor by following these helpful instructions. I had continuous integration up and running in the matter of minutes.


Publishing an Atom package is super easy. Push your code to a public GitHub repository and then from the repository directory call apm publish patch|minor|major depending on the type of change. The flight manual I mentioned has details on this command.

What’s Next?

I don’t plan on investing a huge amount of time in this extension. It was more an exercise for me to learn about the Atom packaging system. If you’re interested in helping out, I’ve already started logging issues such as being able to set the list of encouragements. I’d welcome the help!

For example, I want to add the ability for those who use the package to set up their own encouragements. Or perhaps, discouragements. I actually find it really funny when my editor shits on my code. In fact, it causes me to think harder about my code because I want to prove it wrong. I should probably stop with all this editor anthropomorphism, huh? Tell me what you think in the comments.

UPDATE: A couple days after publishing this package, Nathan Armstrong (aka armstnp on GitHub) sent me a pull request that implemented the ability to configure the list of encouragements via the Package Settings (Thanks!). This has been published in Encourage v0.2.0. To set this, go to the Settings view, select the Packages tab, and find “encourage” under the Installed Packages section. Then can click the Settings button for the package and update the comma separated list of encouragements.

UPDATE 2: There’s a port for VS Code users now!

nuget comments edit

Yesterday, the NuGet team announced that reached one billion package downloads!

With apologies to everybody for drudging up this tired old meme.

It’s exciting to see NuGet still going strong. As part of the original team that created NuGet, we always had high hopes for its future but were also cognizant of all the things that could go wrong. So seeing hope turn into reality is a great feeling. At the same time, there is still so much more to do. One billion is just a number, albeit a significant and praiseworthy one.

I love that the post calls out the original name for NuGet, aka NuPack. I loved the original name and there was a lot of upset feelings about the change at the time, but the experience taught me an important lesson about naming. Not only is it hard, there will always be a lot of people who will immediately hate whatever name you choose. It takes time for people to adjust to any name. Unless the name is truly terrible like Qwikster. What was that about?

At the time, every name we chose felt wrong, but over time, the name and the identity of the product start to mesh together and now, I can’t imagine any other name other than NuGet. Except for HaackGet. I would have totally been all over that.

Just recently I cleaned out some long neglected DropBox folders and found an old PowerPoint presentation about a design change to the license acceptance flow for packages. Yes, license acceptance sounds like boring stuff but it’s the only remnant I have from the design process back in the day and it’s more interesting than you think if you’re a licensing nerd like me.

We had a goal to make installing packages as frictionless as possible. To that end, we didn’t make license acceptance explicit, but instead we noted that by installing the package, you accept its license and we told you where to find the license. It was a more implicit license acceptance flow that we felt was unintrusive and would serve most package authors fine.

However, this didn’t work for everybody. We had to deal with the reality that some package authors (especially large corporations such as Microsoft) required explicit acceptance of the license before they could install it. So we made this an opt-in feature for package authors which represented itself like so in the GUI.

NuPack License Acceptance Flow Mockup

As you can see, I used Balsamiq to mock up the UI. I used Balsamiq a lot back then to play around with UI mockups. This mockup is from the time when the project was still called NuPack. It’s a fun (to me at least) bit of history.

These days I’m not as involved with NuGet as I used to be, but I have no shortage of opinions on what I hope to see in its future. I may not be contributing to NuGet directly anymore, but I’m still a NuGet package user and author. All of my useful repositories have corresponding packages on

code review, github, code comments edit

As an open source maintainer, it’s important to recognize and show appreciation for contributions, especially external contributions.

We’ve known for a while that after a person’s basic needs are met, money is a poor motivator and does not lead to better work. This seems especially true for open source projects. Often, people are motivated by other intrinsic factors such as the recognition and admiration of their peers, the satisfaction of building something that lasts, or because they need the feature. In the workplace, good managers understand that acknowledging good work is as important if not more so than providing monetary rewards.

This is why it’s so important to thank contributors for their contributions to your projects, big and small.

Seems obvious, but I was reminded of this when I read this blog post by Hugh Bellamy about his experiences contributing to the .NET CoreFX repository. In the post, he describes both his positive and negative experiences. Here’s one of his negative experiences.

In the hustle and bustle of working at Microsoft, many of my PRs (of all sizes) are merged with only a “LGTM” once the CI passes. This can lead to a feeling of lack of recognition of the work you spent time on.

Immo Landwerth, a program manager on the .NET team, gracefully responds on Twitter in a series of Tweets

.@bellamy_hugh Thanks for the valid criticism and the points raised. We’ve started to work so closely with many contributors that team…

@bellamy_hugh …members treat virtually all PRs as if coming from Microsofties. This results reduction to essence, LGTM, and micro speak.

.@bellamy_hugh Quite fair to say that we should improve in this regard!

What I found interesting though was the part where they treat PRs if it came from fellow employees. That’s very admirable! But it did make me wonder, “WHA?! You don’t thank each other!” ;)

To be clear, I have a lot of admiration for Immo and the CoreFX team. They’ve been responsive to my own issues in the past and I think overall they’re doing a great job of managing open source on GitHub. In fact, a tremendous job! (Side note, Hey Immo! Would love to see a new Open Source Update)

This is one of those easy things to forget. In fact, I forgot to call it out in my own blog post about conducting effective code reviews. Recognition makes contributors feel appreciated. And often, all it takes is something small. It doesn’t require a ceremony.

GitHub Selfie to the rescue

However, if you want to add a little bit of ceremony, I recommend the third party GitHub Selfie Extension which is available in the Chrome Web Store as well as for Firefox.

One important thing to note is that this extension does a bit of HTML screen scraping to inject itself into the web page, so when changes its layout, it can sometimes be broken until the author updates it. The extension is not officially associated with GitHub.

I’ve tweeted about it before, but realized I never blogged about it. The extension adds a selfie button for Pull Requests that let you take a static selfie or an animated Gif. My general rule of thumb is to try and post an animated selfie for first time contributions and major contributions. In other cases, such as when I’m reviewing code on my phone, I’ll just post an emoji or animated gif along with a simple thank you.

Here’s an example from the haacked/ repository.

Phil checks the timing

My co-worker improved on it.

Phil's Head Explodes

Here’s an example where I post a regular animated gif because the contributor is a regular contributor.

Dancing machines

However, there’s a dark side to GitHub Selfie I must warn you about. You can start to spend too much time filming selfies when you should be reviewing more code. Mine started to get a bit elaborate and I nearly hurt myself in one.

Phil crash

Octocat involved review

Code review in the car. I was not driving.

Fist pump

These became such a thing a co-worker created a new Hubot command at work .haack me that brings up a random one of these gifs in Slack.

Anyways, I’m losing the point here. GitHub Selfie is just one approach, albeit a fun one that adds a nice personal touch to Pull Request reviews and managing an OSS project. There are many other ways. The common theme though, is that a small word of appreciation goes a long way!

regex comments edit

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems. - Jamie Zawinski

For other people, when confronted with writing a blog post about regular expressions, think “I know, I’ll quote that Jamie Zawinski quote!”

It’s the go to quote about regular expressions, but it’s probably no surprise that it’s often taken out of context. Back in 2006, Jeffrey Friedl tracked down the original context of this statement in a fine piece of “pointless” detective work. The original point, as you might guess, is a warning against trying to shoehorn Regular Expressions to solve problems they’re not appropriate for.

As XKCD noted, regular expressions used in the right context can save the day!

XKCD - CC BY-NC 2.5 by Randall Munroe

If Jeffrey Friedl’s name sounds familiar to you, it’s probably because he’s the author of the definitive book on regular expressions, Mastering Regular Expressions. After reading this book, I felt like the hero in the XKCD comic, ready to save the day with regular expressions.

The Setup

This particular post is about a situation where Jamie’s regular expressions prophecy came true. In using regular expressions, I discovered a subtle unexpected behavior that could have lead to a security vulnerability.

To set the stage, I was working on a regular expression to test to see if potential GitHub usernames are valid. A GitHub username may only consist of alphanumeric characters. (The actual task I was doing was a bit more complicated than what I’m presenting here, but for the purposes of the point I’m making here, this simplification will do.)

For example, here’s my first take at it ^[a-z0-9]+$. Let’s test this expression against the username shiftkey (a fine co-worker of mine). Note, these examples assume you import the System.Text.RegularExpressions namespace like so: using System.Text.RegularExpressions; in C#. You can run these examples online using CSharpPad, just be sure to output the statement to the console. Or you can use to test out the .NET regular expression engine.

Regex.IsMatch("shiftkey", "^[a-z0-9]+$"); // true

Great! As expected, shiftkey is a valid username.

You might be wondering why GitHub restricts usernames to the latin alphabet a-z. I wasn’t around for the initial decision, but my guess is to protect against confusing lookalikes. For example, someone could use a character that looks like an i and make me think they are shiftkey when in fact they are shıftkey. Depending on the font or whether someone is in a hurry, the two could be easily confused.

So let’s test this out.

Regex.IsMatch("shıftkey", "^[a-z0-9]+$"); // false

Ah good! Our regular expression correctly identifies that as an invalid username. We’re golden.

But no, we have another problem! Usernames on GitHub are case insensitive!

Regex.IsMatch("ShiftKey", "^[a-z0-9]+$"); // false, but this should be valid

Ok, that’s easy enough to fix. We can simply supply an option to make the regular expression case insensitive.

Regex.IsMatch("ShiftKey", "^[a-z0-9]+$", RegexOptions.IgnoreCase); // true

Ahhh, now harmony is restored and everything is back in order. Or is it?

The Subtle Unexpected Behavior Strikes

Suppose our resident shiftkey imposter returns again.

Regex.IsMatch("ShİftKey", "^[a-z0-9]+$", RegexOptions.IgnoreCase); // true, DOH!

Foiled! Well that was entirely unexpected! What is going on here? It’s the Turkish İ problem all over again, but in a unique form. I wrote about this problem in 2012 in the post The Turkish İ Problem and Why You Should Care. That post focused on issues with Turkish İ and string comparisons.

The tl;dr summary is that the uppercase for i in English is I (note the lack of a dot) but in Turkish it’s dotted, İ. So while we have two i’s (upper and lower), they have four.

This feels like a bug to me, but I’m not entirely sure. It’s definitely a surprising and unexpected behavior that could lead to subtle security vulnerabilities. I tried this with a few other languages to see what would happen. Maybe this is totally normal behavior.

Here’s the regular expression literal I’m using for each of these test cases: /^[a-z0-9]+$/i The key thing to note is that the /i at the end is a regular expression option that specifies a case insensitive match.

/^[a-z0-9]+$/i.test('ShİftKey'); // false

The same with Ruby. Note that the double negation is to force this method to return true or false rather than nil or a MatchData instance.

!!/^[a-z0-9]+$/i.match("ShİftKey")  # false

And just for kicks, let’s try Zawinski’s favorite language, Perl.

if ("ShİftKey" =~ /^[a-z0-9]+$/i) {
  print "true";    
else {
  print "false"; # <--- Ends up here

As I expected, these did not match ShİftKey but did match ShIftKey, contrary to the C# behavior. I also tried these tests with my machine set to the Turkish culture just in case something else weird is going on.

It seems like .NET is the only one that behaves in this unexpected manner. Though to be fair, I didn’t conduct an exhaustive experiment of popular languages.

The Fix

Fortunately, in the .NET case, there’s two simple ways to fix this.

Regex.IsMatch("ShİftKey", "^[a-zA-Z0-9]+$"); // false
Regex.IsMatch("ShİftKey", "^[a-z0-9]+$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); // false

In the first case, we just explicitly specify capital A through Z and remove the IgnoreCase option. In the second case, we use the CultureInvariant regular expression option.

Per the documentation,

By default, when the regular expression engine performs case-insensitive comparisons, it uses the casing conventions of the current culture to determine equivalent uppercase and lowercase characters.

The documentation even notes the Turkish I problem.

However, this behavior is undesirable for some types of comparisons, particularly when comparing user input to the names of system resources, such as passwords, files, or URLs. The following example illustrates such as scenario. The code is intended to block access to any resource whose URL is prefaced with FILE://. The regular expression attempts a case-insensitive match with the string by using the regular expression $FILE://. However, when the current system culture is tr-TR (Turkish-Turkey), “I” is not the uppercase equivalent of “i”. As a result, the call to the Regex.IsMatch method returns false, and access to the file is allowed.

It may be that the other regular expression engines are culturally invariant by default when ignoring case. That seems like the correct default to me.

While writing this post, I used several helpful online utilities to help me test the regular expressions in multiple languages.

Useful online tools

  • provides a REPL for multiple languages such as Ruby, JavaScript, C#, Python, Go, and LOLCODE among many others.
  • is a Perl REPL since that last site did not include Perl.
  • is a regular expression tester that uses the .NET regex engine.
  • allows testing regular expressions using PHP, JavaScript, and Python engines.
  • allows testing using the Ruby regular expression engine.

hr vacation comments edit

Vacation, All I ever wanted
Vacation, Had to get away
Vacation, Meant to be spent alone
Lyrics by The Go Go’s

Beatnik Beach CC BY-SA 2.0 Photo by Ocad123

When I joined GitHub four years ago, I adored its unlimited paid time off benefit. It’s not that I planned to take a six month trek across Nepal (or the more plausible scenario of playing X-Box in my pajamas for six months), but I liked the message it sent.

It told me this company valued its employees, wanted them to not burn out, and trusted them to behave like stakeholders in the company and be responsible about their vacation.

And for me, it’s worked out well. This, in tandem with our flexible work hours, helps me arrange my work schedule so that I can be a better spouse and parent. I walk my son to the bus stop in the mornings. I chaperone every field trip I can. I take the day off when my kids have no school. It’s great!

I also believe it’s a tool to help recruit great people.

For example, in their famous Culture Deck, Netflix notes that…

Responsible People Thrive on Freedom and are Worthy of Freedom

They go on…

Our model is to increase employee freedom as we grow, rather than limit it, to continue to attract and nourish innovative people, so we have a better chance of sustained success

In one slide they note that “Process-focus Drives More Talent Out”

The most talented people have the least tolerance for processes that serve to curtail their freedom to do their best work. They’d rather be judged by the impact of their work than when and how much they worked.

This is why Netflix also has a policy that there is no vacation policy. They do not track vacation in the same way they do not track hours worked per day or week.


As you might expect, there are some subtle pitfalls to such a policy or lack thereof. I believe such policies that rely on the good judgment of individuals are well intentioned, but often ignore the very real psychological and sociological factors that come into play with such policies.

Only the pathologically naïve employee would believe they can go on a world tour for twelve months and expect no repercussions when they return to work.

In the absence of an explicit policy, there’s an implicit policy. But it’s an implicit policy that in practice becomes a big game of Calvinball where nobody understands the rules.

But unlike Calvinball where you make the rules as you go, the rules of vacationing are driven by subtle social cues from managers and co-workers. And the rules might even be different from team to team even in a small company because of different unspoken expectations.

At GitHub, this confusion comes into sharp relief when you look at our generous parental policy. GitHub provides four months of paid time off for either parent when a new child enters the family through birth or adoption. I love how family friendly this policy is, but it raises the question, why is it necessary when we already have unlimited paid time?

Well, one benefit of this policy, even if it seems redundant, is that it sets the right expectations of what is deemed reasonable and acceptable.

Travis CI (the company) realized this issue in 2014.

When everyone keeps track of their own vacation days, two things can happen. They either forget about them completely, or they’re uncertain about how much is really okay to use as vacation days.

They also noted that people at companies with unlimited time off tend to take less time off or work here and there during their vacations.

A short-sighted management team might look at this as a plus, but it’s a recipe for burnout among their most committed employees. Humans need to take a break from time to time to recharge.

Travis CI took the unusual step of instituting a minimum vacation policy. It sets a shared understanding of what is considered an acceptable amount of time to take.

In talking about this with a my friend Drew Miller, he had an astute observation. He noted that while such a policy is a good start, it doesn’t address the root cause. A company with no vacation policy where people don’t take vacation should take a deep look at its culture and ask itself, “What about our culture causes people to feel they can’t take time off?”

For example, and the Travis-CI post notes this, leaders at a company have to model good behavior. If the founders, executives, managers, take very little vacation, they unconsciously communicate to others that going on vacation is not valued or important at this company.

His words struck me. While I like the idea of a minimum vacation to help people feel more comfortable taking vacation, I feel such a move has to be in tandem with a concerted effort to practice what we preach.

Ever since then, as a manager, I’ve tried to model good responsible vacation behavior. Before I take off, I communicate to those who need to know and perform the necessary hand-offs. And more importantly, while on vacation, I disconnect and stay away from work. I do this even though I sometimes want to check work email because I enjoy reading about work. I abstain because I want the people on my team to feel free to do the same when they are on vacation.

Apparently I’ve done a good job of vacationing because somebody at GitHub noticed. We have an internal site called Team that’s sort of like an internal Twitter and then some. One fun feature is that anybody at GitHub can change your team status. At one point, I returned from vacation and noticed my status was…

I can live with that!

It’s since been changed to “Supreme Vice President.” It’s a long story.

github csharp dotnet scientist comments edit

Over on the GitHub Engineering blog my co-worker Jesse Toth published a fascinating post about the Ruby library named Scientist we use at GitHub to help us run experiments comparing new code against the existing production code.

Photo by tortmaster on flickr - CC BY 2.0

It’s an enjoyable read with a really great analogy comparing this approach to building a new bridge. The analogy feels very relevant to those of us here in the Seattle area as we’re in the midst of a major bridge construction project across Lake Washington as they lay a new bridge alongside the existing 520 bridge.

Naturally, a lot of people asked if we were working on a C# version. In truth, I had been toying with it for a while. I had hoped to have something ready to ship on the day that Scientist 1.0 shipped, but life has a way of catching up to you and tossing your plans in the gutter. The release of Scientist 1.0 lit that proverbial fire under my ass to get something out that people can play with and help improve.

Consider this a working sketch of the API. It’s very rough, but it works! I don’t have a CI server set up yet etc. etc. I’ll get around to it.

The plan is to start with this repository and once we have a rock solid battle tested implementation, we can move it to the GitHub Organization on If you’d like to participate, jump right in. There’s plenty to do!

I tried to stay true to the Ruby implementation with one small difference. Instead of registering a custom experimentation type, you can register a custom measurement publisher. We don’t have the ability to override the new operator like those Rubyists and I liked keeping publishing separate. But I’m not stuck to this idea.

Here’s a sample usage:

public bool MayPush(IUser user)
  return Scientist.Science<bool>("may-push", experiment =>
      experiment.Use(() => IsCollaborator(user));
      experiment.Try(() => HasAccess(user));

As expected, you can install it via NuGet Install-Package Scientist -Pre


semver comments edit

A long time request of (just shy of five years!) is to be able to link to specific headings and clauses of the Semver specification. For example, want to win that argument about PATCH version increments? Link to that section directly.

Today I pushed a change to that implements this. Go try it out by hovering over any section heading or list item in the main specification section! Sorry for the long delay. I hope to get the next feature request more promptly, like in four years.

In this post, I discuss some of the interesting non-obvious challenges in the implementation, some limitations of the implementation, and my hope for the future.


The Semver specification is hosted in a different GitHub repository than the website.

The specification itself is a markdown file named When I publish a new release, I take that one file, rename it to, and replace this file with it. Actually, I do a lot more, but that’s the simplified view of it.

The site is a statically generated Jekyll site hosted by the GitHub Pages system. I love it because it’s so simple and easy to update.

So one of my requirements was to require zero changes to when publishing a new version to the web. I wanted to make all transformations outside of the document to make it web friendly.

However, this meant that I couldn’t easily control adding HTML id attributes to relevant elements. If you want add links to specific elements of an HTML page, giving elements an ID gives you a nice anchor target.

Fortunately, there’s a Markdown renderer supported by GitHub that generates IDs for headings. Up until now, was using rdiscount. I switched it to use Kramdown. Kramdown generates heading IDs by default.

But there’s a problem. It doesn’t generate IDs for list items. Considering the meat of the spec is in the section with list items, you would guess people would want to be able to link to a specific list item.

I explored using AnchorJs which is a really wonderful library for adding deep anchor links to any HTML page. You give the library a CSS selector and it’ll both generate IDs for the elements and add a nice hover link to link to that anchor.

Unfortunately, I couldn’t figure out a nice way to control the generated IDs. I wanted a nice set of sequential IDs for the list items so you could easily guess the next item.

I thought about changing the list items to headings, but I didn’t want to change the original markdown file just for the sake of its rendering as a website. I think the ordered list is the right approach.

My solution was to implement a specific implementation in JavaScript to add IDs to the relevant list items and then add a hover link to all elements in the document that has an ID.

This solves things in the way I want, but it has one downside. If a user has JavaScript disabled, deep links to the list items won’t work. I can live with that for now.

My hope is that someone will add support for generated list item IDs in Kramdown. I would do it, but all I really wanted to do was add deep links to this document. Also, my Ruby skills are old Ford mustang sitting on the lawn on concrete blocks rusty.

If you have concerns or suggestions about the current implementation, please log an issue here.


In 2016, I hope to release Semver 3.0. But I don’t want to do it alone. I’m going to spend some time thinking about the best way to structure the project moving forward so those with the most skin in the game are more involved. For example, I’d really like to have a representative from NPM, NuGet, Ruby Gems, etc. work closely with me on it.

I unfortunately have very little time to devote to it. On one level, that’s a feature. I believe stability is a feature for a specification like this and constant change creates a rough moving target. On the other hand, the world changes and I don’t want Semver to become completely irrelevant to those who depend and care about it most.

Anyways, this change is a small thing, but I hope it works well for you.

personal comments edit

I have a big problem as a dad.

For the most part, my kids are wonderful. Like most kids, they have their infuriating moments. But that’s not the problem of which I speak. It may help for me to describe one such scenario.

My family and I are in Portland for a brief trip. As I drove around an unfamiliar location, my daughter asked the typical question kids ask as a form of advanced psychological torture, “Are we there yet?”

This wasn’t so bad. My wife calmly explained to my daughter not to ask that again because she’d already done so several hundred times. She then asked my daughter what the consequence should be if she asks again and they started negotiating about the consequence of that action.

Not long after, my daughter repeatedly poked my ear with a stick made of straws as I drove. We have a strict and, in my humble opinion, eminently reasonable rule not to distract the driver. My wife calmly told my daughter that the consequence of that action next time would be to break the stick.

Now if you’ve ever seen or met my daughter, she’s a delightful joyful child who’s usually all bright eyes and big smiles. She can also be a bit mercurial. Like most kids, that temper burns a little hotter when she’s hungry.

At being admonished, she started whimpering and crying. But then, out of nowhere, she screams with the full fury of her six year old being, “Try it and I’ll kill you!”

public domain image

My eyes went wide and I looked at my wife in shock mouthing “Holy fuck!” As I searched for the words to convey to my daughter the gravity of how wrong it was to say that, I bust out laughing. Out loud. Uncontrollably.

The intense incongruity of this little bundle of cuteness screaming such an over the top aggressive threat was too comical and I could not keep a straight face.

Of course, this is the wrong reaction for so many reasons. For one, it could encourage such behavior. Or worse, it might appear that I’m mocking her feelings.

And this is my problem. This isn’t the first time she let out her outsized rage that spurred uncontrollable laughter on my part. Of course I struggle to take a serious tone and talk through her feelings with her, but I can’t help to take an outside view of the situation and see how funny it is.

Fortunately, we apply the principle of failure and repair and talked it through after my laughter subsided. She recognized her words were hurtful and apologized. We then had lunch and she’s back to her sweet full of joy self. Until next time.

personal comments edit

I planned to skip the tried and true year in review post because who reads such drivel anyways, amirite? They feel like one big exercise in vanity.

But it dawned on me. Perhaps, I lost touch with what blogging was all about. What it’s always been all about. Hasn’t it always been one big unabashed and unashamed exercise in vanity?

Though writers better than me tend to couch it as something that sounds more virtuous with words like “write for yourself” and such while they smirk awash in the glow of their laptop screen with a giant glamour shot of themselves on the wall.

So, um, yeah. I write for myself. But when others than your close friends and family (well, my family long since stopped reading it) start to read it, it’s easy to lose sight of that fact. Also, I’m on a train to Portland and I don’t really have anything much better to do.

So on that note, here it is, my look back at 2015.

new year celebration


.NET on the Fringe

As one of the organizers of the conference, I had the great pleasure to deliver the closing talk about a topic near and dear to me, Social Coding. The conference had a great infectious energy and many people told me it inspired them to make their first commit to open source.

Nearly dying in Puerto Rico

Ok, I didn’t really almost die, but I was really really uncomfortable. I did have a wonderful time speaking about GitHub to the Latin American audience and exploring the old forts like I was inside Assassin’s Creed Black Flag. In 2016 I’ll be speaking in Peru!

The release of GitHub Extension for Visual Studio

This was a fun collaboration with Microsoft and represents just the beginning. We later made it open source! In 2016, we plan to invest a lot more time and energy into the extension to make your experience working with GitHub projects from Visual Studio better.

DevInteresections EU

I had the pleasure to speak at DevIntersections EU in Amsterdam. It was my first time in Amsterdam and I immediately loved it. The week of the conference just happened to coincide with ADE (Amsterdam Dance Event) so there were a lot of great music events to check out. One of my favorite sites though was the library I went to with the infamous Mr. Hanselman and a local friend of his.


QCon is an international collection of conferences and the organizers asked me to chair the the first .NET track in a long while and the second one ever. They mentioned that the first one didn’t go so well.

The title of the track was The Amazing Potential of .NET Open Source. I wanted to highlight all the wonderful things happening in the .NET world in the wake of Microsoft making a big splash on GitHub. But I also focused on talks I thought would have crossover appeal to those who are not .NET developers.

I am eternally grateful to the speakers who accepted my invitation and delivered a knockout track. Our track ended up being the top rated track based on attendee voting of the conference. So I think this .NET thing still has legs. It probably helped that I didn’t speak at the conference.


This year the family and I didn’t take any major vacations. We did go on an outing to Lake Chelan and got caught in a wild fire. My wife and I went to Vancouver for a couple days to see a concert which was a lot of fun. Next year we’re doing a proper vacation to Maui with another family which should be a lot of fun.

Looking to 2016

I’m really looking forward to 2016. My team has a new focus to make GitHub great for .NET developers and I can’t wait to dive into that.

It’s tough on my kids when I travel, so I try not to speak at too many conferences, but there’s so many good ones around these days. So far, I plan to speak at a DevDays in Peru. I’m also hoping to return to NDC in Oslo, which will be exciting.

Other than that, I haven’t really confirmed anywhere else. Perhaps we’ll throw another .NET Fringe. I’m hoping to reach some new audiences in some new places so we’ll see what the year has in store.

Happy New Year!

csharp style code comments edit

Like many developers, I have many strong opinions about things that really do not matter. Even worse, I have the vanity to believe other developers want to read about it.

For example, a recent pull request changed all instances of String to string. As a reminder, String actually represents the type System.String and string is the nice C# alias for System.String. To the compiler, these are the exact same thing. So ultimately, it doesn’t really matter.

However, as I just said, I care. I care about things that don’t matter.

Resharper, a tool we use to maintain our code conventions, by default suggests changing all String to string. But this doesn’t fit the convention we follow.

To understand the convention I have in my head, it probably helps to think about why are there aliases in the first place for these types.

I’m not really sure, but types like string and int feel special to me. They feel like primitives. In C#, keywords are lowercase. So in my mind, when we’re using these types in this manner, they should be lowercase. Thus my convention is to lowercase string and int any time we’re using them in a manner where they feel like a keyword.

For example,

int x;
string foo;
string SomeMethod();
void AnotherMethod(string x);
public string Foo { get; }

But when we’re using it to call static methods or calling constructors on these types, I want it to look like a normal type. These constructs don’t look like you’re using a keyword.

var foo = String.Empty;
String.Format("blah{0}", "blah");
var baz = new String();

Maybe I’m being too nitpicky about this. For those of you who also care about unimportant things, I’m curious to hear what your thoughts on this matter. Is it possible to configure R# or other tools to enforce this convention?


One of the reasons I follow this convention is for readability. When things don’t fit my expectations a tiny bit of extra processing is needed. So as I’m scanning code in Visual Studio and I see keyword.MethodCall it takes a second.

Having said that, a commenter noted that the corefx coding guidelines always use lowercase. And one of my principles with coding conventions is I tend to adopt something I feel is something of a widespread standard even if I disagree with it because at the end of the day, these are all mostly arbitrary and rather than spend a lot of time arguing, I’d rather just point to something and say “We’re doing it that way because why not?” That’s why I tend to follow the Framework Design Guidelines for example.

Having said that, I still need to let this one sink in.

git github console shell comments edit

GitHub Desktop, the application formerly known as GitHub for Windows, is a streamlined GUI that makes it easy to contribute to repositories on GitHub.

GitHub Desktop Screenshot

At the same time, I often hear from people that they don’t need a GUI because they’re perfectly happy to use the command line. If you feel this way, that’s great! I love the command line too! Let’s be friends!

Even so, in a set of blog posts I plan to write, I hope to convince you that GitHub Desktop is one GUI application that augments and complements the Git command line in such a powerful way that you’ll want to integrate it into your GitHub workflow.

But for now, I’ll work to convince you that GitHub Desktop is the easiest, fastest, and best way to get the Git command line set up on a Windows machine and keep that installation up to date.


Installation is easy. Visit and click the big blue button that says “Download GitHub Desktop.” We use ClickOnce to streamline the installation process.

Once you install, you’ll notice a GitHub icon and a Git Shell Icon on your desktop.

GitHub Desktop Icons

By default, the Git Shell shortcut launches PowerShell with Git set up. You can also launch the Git Shell from the Desktop GUI application by pressing the ~ key (or CTRL + ~ at any time such as when a text field has focus) or via the gear menu in the top right. Select the “Open in Git Shell” menu item.

Support for the ~ key to launch the shell was inspired by the 3D shooter Quake which uses that key to bring up the console within the game. Many thanks to Scott Hanselman for that idea.

Sane Defaults

We often mention that we install Git with “sane defaults.” What do we mean by that? Well, let me tell you an old joke first.

Q: How do you generate a random string? A: Put a Windows user in front of vi, and tell them to exit

I can’t take credit for this joke. The first instance I’ve found is on Twitter by Aaron Jorbin.

By default, Git sets vi as the default commit editor. Statistically speaking, that’s never the right answer for Windows users. GitHub Desktop sets your default editor (typically NotePad) as the default editor via the open source GitPad tool.

Also, GitHub Desktop sets itself up as the Git credential provider. That way, you can log into the app and we’ll handle the credential management when you push to or pull from GitHub using the Git command line. This is especially useful if you have two-factor authentication enabled (WHICH YOU SHOULD!) as we handle the 2fa dance on your behalf. There’s no need for messing around with personal access (OAuth) tokens.


The other “sane default” is that we include Posh-Git (maintained by Keith Dahlby) with our installation.

When you launch the shell, you’ll notice that the Powershell window now has a Git enhanced prompt that displays your current branch name. Posh-Git provides tab completion within PowerShell for Git commands and Git data. For example, you can type git {TAB}, where {tab} is the TAB key, and it will complete with the first Git command (abort in this case). Keep pressing TAB to cycle through all the Git commands.

Likewise, if you type git checkout b{tab}, you can cycle through all branches in your repository that start with b.

Here is an animated gif that shows what it looks like to tab through all my repository’s branches.

Posh-Git Tab Expansion

PowerShell Configuration

One thing to note is that if you launch PowerShell via some other means other than our Git Shell shortcut or the Desktop application, our version of Git won’t be there. That’s because we install a portable version of Git that does not change any of your system settings.

You can add our version of Git to your PowerShell profile so it’s always there. Simply edit the PowerShell profile document: %UserProfile%\Documents\WindowsPowershell\Microsoft.Powershell_profile.ps1

Add this snippet to the file.

Write-Host "Setting up GitHub Environment"
. (Resolve-Path "$env:LOCALAPPDATA\GitHub\shell.ps1")

Shell.ps1 contains the environment settings that the Desktop application uses when it launches the Git Shell.

You can also have your default profile load up Posh-Git if you haven’t already. Make sure this snippet comes after the previous one.

Write-Host "Setting up Posh-Git"
. (Resolve-Path "$env:github_posh_git\profile.example.ps1")

$env:github_posh_git is one of the environment variables that Shell.ps1 sets up.

The other thing to note is if you have already customized PowerShell with a profile, the Git Shell doesn’t load your existing PowerShell profile. We wanted to avoid conflicts with existing Posh-Git installs or whatever else you might have. To load your existing profile requires you to opt into this behavior. To do this, create a PowerShell script file named GitHub.PowerShell_profile.ps1. Desktop will execute this file, if it exists.

Desktop looks for this file in the same directory as your $profile script (typically %UserProfile%\Documents\WindowsPowershell\). I simply load my regular profile from that script.

Here’s the full contents of my GitHub.PowerShell_profile.ps1.

Write-Host "Setting environment for GitHub Powershell Profile"

$dir = (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent)
Push-Location $dir

. (Resolve-Path "$dir\Microsoft.Powershell_profile.ps1")


Turbocharge the Shell with ConsoleZ

Hey, you’re an individual and you need to express that individuality. Nothing says “I’m boring” like the default blue PowerShell console (if you do always use the default, ignore what I just said. You might be the real noncomformist). I express my individuality with a fork of Console2 called ConsoleZ just like every one of my friends! If you have Chocolatey installed, you can run this command to install ConsoleZ:

chocolatey install ConsoleZ

Then in GitHub Desktop, go to the Tools menu (top right gear icon), select Options..., and find the section labeled Default Shell. Select Custom and enter the path to ConsoleZ. On my machine, that’s C:\Chocolatey\lib\ConsoleZ.\tools\Console.exe.

Default Shell

You’re not quite done yet. By default, ConsoleZ loads the Command shell. You’ll want to change it so it loads PowerShell.

  • Right-click in the main console and click Edit Settings.
  • Under Tabs, paste the path %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe into the “Shell” text box.

ConsoleZ Tab Settings

You’ll notice I got a little fancy and use the Git Shell icon for the tab. I put icon here (or use our Octocat App Icon) so you can download it and do the same if you’d like. I saved the icon to the %LocalAppData%\GitHub\icons directory and then pasted the path to the Icon in the Icon text box.

Customize ConsoleZ

That’s just enough to make ConsoleZ work with Desktop. But since you’ll spend a lot of time in the shell, let’s really turbo charge it. Here is a set of customizations adapted from Scott Hanselman’s Console2 blog post. I’ve made a few small tweaks in places to ensure that the customizations don’t interfere with the Git Shell functionality.

  • Under the Console tab, do not enter a value for the “Startup Dir” setting as Hanselman suggests. When you launch the Git Shell from the Desktop application, it will set the working directory to the currently selected repository’s working directory. If you set ConsoleZ’s startup directory, then that feature of Desktop is overridden. If you don’t care about this feature, by all means set a startup directory.
    • Under the Console tab, do play around with the Columns and Rows. I have mine set to 30 rows, and 80 columns.
  • Under Appearance More, hide the menu, status bar and toolbar.
  • Under Appearance Font, set the font to Consolas 15. Unlike Hanselman’s advice, do not change the font color. Posh-Git makes important use of color. Not to mention the output of many Git commands will use color to signify additions and deletions, for example. If you want to change the default font color, do it via your PowerShell profile or by hacking Posh-Git.
  • Under Appearance Transparency, Hanselman recommends setting Window Transparency to a nice conservative 40 for both Active and Inactive. I like setting Inactive to 80. Your mileage may vary.
  • Under Hotkeys, set “Group Tab” to something else like CTRL+ALT+T. This frees you up to change the “New Tab 1” hotkey to CTRL+T as God intended. You’ll have to click on the hotkey, then in the textbox, then type the hot-key you want AND press the Assign button for it to stick.
  • Under Hotkeys, change “Copy Selection” to Ctrl-C and “Paste” to Ctrl-V

Here’s what it looks like on my machine. You can see my background image poking through.

Customized ConsoleZ

Finally, one setting that makes ConsoleZ feel really badass to me is to go to Appearance Full Screen and check “Start in full screen”. I’ve been using this for a bit and it’s growing on me. Just remember, hit ALT+F4 or type exit to close it.


We put in a lot of work to ensure that GitHub Desktop silently and automatically updates itself. When we ship an update, you’ll see a subtle notification in the application (a little up arrow in the top right) that an update is available. Just restart the application to install the update.

Desktop updates also include updates to Posh-Git, the Git command line, and Git LFS. It’s convenient to have all of that updated for you automatically so you don’t have to track down each update individually.

We keep everything updated so you don’t have to.


With these customizations in place, you’ll have a really great Git command line setup that we’ll work hard to keep up to date so you don’t have to. In fact, we have a few updates coming up very soon! Follow this up with some of my Git aliases and you’ll really be smoking.

Be careful though, a setup like this communicates that you’re a Git Pro and everyone will start to bug you with their Git problems. Just remember, git reflog is your friend.

In some follow-up posts, I’ll demonstrate how this setup works really nicely in tandem with GitHub Desktop.

work comments edit

The TED Radio Hour podcast has an amazing episode entitled “The Meaning of Work”. It consists of four segments that cover various aspects of finding meaning and motivation at work. You should definitely listen to it, but I’ll provide a brief summary here of some points I found interesting.

The first segment features Margaret Heffernan who gave this TED talk about what makes high functioning teams.

At the beginning of the talk, she recounts a study by the biologist William Muir, emphasis mine.

Chickens live in groups, so first of all, he selected just an average flock, and he let it alone for six generations. But then he created a second group of the individually most productive chickens – you could call them superchickens – and he put them together in a superflock, and each generation, he selected only the most productive for breeding.

After six generations had passed, what did he find? Well, the first group, the average group, was doing just fine. They were all plump and fully feathered and egg production had increased dramatically. What about the second group? Well, all but three were dead. They’d pecked the rest to death. The individually productive chickens had only achieved their success by suppressing the productivity of the rest.

Sound familiar? We’re often taught that great results come from solitary geniuses who bunker down to work hard and emerge some time later with some great work of genius to bestow upon the world, alongside a luxurious beard perhaps.

Jim Carrey in some movie

But it’s a myth. Great results come from deep collaborations among teams of people who trust each other. Heffernan goes on to cite an MIT study that noted what lead to high functioning teams.

Nor were the most successful groups the ones that had the highest aggregate I.Q. Instead, they had three characteristics, the really successful teams. First of all, they showed high degrees of social sensitivity to each other. This is measured by something called the Reading the Mind in the Eyes Test. It’s broadly considered a test for empathy, and the groups that scored highly on this did better. Secondly, the successful groups gave roughly equal time to each other, so that no one voice dominated, but neither were there any passengers. And thirdly, the more successful groups had more women in them.

People who are attuned to each other, who can talk to each other with trust, empathy, and candor, create an environment where ideas can really flow. It’s wonderful to work in such an environment.

Another thing that struck me in the Radio Hour interview is this exchange she describes she often has with businesses.

What’s the driving goal here? And they answer, $60 billion in revenue. And I’ll say, “you have got to be joking! What on earth makes you think that everybody is really going to give it their all to hit a revenue target. You know you have to talk to something much deeper inside people than that. You have to talk to people about something that makes a difference to them everyday if you want them to bring their best and do their best and feel that you’ve given them the opportunity to do the best work they’ve ever done.”

This resonates with me. Revenue and profit targets don’t put a spark in my step in the morning.

Rather, it’s the story of Anna and how my own kids reflect that story that get me motivated. I’m excited to work on a platform that the future makers of the world will use to build their next great ideas.

I don’t mind getting paid well, but it doesn’t produce a deep connection to my work. As Heffernan points out,

For decades, we’ve tried to motivate people with money, even though we’ve got a vast amount of research that shows that money erodes social connectedness.

That lesson is reiterated in Drive: the surprising truth about what motivates us which I’ve linked to many times in the past.

What gets me up in the morning with a spring in my step is working on a platform that houses the code that helps send people into space or coordinates humanitarian efforts here on earth.

What motivates you?

Oh, by the way, many teams at GitHub including mine are hiring. Come do meaningful work with us!

hiring industry comments edit

The shaman squatted next to the entrails on the ground and stared intently at the pattern formed by the splatter. There was something there, but confirmation was needed. Turning away from the decomposing remains, the shaman consulted the dregs of a cup of tea, searching the shifting patterns of the swirling tea leaves for corroboration. There it was. A decision could be made. “Yes, this person will be successful here. We should hire this person.”

Spring Pouchong tea - CC BY SA 3.0 by Richard Corner

Such is the state of hiring developers today.

Our approach to hiring is misguided

The approach to hiring developers and managing their performance afterwards at many if not most tech companies is based on age old ritual and outdated ideas of what predicts how an employee will perform. Most of it ends up being very poor at predicting success and rife with bias.

For example, remember when questions like “How would you move Mt. Fuji?” were all the rage at companies like Microsoft and Google? The hope was that in answering such questions, the interviewee would demonstrate clever problem solving skills and intelligence. Surely this would help hire the best and brightest?


According to Google’s Senior VP of People Operations Laszlo Bock, Google long ago realized these questions were complete wastes of time.

Years ago, we did a study to determine whether anyone at Google is particularly good at hiring. We looked at tens of thousands of interviews, and everyone who had done the interviews and what they scored the candidate, and how that person ultimately performed in their job. We found zero relationship.

We’re not the first to face this

Our industry is at a stage where we are rife with superstition about what factors predict putting together a great team. This sounds eerily familiar.

The central premise of Moneyball is that the collected wisdom of baseball insiders (including players, managers, coaches, scouts, and the front office) over the past century is subjective and often flawed. Statistics such as stolen bases, runs batted in, and batting average, typically used to gauge players, are relics of a 19th-century view of the game and the statistics available at that time.

Moneyball, a book by Michael Lewis documents how the Oakland Athletics baseball team decided to ignore tradition and use an evidence-based statistical approach to figuring out what makes a strong baseball team. This practice of using empirical statistical analysis towards baseball became known as sabermetrics.

Prior to this approach, conventional wisdom looked at stolen bases, runs batted in, and batting average as indicators of success. Home run hitters were held in especially high esteem, even those with low batting averages. It was not unlike our industry’s fascination with hiring Rock Stars. But the sabermetrics approach found otherwise.

Rigorous statistical analysis had demonstrated that on-base percentage and slugging percentage are better indicators of offensive success.

Did it work?

By re-evaluating the strategies that produce wins on the field, the 2002 Athletics, with approximately US$44 million in salary, were competitive with larger market teams such as the New York Yankees, who spent over US$125 million in payroll that same season…This approach brought the A’s to the playoffs in 2002 and 2003.

Moneyball of Hiring

It makes me wonder, where is the Moneyball of software hiring and performance management?

Companies like Google, as evidenced by the previously mentioned study, are applying a lot of data to the analysis of hiring and performance management. I bet that analysis is a competitive advantage in their ability to hire the best and form great teams. It gives them the ability to hire people overlooked by other companies still stuck in the superstition that making candidates code on white boards or reverse linked lists will find the best people.

Even so, this area is ripe to apply more science to it and study it on a grander scale. I would love to see multiple large companies collect and share this data for the greater good of the industry and society at large. Studies like this often are a force in reducing unconscious bias and increasing diversity.

Having this data in the open might remove this one competitive advantage in hiring, but companies can still compete by offering interesting work, great compensation, and benefits.

The good news is, there are a lot of people and companies thinking about this. This article, What’s Wrong with Job Interviews, and How to Fix Them is a great example.

We’ll never get it right

Even with all this data, we’ll never perfect hiring. Studying human behavior is a tricky affair. If we could predict it well, the stock market would be completely predictable.

Companies should embrace the fact that they will often be wrong. They will make mistakes in hiring. As much time as a company spends attempting to make their hiring process rock solid, they should also spend a similar amount of time building humane systems for correcting hiring mistakes. This is a theme I’ve touched upon before - the inevitability of failure.

github jekyll pages comments edit

A while back I migrated my blog to Jekyll and GitHub Pages. I worked hard to preserve my existing URLs.

But the process wasn’t perfect. My old blog engine was a bit forgiving about URLs. As long as the URL “slug” was correct, the URL could have any date in it. So there happened to be quite a few non-canonical URLs out in the wild.

So what I did was create a 404 page that had a link to log an issue against my blog. GitHub Pages will serve up this page for any file not found errors. Here’s an example of the rendered 404 page.

And the 404 issues started to roll in. Great! So what do I do with those issues now? How do I fix them?

GitHub Pages fortunately supports the Jekyll Redirect From plugin. For a guide on how to set it up on your GitHub Pages site, check out this GitHub Pages help documentation.

Here’s an example of my first attempt at front-matter for a blog post on my blog that contains a redirect.

layout: post
title: "Localizing ASP.NET MVC Validation"
permalink: /404.html
date: 2009-12-07 -0800
comments: true
disqus_identifier: 18664
redirect_from: "/archive/2009/12/12/localizing-aspnetmvc-validation.aspx"
categories: [aspnetmvc localization validation]

As you can see, my old blog was an ASP.NET application so all the file extensions end with .aspx. Unfortunately, this caused a problem. GitHub currently serves unknown extensions like this using the application/octet-stream content type. So when someone visits the old URL using Google Chrome, instead of a redirect, they end up downloading the HTML for the redirect. It happens to work on Internet Explorer which I suspect does a bit of content sniffing.

It turns out, there’s an easy solution as suggested by @charliesome. If you add the .html extension to a Jekyll URL, GitHub Pages will handle the omission of the extension just fine.

Thus, I fixed the redirect like so:

redirect_from: "/archive/2009/12/12/localizing-aspnetmvc-validation.aspx.html"

By doing so, a request for is properly redirected. This is especially useful to know for those of you migrating from old blog engines that appended a file extension other than ``.html` to all post URLs.

Also, if you need to redirect multiple URLs, you can use a Jekyll array like so:

  - "/archive/2012/04/15/The-Real-Pain-Of-Software-Development-2.aspx.aspx.html/"
  - "/archive/2012/04/15/The-Real-Pain-Of-Software-Development-2.aspx.html/"

Note that this isn’t just useful for blogs. If you have a documentation site and re-organize the content, use the redirect_from plug-in to preserve the old URLs. Hope to see your content on GitHub Pages soon!

github git oss comments edit

Writing extensions to Visual Studio is really hard. As in turn your hair gray hard. In fact, I now have gray hairs and I didn’t when I started the GitHub Extension for Visual Studio project (true story).

Some of the challenge is in the fact that Visual Studio has been around a long time and has accumulated multiple different extensibility systems (such as DTE and MEF) and points (such as Editor extensions and Project Systems) to learn. But that’s not the real challenge. The real challenge is that Visual Studio is so flexible and offers so many extensibility points that it can be hard to figure out where to start. It’s almost too much of a good thing.

Fortunately, Andreia and I had the help of the Visual Studio team at Microsoft as we worked together to add GitHub features to the release candidate for Visual Studio 2015 last April. Not to mention the fact that Andreia has more Visual Studio extensibility experience in her pinky than ten of me would have.

Well today Microsoft announced the RTM of Visual Studio 2015. Congratulations!

Glad I dry cleaned the tux for this occasion

We figured, what better time than now to open up the code we used to build the extension? In discussions with the Visual Studio team, we all agreed that the more real world examples of Visual Studio extensions are out there, the better for everyone. This is in part why we released the GitHub Extension for Visual Studio under the MIT license today.

The Future

I’ll be honest with you, the extension doesn’t do a whole lot today. What it does do is important, it handles the authentication aspects (including two-factor authentication) of working with Git and GitHub. It makes it easy to clone repositories into Visual Studio as well as publishing new projects.

But we plan to do so much more. Our next major feature will add support for creating Pull Requests right from Visual Studio similar to the way GitHub for Windows supports it.

Get involved!

If this sort of thing appeals to you, we’d love to have you participate. Every contribution matters whether it’s logging an issue or submitting a pull request.

On a personal level, this has been a fun project for me. The idea of extending my primary development environment has always appealed to me, but I never felt I had the time to learn how.

It was great to work with people who are world class experts in this environment. I learned a huge amount. Not to mention the fact that even though I’m a manager now and don’t get to code as much as I used to, I made an exception (out of necessity) and spent a lot of time writing code for this project which made me very happy.

Preparing for this project is what lead me to write the Encourage Extension (shameless plug).

science holography comments edit

This past week I learned a new party trick. I can turn a holographic researcher beet red by simply referencing Tupac’s Hologram. It’s not because they identify strongly with East Coast hip-hop. Rather, it has to do with calling it a hologram in the first place.

Tupac's Peppers Ghost

A hologram is a very specific effect taking advantage of interference and refraction of light. As Wikipedia describes it,

Normally, a hologram is a photographic recording of a light field, rather than of an image formed by a lens, and it is used to display a fully three-dimensional image of the holographed subject, which is seen without the aid of special glasses or other intermediate optics. … When suitably lit, the interference pattern diffracts the light into a reproduction of the original light field and the objects that were in it appear to still be there, exhibiting visual depth cues such as parallax and perspective that change realistically with any change in the relative position of the observer.

The Tupac “hologram” was a variant of Pepper’s Ghost which is a technique that’s been described as early as the 16th century by Giambattista della Porta:

Let there be a chamber wherein no other light comes, unless by the door or window where the spectator looks in. Let the whole window or part of it be of glass, as we used to do to keep out the cold. But let one part be polished, that there may be a Looking-glass on bothe sides, whence the spectator must look in. For the rest do nothing. Let pictures be set over against this window, marble statues and suchlike. For what is without will seem to be within, and what is behind the spectator’s back, he will think to be in the middle of the house, as far from the glass inward, as they stand from it outwardly, and clearly and certainly, that he will think he sees nothing but truth. But lest the skill should be known, let the part be made so where the ornament is, that the spectator may not see it, as above his head, that a pavement may come between above his head. And if an ingenious man do this, it is impossible that he should suppose that he is deceived.

I learned this recently at a Microsoft Research Faculty Summit that brought together leading experts in machine vision, natural language processing, AI, etc. I was there to be on a panel about what academia could learn from the open source community. I’ll write more about this later when the video becomes available.

At the conference reception dinner, I found myself in a conversation with some pioneers of holography and machine vision. During most of the conversation I wisely kept my mouth shut and did my best bobblehead impression.

However, at one point I did open my mouth just long enough to betray my complete ignorance on the topic, asking the researchers about the Tupac Hologram. Dark clouds gathered overhead casting a pall on the once bright conversation. To their credit, with beads of sweat rolling off their foreheads under the strain of self-control, the researchers politely and calmly educated me about holography. One key aspect of a hologram is that it does not require special equipment to see it. It’s a thing of beauty. It appears to be right there.

By that definition, it occurred to me that HoloLens therefore isn’t a true hologram either. This came up in the conversation (but not by me as I decided to continue keeping my mouth shut) and the HoloLens researcher noted that while true, it’s much closer to the experience of a hologram than using the Pepper’s Ghost technique. So while it makes him cringe as someone who understands the distinction, it doesn’t make him as angry as it used to.

So next time the topic of HoloLens comes up and someone uses the term holgram, you can pull an epic Well, Actually and come out of the conversation victorious!

UPDATE: Daniel Rose left a comment pointing to this post that goes into more detail about holography and makes a convincing case that the distinction between what HoloLens does and holography is overly pedantic and not useful. It looks like the well actuallyer has been well actually’d!