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.
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.
Once that’s done, use cpanm to install App-GitGot:
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:
(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
You can also use the ‘-D’ flag to the add command to just have to use the defaults:
Once you’ve added some repositories, you can use the ‘ls’ or ‘list’ subcommand to see all of them:
You can then check the status of all these repositories in a single shot with the ‘status’ or ‘st’ command:
Or get it to show you information on only the non-clean repositories by giving the ‘-q’ or ‘—quiet’ flag:
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:
There are also a few other utilities, like the ‘cd’ or ‘chdir’ subcommand for opening a subshell in a repo’s working directory:
or the ‘fork’ subcommand for directly forking a repo from github:
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.