Monday, March 28, 2011

Bikeshed: apply-patch (auto detect strip level and apply the specified patch)

It's been a while since I blogged a Bikeshed post, and I still have plenty of utilities to cover :-)

But this one just made it into Ubuntu Natty (11.04), and my bash history says that I've used it 30+ times already this week...

I think Larry Wall's diff and patch utilities are among the most important programs in all of free software.  These are the most fundamental tools that allow us to modify code, share those modifications with one another in both a human and machine readable format, and apply those changes elsewhere.  It's not uncommon for me to use the two of them more than a hundred times in a work day.

And yet there's two things that bother me about patch...
  1. the -p|--strip parameter should be auto detected, if unspecified
  2. usually, I just want to pass a file in as a parameter using tab-completion, rather than piping it or redirecting it from standard input
So, I'd like to introduce you to the apply-patch utility, which addresses both (1) and (2)!  It takes a patch or a diff file as an argument, and then quietly tries to apply the patch using --dry-run, for -p=0..16, until it finds the correct strip level.  Once it does, it actually applies the patch.

Example:

kirkland@x201:/tmp/foo/patch-2.6$ apply-patch debian/patches/lenny-options 
patching file src/patch.c
patching file patch.man

Useful to anyone besides me?

I'm pretty sure I could hack patch.c and pch.c in the upstream source for patch to do this auto detection of strip level, but I wonder if upstream would take it?


:-Dustin

6 comments:

  1. You make awesome utilities.

    Upstream might be more receptive to an additional command-line arg that turns on autostrip, rather than making it default.

    ReplyDelete
  2. Nice! I often find that I want to wget a patch and apply it. I use a crappy script for doing this, but I often find i need to adjust the strip level, depending on the patch source.

    I could either convert wpatch to pipe into apply-patch... or my favoured option.. apply-patch learns to support remote retrieval of patches... whatcha think? :)

    $ cat ~/bin/wpatch
    #!/bin/sh
    wget -qO- "$1" | patch -p1

    ReplyDelete
  3. Daviey, brilliant idea :-) Can you open an LP bug? I have some code for adding 'apply-patch URL' support tested and working :-) I'd love to commit it with an LP bug number!

    :-Dustin

    ReplyDelete
  4. Daviey:
    * http://paste.ubuntu.com/586595/

    :-Dustin

    ReplyDelete
  5. Couldn't hurt to ask upstream, I think. Any existing script with a patch command not specifying a -p* shouldn't be any more broken if it autodetected, so it doesn't seem like the change would do harm.

    ReplyDelete
  6. Nice tool, gentoo uses something similiar in it's eutils.eclass (a set of helper functions for the package manager) you might find some inspiration there: http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/eclass/eutils.eclass (search for "epatch")
    BTW: you can specify -i to give patch a filename instead of piping stdin

    ReplyDelete

Please do not use blog comments for support requests! Blog comments do not scale well to this effect.

Instead, please use Launchpad for Bugs and StackExchange for Questions.
* bugs.launchpad.net
* stackexchange.com

Thanks,
:-Dustin