Using git commits to drive a live coding session

Introduction: Coding live is awesome, but difficult

Perhaps the most powerful way to show off anything, is to use it live in front of your audience – programming tools, languages and libraries are no exception. You’re showing off a “Hello, world!”-like example with some new framework, and someone in the audience asks a “what if you change this to that?”-question? No problem – just change the code, and show what happens! There’s no way to do that in the code sample you’ve pasted onto your slide deck…

On the other hand, perhaps the worst kind of interruption in your presentation is when something doesn’t work. Of course you tested it thoroughly ten minutes before you started presenting, but Murphy’s Law will bite you anyway – coding live is no exception. In fact, coding live might be one of the most difficult presentation techniques available to us; you can bet your neighbour’s cat that everyone in your audience will spot the typo before you do. That’s why putting the code on a slide is so reassuring; you know you’ve already checked it for typos.

But as it turns out, there is a way to both have the cake and eat it.

What you want to accomplish, is basically to write code live, in a real environment where you can run the code, change it on-demand from your audience and run it again – all in a way that allows you to re-use already tested samples, down to the last semicolon, to avoid wasting time looking for typos and focusing on the real features. Jumping between samples should be just as easy as jumping between slides, while staying interactive.

Re-stating the problem, you want to be able to bring up code samples and versions of code on-demand, inside your real environment. Sounds familiar, no?

Enter git

Jumping between versions of code is just what git does best. Let’s make use of it!

1. Write the demo code, and decide how you want to structure the presentation of it.

2. Manipulate your git tree to give you a straight path through the demo (somewhat equivalent of “preparing your slides” – one slide becomes one commit). How you get there is not so important – personally, I’ve found interactive rebases to be a helpful tool.

3. Add a couple of git tags to the start and end of your demo, e.g. demo-start and demo-end, to make it easier for you to make sure that you’re in the right place when you start your presentation.

You should now have a git log that looks something like this:

4. As the final ingredient in our recipe for a successful live demo, run the following command:

git config --global '!git checkout `git rev-list HEAD..demo-end | tail -1`'

What does this do? Let’s examine it in pieces, starting on the inside and working ourselves out:

  • The innermost command is git rev-list HEAD..demo-end which shows us the list of commit hashes between the current commit (HEAD) and the tag demo-end which we created above, in reverse chronological order. This is then piped to tail -1 so we get only the last hash in the list, which is the next hash between HEAD and demo-end.
  • Next, we wrap that in backticks, and check out the output, i.e. the next commit in the history. In practice, what we’ve done is to run git checkout HEAD^ only backwards.
  • git config –global <…> configures an alias in git, so you can use git next to run whatever code you gave in the alias. If aliases are unfamiliar to you, you might want to read this guide. That guide also explains in detail what the exclamation mark at the beginning of the alias does, but for now it’s sufficient to know that it makes the alias run the command through the shell from the root of the current repo, instead of through git from the current folder.

Your demo, revisited

Now, instead of opening your slide deck and showing code samples, you’re ready for some interactive demo-ing, but without the typos! To start, run

git checkout demo-start

and start running the sample, explaining whatever you do to the audience. When you’re ready to “move to the next slide”, just run git next to advance through the git history until you get to the demo-end tag.

Update: you can have it both ways!

A couple of people have commented (huzzah! I love feedback!) and asked for a similar alias for going backwards in the presentation. This is a lot easier in git, so there’s no need to go through the hassle of reading the list of revisions between two commits – just create the following alias:

git config –global alias.prev ‘checkout HEAD^’

Now, git prev  will take you to the previous “slide”.

Happy hacking!


This Post Has 9 Comments

  1. steve

    This is awesome, I like this a lot. We do a lot of flash talks at work and this will surly break the monotony of MS power point or Google slides next, next ,next tedium. Its so simple I cant believe that i’d never thought of it and I assume that I wont be the only person expressing this sentiment.


  2. Alex Dresko

    I’m still pretty much a git noob, but I love this idea. Any chance a ‘git back’ alias can be created to compliment ‘get next’?

    Bonus question: Can you create an alias for “git on the floor”? j/k.. but seriously with git back.. :)

    1. Tomas Lycken

      In fact, the command you need for git back is already in the blog post. The main reason I didn’t create an alias for this is that it’s so simple in itself – to check out the previous commit, all you have to do is

      git checkout HEAD^

      But of course you could alias it. It’s even much easier than the magic we did for git next, since it doesn’t require any external commands running through the shell; we can just alias through git directly:

      git config --global alias.back 'checkout HEAD^'

      Now, what did you say you wanted git on-the-floor to do? ;)

  3. Anders Poulsen

    I’ve done this a couple of times myself. Although I’ve used mercurial instead of git. The good thing about mercurial is that commits have version numbers instead of commit hashes, so you don’t need the “file with commit hashes” magic. If you can remember
    “hg up -C -r 8”
    “hg up -C -r 9”
    then you are good to go.
    But of course this solution allows you to rearrange things, skip commits and don’t have to worry about what step in the presentation you are at, so I can definitely see myself using this some time.

  4. Rubén


    I was thinking of a way to achieve this and you did it! Thanks a lot, that’s exactly what I was looking for. I didn’t figure out how to move from one commit to the next in an easy way (ok, I could set a tag in every commit, but it wouldn’t have been easy to remember and type), but your `next` alias is impresive.

    Thanks! Very useful post.

  5. Heath H

    I recently brought up the idea of using Git to navigate through a demo and a co-worker pointed me towards this blog post. This is exactly what we had been talking about. After giving this a shot, my co-worker did a bit of tinkering and came up with this snippet:

    git config –global alias.prev ‘!git checkout `git rev-list demo-start..HEAD^1 | HEAD -n1`’

    This will allow you to step backwards through your demo steps also. It seems you can’t jump back to the tag you start the demo on, but other than that it seems to work perfectly. Hope this is useful to someone somewhere.

    1. Tomas Lycken

      Nice! I’m glad you found it useful :)

      Is there a reason you didn’t just `git config –global alias.prev ‘checkout HEAD^’`? It should do the same thing (go to the previous commit).

  6. alecthegeek

    I’m playing about with PowerShell and the equivalent seems to be

    git checkout @(git rev-list HEAD..demo-end)[-1]

    1. alecthegeek

      So after more thorough testing I discovered does not work because git aliases use bash anyway, even on PowerShell

      But tail is not available on my Windows install so I had to find a bash builtin equivalent. I assumed ${..##*”\n”} would be the easiest but could not get it to work.

      In the end I found some help here and ended up with this:

      next = “!$SHELL -c ‘git checkout $(mapfile -t < <(git rev-list HEAD..demo-end);echo -n ${MAPFILE[-1]})'"

      which seems very complicated, but at the moment that is the only way I have found to get it to work.

Leave a Reply