Hubot with Git Submodules

I love hubot and use one in a few different places. One thing I do find though is that I often want to edit or evolve those plugins, and it seems somehow unethical to just hardcode my changes into my own repo. Once I figured out how to wire together a forked repo as a submodule, it became much easier to work with hubots with external plugins, so I thought I'd share my recipe for that.

Plugins as Submodules

Git submodules can get messy if you're not totally clear on what is going on. The basic premise is this: there's a git repo in your subdirectory, and the parent directory will notice if things change in there. You need to remember to commit and push on both the main repo and the submodule and then everything will work! The git-scm reference for this has good examples: http://git-scm.com/book/en/v2/Git-Tools-Submodules>http://git-scm.com/book/en/v2/Git-Tools-Submodules

In this case, I've got my own fork of the github notifier plugin which we use in the #joind.in channel on freenode. My fork lives here: https://github.com/lornajane/hubot-github-repo-event-notifier so I go there, and I grap the repo URL.

Then, I add it as a submodule. I've created a directory called my_modules inside my hubot folder to keep submodules in.

git submodule add my_modules/hubot-github-repo-event-notifier https://github.com/lornajane/hubot-github-repo-event-notifier.git

There are two particular things to notice about this command:

  1. It is run from the top level of the repo, not the subdirectory
  2. It uses the https version of the URL - I usually work with SSH for github, but if you're going to push to heroku, the https one makes more sense there

Tell Hubot About The Plugin

To get hubot to "see" this plugin, create a symlink in the scripts/ directory that points to the script you want to run in your plugin. My command looks like this:


cd scripts
ln -s ../my_modules/hubot-github-repo-event-notifier/index.coffee gh-notifier.coffee

Now when you run hubot, the plugin should load. You can easily test your hubot locally (without having to commit and push to heroku every time) by running ./bin/hubot from the commandline; this starts hubot with the shell adapter and is really hand for the types of commands where you say something and the bot does something. I have a trick for testing webhooks on my local machine that I'll share in a separate blog post but the main thing is, any really basic mistakes like syntax errors will become obvious at this point :)

Submodules to Heroku

There isn't anything special to do here. Make sure that both your main and submodule repositories have changes added, committed and pushed. When you push the main repo to heroku, it knows how to handle the submodules and will plug them in accordingly.

I love that so many of the hubot plugins are packaged via npm but often I want to tweak or evolve them - or even just take advantage of their newest changes without waiting for it to be packaged! The github integration in particular I found was a lot less useful than I expected from any of the plugins I could find, so if you're using hubot and github and you want to try my version, feel free ... the main reason I wanted to work with submodules and hubot is so that I could share what I was working on in case it was useful to anyone else.

Git: upstream is gone

I came across a git repo recently that output this message with every operation I did:

Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

I was delivering a workshop at the time so I kinda snarled at it and carried on with what I was doing, but later I looked up what is happening. This occurs when a branch is tracking a branch that the git repo doesn't have any information about - the branches to be tracked aren't in the local repo metadata.

In my case, it happened because I had created and then cloned an empty repo for training purposes - so origin/master didn't actually exist yet! I added a quick commit-and-push to my script and hope that I won't be upstaged by this change that came in with git 1.8.5.

Hopefully this post will help someone else to avoid being upstaged or irritated by this as well!

Announcing the Git Workbook

I'm very pleasedtitle_page to announce the immediate availability of my new book Git Workbook, costing $20 from LeanPub. This is a book that you "do" rather than "read"; it's a series of chapters (30 ish so far) each covering one specific git skill.

Each chapter includes an explanation of the skill in question, followed by a hands-on exercise so that you can work through the skill yourself, and ends with a tickbox so you can keep track of how far through you are. It has quizzes, diagrams, mildly amusing stories, and as many other examples as I could think of that could help anyone to take in this technical topic and understand how to apply the techniques covered. Continue reading

Git Submodules for Dependent or Common Code

Submodules are one of the most powerful and most mistrusted features in git, at least in the web development part of the internet where I spend my time. I've seen them go horribly wrong, but I've also had teams adopt submodules and have their development process run much more smoothly as a result - so I thought I'd take a moment out of my day to write down the process (and the gotchas) of development with submodules. Continue reading

Video: Git Remotes and Tracking Branches

Here's a little demo video that I put together to explain pushing/pulling with multiple remotes and how tracking branches make this easier. It's one of the chapters from my "Git Adventures" talk, but it didn't make it in to the talk in Amsterdam last week since we chose a different adventure that time - sharing it here in case it's helpful to anyone else, and so I can find it later!

I also blogged about the tracking branches in a bit more detail if you're interested.

Understanding Tracking Branches in Git

Here's a topic that took me a while to understand in git, and now (I think!) I do, I thought I'd write it all down while I can remember!

Some branches in git (such as your origin/master branch) will usually track the remote branch that they are related to. But what if you want to create a relationship between local and remote branches? Or stop them from tracking? Here's some pointers Continue reading

Colourless Git Output

I teach git and often have issues with bad projectors where you can't see the colours. Recently I had a setup where even white on black was more or less invisible, but using black text on a white background worked okay. There's lots of documentation on how to turn on colours in git but not so much about how to turn them off.

Try putting the following into .git/config:

[color]
    branch = false
    diff = false
    interactive = false
    status = false

I had expected to be able to set color.ui to false but that didn't seem to make much difference, so I now use the settings above. I thought I'd drop it here in case anyone else is looking for the same thing.

Quick Switch Between Git Branches

Today's little-known git feature (or maybe everyone knows but me? I only found this a few months ago) is for quickly switching between branches. Usually I would switch branches with:

git checkout [branchname]

However if you switch from one branch to another and want to switch back again (this happens when I'm reviewing changes and wondering if a bug is present on master as well), then you can do so by just doing:

git checkout -

Just a little timesaver in case it's useful to anyone else - I know I've been using it quite a bit!

PHP and Git Training Course Dates

I've had a little flurry of enquiries about training lately, so I thought I'd mention the courses I have coming up, as especially the PHP ones are topics that I don't run public classes on all that often. At the time of writing I have some space on all of these classes: Continue reading

GitHub-Powered Changelog Scripts

My current project does periodic releases, we build a few things, then we work on getting a bunch of user feedback and changing/fixing things before we actually release. This means we need to be organised with tags and branches. We're using GitHub for collaboration, including our issue trackers, commits which contribute to an issue have the issue number in the commit message, and when a branch merges in to the main line, we use the "fixes #42" notation to simultaneously close off the issue that it relates to.

This has been working pretty well, and today I got the question "what's new since I last saw this project?" - so I created a changelog. It's rather rough-and-ready but I had fun so I thought I'd share. Continue reading