Creating Empty Git Commits

- 2 mins read

You may not know it, but Git allows you to create an empty commit in to your repo. It doesn’t like it, but you can do it any way.

An empty commit is one where you don’t actually commit any code changes i.e. if you git status your repo, you get the message:

On branch master
nothing to commit, working tree clean

Why would you want to create an empty commit? You may want to communicate changes, which have nothing to do with code. But you have updated something that you want the rest of the team to know about. And you feel that communicating this via the git log make sense.

Changing the Date of Git Commits

- 2 mins read

Have you ever looked at peoples Github contribution timelines and seen a word or some ASCII art. This is done by creating a repo, then manipulating the dates of commits, to create the desired design.

This blog post is not about creating funky pieces of art in your Github commit history timeline. But instead, shows you how to change the date of a commit using Git.

When you make a git commit you can actually set the date of the commit to anything you want. Lets get started.

Using Subtests and Sub-benchmarks in Go

- 4 mins read

In this post we will walk through an example of how to use the new subtests and sub-benchmarks functionality introduced in Go 1.7.

Subtests

One of the nifty features in Go is the ability to write table driven tests. For example, if we wanted to test the function:

func Double(n int) int {
    return n * 2
}

Then we could write a table driven test as follows:

func TestDouble(t *testing.T) {
	testCases := []struct {
		n    int
		want int
	}{
		{2, 4},
		{4, 10},
		{3, 6},
	}
	for _, tc := range testCases {
		got := Double(tc.n)
		if got != tc.want {
			t.Errorf("fail got %v want %v", got, tc.want)
		}
	}
}

Note: The test case {4, 10} is present to make the test fail, 4 * 2 != 10 😃.

SVG Sprites

- 1 min read

Within an single SVG file we can define many sprites. This consists of merging all your SVG sprites into a single .svg image file. Every sprite is wrapped in a ‘symbol’ tag, like this:

<svg class="character" width="100pt" height="100pt" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <symbol id="circle-red" viewBox="0 0 100 100">
      <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
    </symbol>
    <symbol id="circle-black" viewBox="0 0 100 100">
      <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" />
    </symbol>
</svg>

We can then use HTML or CSS to pick out each part of the image:

Updating Third Party Packages in Go

- 1 min read

Just a short post on how to update packages using go get.

To update all third party packages in your GOPATH use the following command:

go get -u all

To update a specific package, just provide the full package name to go get:

go get -u github.com/gorilla/mux

What about vendor-ed packages? These are updated in exactly the same way as above:

go get -u my-project/vendor/megacorp/foo

If you want more information about your GOPATH, run the command:

sort.Sort & sort.Stable

- 2 mins read

Go 1.6 made improvements to the Sort function in the sort package. It was improved to make fewer calls to the Less and Swap methods. Here are some benchmarks showing the performance of sort.Sort in Go 1.5 vs 1.6:

Sort []int with Go 1.5
BenchmarkSort_1-4       20000000              67.2 ns/op
BenchmarkSort_10-4      10000000               227 ns/op
BenchmarkSort_100-4       500000              3863 ns/op
BenchmarkSort_1000-4       30000             52189 ns/op

Sort []int with Go 1.6
BenchmarkSort_1-4       20000000              64.7 ns/op
BenchmarkSort_10-4      10000000               137 ns/op
BenchmarkSort_100-4       500000              2849 ns/op
BenchmarkSort_1000-4       30000             46949 ns/op

source: state of go

The Defer Statement

- 3 mins read

The Go programming language has a defer statement that allows for a function call to be run just before the currently running function returns. Here is how the defer statement is explained in the language specification:

“A “defer” statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.”

Go Channel Axioms

- 2 mins read

A while ago I was watching a tech talk by Blake Caldwell on Building Resilient Services with Go. In his presentation he had a slide which listed go channel axioms. I have listed his channel axioms here and provided some short code snippets to hopefully clarify them.

A send to a nil channel blocks forever

var ch chan bool
ch <- true // will always block

We declare a channel ‘ch’ but do not initialize it (with make), so it is a nil channel. We then attempt to send a value down the channel, this causes a blocking operation.

dotGo 2015

- 5 mins read

Dot conf. logo

On Monday the 9th of November I was in Paris attending dotGo, the European Go conference. This blog post is a summary of my time there.

Pre-Conference

The day before the conference, the Paris tech talks group organized a pre-conference meetup/party. There were a large number of delegates who turned up and the meet up consisted of about six or seven talks. The talks were about how individuals at there respective companies were using Go. All the projects demoed and talked about were network related i.e. using Go to write a load balancer which solved a particular problem. After the talks, there was a chance to socialize and eat pizza with other gophers :).

tmux Cross Platform Config.

- 1 min read

If like me you use tmux on both Linux and OS X, then managing your tmux configuration can be a pain. The problem is there is configuration that is specific to either OS, such as copy and paste behavior. This blog post will show you how to manage your tmux configuration across platforms in a better way.

The first thing you want to do is create a dot file for each platform, so for Linux create .tmux-linux.conf and for OS X create .tmux-osx.conf. Create and place these files in the same location as your .tmux.conf file (most likely your home directory).