Introducing GitGot — manage all your source code at once

I recently released a Perl module called App-GitGot; this post is to explain the motivation for writing the module and provide some simple examples (and hopefully convince you that you want to use this module too…) As you might guess from the name and the module abstract, GitGot is a tool that streamlines operations across all the code you have checked out from various version control systems.

This is something that I’m interested in because, inspired by first CVS homedir and then Subverting your homedir, I’ve been practicing “keep your $HOME in $VCS” for over 5 years now.1 In addition, like most coding type people in the Github Age, I’ve got a whole collection of other people’s code repositories stashed under my $HOME directory. Further, I’ve got 5 or 6 different systems that I routinely use, and it’s nice to be able to say “show me all the repos with uncommitted changes” or “sync all these repos with their upstream” without having to write shell loops.

I’ve been using a collection of cobbled together bash scripts to accomplish this for the past couple of years, with the intention of someday cleaning them up and releasing them for more general use. Unfortunately, whenever I tried to figure out exactly how that was going to work, I’d hit a wall when trying to figure out how to corral the configuration data on all the repos, as well as an easy-to-use interface to select a subset of repos to operate on – and then I’d kick that particular can down the road a bit and work on something else.

Then, at this year’s Pittsburgh Perl Workshop, I saw Ingy döt Net give a lightning talk about AYCABTU (which expands to “All Your Codez Are Belong To Us”) and all my interface issues were resolved – having a ‘list’ subcommand that presented all the managed repositories as a numbered list, and then using those numbers (as well as repository names) as a way to select subsets was clearly a very workable way to go for a tool of this sort. When I got home, I took a good look at AYCABTU, hoping that I could just throw away my stuff and use it, but it had some workflow assumptions that didn’t fit my setup (such as all repositories being under a common directory), so I stole borrowed took inspiration from Ingy’s interface while rewriting my shell code cruft into slightly less crufty Perl, giving birth to GitGot.


Before you can use it, you’ve got to install it. Fortunately, thanks to CPAN and the wonderfully awesome cpanminus, this is pretty painless. First, if you don’t already have it, install cpanminus:

install cpanm

Once that’s done, use cpanm to install App-GitGot:

install got

Set up

Now that you’ve got GitGot installed, you need to let it know about the repositories you want to manage. Let’s say you keep your ~/etc directory under revision control. You can add it to the GitGot config with the ‘add’ subcommand:

configure got

(Note: everything with GitGot runs through the ‘got’ command – remember that it’s just like ‘git’, only one vowel higher.)

If you’re adding a git repository, got is semi-intelligent about pulling default config values out of the git config file for the repo.2

You can also use the ‘-D’ flag to the add command to just have to use the defaults:

got add -D

Once you’ve added some repositories, you can use the ‘ls’ or ‘list’ subcommand to see all of them:

got ls


You can then check the status of all these repositories in a single shot with the ‘status’ or ‘st’ command:

got st

Or get it to show you information on only the non-clean repositories by giving the ‘-q’ or ‘–quiet’ flag:

got st -q

GitGot tries to use colored output to highlight important information as much as possible – generally, things that you want to pay attention to will have black letters on a colored background; things that are uninteresting and safely ignorable are (usually green) colored letters.

You can also update all your managed repositories in a single shot with the ‘update’ or ‘up’ subcommand:

got up

There are also a few other utilities, like the ‘cd’ or ‘chdir’ subcommand for opening a subshell in a repo’s working directory:

got cd

or the ‘fork’ subcommand for directly forking a repo from github:

got fork

Note that the ‘fork’ subcommand does the fork on github and adds the repo to your config, but doesn’t actually check the new repo out – the ‘status’ subcommand reports that. The new time you run the ‘update’ subcommand, it will see that the repo hasn’t been checked out yet and do that for you.


As I mentioned above, there’s currently no support for anything other than git – although I’m planning on adding SVN support soon, and possibly CVS and Mercurial. (I would of course be delighted to accept patches to add that support – the code is on Github; fork it and send me pull requests.) The test suite is currently pathetically minimal, largely because I was too lazy to write all the fixture generating code at the time. I should circle back and fix that up. Further suggestions are welcomed; hopefully this is useful to somebody other than me.


1 You’d think I’d be able to pull an exact date out of a logfile somewhere, but I’m on about my fourth or fifth iteration of different ways of keeping most everything under revision control, and I usually change implementations by wholesale dump and re-import without bothering to move the logs along, so… yeah, “over 5 years” it is. return

2 If you’re adding a non-git repo, you’re going to get an error message at the moment, as that code hasn’t been written yet… return