Multi-repository helper scripts

I use a set of two-letter commands to make it easier to function in a wide range of source-code repositories without having to always remember what SCM prefix to type. It also makes some things about the different SCMs more homogeneous.

I started out by writing a perl script that can be symlinked to a bunch of two-letter commands, which works well, but you lose any SCM-specific command-line completion for your shell, so I switched to a new method: redefining aliases on every chdir. However, the old script may still be useful and you can find it here:

As for the aliases, zsh makes it easy to run a script every time the shell changes into a new directory. As such, the following script is specific to zsh (bash users can use the repos script above). You may also need a couple helper scripts on your path, depending on which SCM features you make use of.

A description of the 2-letter commands (aliases) follows:

Does an "add" operation on the specified args.
Does a check-in, defaulting to the committing of all changed files unless an argument beyond "-m msg" is specified (e.g. one or more filenames). For git, you can also specify a trailing -i if you want to turn off the -a option without specifying any files (and thus just commit things that have been explicitly added).
Repo's "diff" command. Auto-pages.
Repo's "log" command. Auto-pages. The -v option can be used to request that names be included in the commit output, even in git. The -s option can be used in a git-svn repo to ask for the "git svn log" output.
Repo's "status" command. For cvs, this uses a helper script (cvs-status) to output status in the same manner as svn, with a default being local-only output, and remote-status added in via -u (though local cvs status does not include info on unknown files).
Push the currently-checked-in changes. This has no effect in svn or cvs. For git, it will do the right thing in a git-svn checkout, as well as a custom cvs-modifying git checkout (see helper-script git-cvs-push and also the zsh talk below).
Update from the saved remote repo location. For git, this defaults to doing a "git pull --rebase" for a normal repo, or an "git svn rebase" for a git-svn repo.

The commands that "auto-page" pipe their output through "less -F" so that you get a pager if the output is long, and normal output if it is not. It helps to have a modern version of less to avoid jumping down to the bottom of the screen when that is not needed. Note that git auto-pages by default, so the aliases leave it alone (which ensures auto-color is unaffected).


ci -m 'The commit message'
di foobar.c
lo -p        (-p doesn't work for cvs or svn)

A historical look at the git-cvs-push

Back before the zsh project switched over to using git, they had a CVS repository. I had created a read-only git mirror to allow developers to develop in git and push their changes via CVS using the git-cvs-push script. Commits are not pulled from CVS in any way, so it is assumed that someone is taking the CVS commits and turning them into git updates somewhere else, and that this mirrored git repository is what you've cloned for your local git copy. In order for the git-cvs-push script to work, there must be a directory named .git/cvs in your repo, and it must have a writable CVS checkout in it. (Aside: anyone doing cvs-to-git mirroring, you should check out my patches for cvsps 2.1 or cvsps 2.2b1 that fixes a problem with potentially misordered commits.)

A practical example for the zsh project:

I used to maintain a git mirror of the official zsh CVS repository in the official git repo (both on SourceForge). This allows someone to pull zsh as a git repo, and keep up-to-date without ever having to fiddle with CVS. For those that want to be able to commit changes to their local git and then push them into the official CVS repo, the git-cvs-push script will figure out what changes to push and commit them into CVS via an appropriate "git cvsexportcommit" command.

Here's how this used to be set up:

git clone git://
cd zsh/.git
cvs -z3 -d:ext:[email protected]:/cvsroot/zsh co -P zsh  
mv zsh cvs
cd ..

After doing that, using the "pu" alias to push your git commits will run the git-cvs-push script (which makes sure that the affected files are up-to-date in the CVS checkout, modifies them, and checks them into CVS). After a few minutes, the git mirror should have updated, and your changes will be pullable by others via git. At that point you should use the "up" alias to let "git pull --rebase" reconcile the official commits with your local commits.

Home > repos
Feel free to with any questions or comments you may have.