The Git distributed version control system is very popular in with Perlers, and even if you aren’t using it for your own project, you should know how to do simple things with it so you can interact with the most active parts of the community. It’s not that hard. Not only that, many Perl projects are on Github, and it’s something else you’ll know when you go to your next interview.
Git has many nice features, some of which people consider advantages over other source control paradigms. As a distributed system, you don’t need anyone’s permission to use it. You don’t have to ask anyone to set up a repository for you, and you can install the client software yourself. This isn’t a Git tutorial. You’ll find enough of those on the interwebs, especially by Scott Chacon.
Create your first repository
Creating a git repository is easy. The repo itself carries everything that you need (that’s part of its distributed nature), so you don’t need to do much to create and use a repository. You don’t need anyone’s permission and you don’t need net access. Everything the repository needs is directly in the repositories directory, so once you are done with it, you can simply delete the directory without any additional cleanup.
Suppose that you wanted to start using Git with one of your Perl distributions. Change into its directory and create the repo:
$ cd Some-Module-Distribution-Directory $ git init $ git add . $ git commit -m 'initial import'
That’s it. Now you have a Git repository. The init
creates the repository, the add
tracks files (and the .
works on the current directory, tracking the directory and everything below). The commit
makes it official.
The next step is to work on your Perl distribution. Isn’t working on the Perl the point, anyway? You need to makes some changes to track changes. From that point, it’s the basic Git workflow. You can add
individual files and commit their changes:
$ git add lib/Foo.pm $ git commit -m 'Made things work'
You’ll get some output:
[master 3663fe3] Made things work 1 files changed, 1 insertions(+), 0 deletions(-)
That number after master
is the first part of the commit ID, a SHA-1 digest that not only identifies the particular commit, but everything that led up to it. Again, the Git tutorials will explain these things.
You just keep doing that until your software rules the world.
Work on other distributions
But you can use Git with Perl distributions that aren’t yours. Since you don’t have to do much work to create the repository, it makes sense to make temporary repositories for other people’s distributions when you want to make a patch. IF you like, you can download the distribution, unpack it, and create the repository just like you did before:
$ curl -O http://www.cpan.org/authors/id/T/TU/TURNSTEP/Net-SSH-Perl-1.34.tar.gz $ tar -xzf Net-SSH-Perl-1.34.tar.gz $ cd Net-SSH-Perl-1.34 $ git init $ git add . $ git commit -m 'initial import of Net-SSH-Perl-1.34'
Now you have the module you want to patch in a Git repository, and you’ve saved the initial state of the repository. Make your changes, commiting as many times as you like along the way.
After you do your work, you can easily create patches. Check your log to find the commit where you want to start. The --oneline
log format is useful just to see the commit digests and the short messages:
$ git log --oneline 5cbbf58 Make delete part of the pipeline 33268fc Removed keyword 5efbedd Initial import of Net-SSH-Perl-1.34
Since you want to create the patches for the work you’ve done since the initial import, you tell git
to create those patch files by specify where it should start by giving it the commit digest. There are many ways to specify how you want to create the patch, but this is easy enough:
$ git format-patch 5efbedd 0001-Removed-keyword.patch 0002-Make-delete-part-of-the-pipeline.patch
There you are. You have one file per change (although you can do that differently as well). Those are the files you need to send off. If you’re used to doing with with the diff
tool, notice that you don’t have to keep two copies of the distribution for comparison and you don’t have to remember if the original directory comes first or second. Git does all of that work for you.
That’s the basic idea, and that’s easy, but it gets even easier.
git-cpan
Yanick Champoux created the Git::CPAN::Patch distribution so you can easily interact with CPAN distributions with git
, but especially so you can download the latest version, create a patch, and submit it while doing as little work as possible. Yanick first mentioned his work in a Use.perl post after he wrote an artile about it for The Perl Review 5.1.
His Git::CPAN::Patch distribution installs several Perl programs that you’ll use as regular git
commands. You can even make your own git
commands; installed in the right place (somewhere in PATH), a script named git-foo becomes the git foo
you type at the command line.
Script | Task |
---|---|
git-cpan-init | Create a git repository for a CPAN module |
git-cpan-send-email | use git-send-email to submit patches to CPAN RT |
git-cpan-sendpatch | create patch files and submit them to RT |
Suppose that you wanted to make a patch to Module::Build. Create a directory to hold your repository, change into it, then call git cpan-init
:
$ mkdir module-build $ cd module-build $ git cpan-init Module::Build
Now you have the latest version of Module::Build in a Git repository, making it easy for you to do work and later create the patch. So, do that. Perhaps you can fix one of the outstanding bugs in its RT queue. As you go along, commit as normal.
After many commits, perhaps you’re ready to submit a patch. Instead of creating a patch for each commit, you can combine them into one big commit. The git cpan-squash
command takes your commits and turns them into a single commit in a new branch:
$ git cpan-squash some_branch
After you do that, git cpan-squash
leaves you on the branch that it created for you so you can do the final step: sending the patch to the RT queue. You don’t even need to know anything about RT:
$ git cpan-send-path
That’s it. Now that you are done, you can keep the repository or get rid of it.
Things to remember
- You can use Git for lightweight, short term repositories.
- You can use Git to make quick patches to other people’s distributions
- Git::CPAN::Patch installs git commands that interact with CPAN for you.
The gitpan project also made it easy to contribute to other distributions. Too bad it is no longer maintained.