Use Git::CPAN::Patch to make quick patches to CPAN distributions

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.

One thought on “Use Git::CPAN::Patch to make quick patches to CPAN distributions”

Comments are closed.