2026-06-05
Before git rebase -i, before git format-patch, kernel hackers and Debian maintainers had a problem: you have a pristine upstream tarball and you need to maintain twenty patches on top of it — patches you'll reorder, refresh against new upstream drops, hand off to colleagues, and ship in a tarball next to the source. quilt solved this in 2003, it still ships in every distro, and it remains the best tool I know for a very specific job: treating a set of patches as a first-class artifact, separate from any VCS.
The mental model is a stack. You push patches onto the working tree, pop them off, refresh them when files change underneath. The patches/ directory holds the actual .patch files plus a series file listing the order.
$ cd linux-6.10/
$ quilt new fix-acpi-quirk.patch # create new patch on top of stack
$ quilt add drivers/acpi/scan.c # tell quilt you'll edit this file
$ vim drivers/acpi/scan.c
$ quilt refresh # snapshot diff into the patch file
$ quilt new add-debug-knob.patch
$ quilt add kernel/sysctl.c
$ vim kernel/sysctl.c
$ quilt refresh
$ quilt series # show the stack
fix-acpi-quirk.patch
add-debug-knob.patch
$ quilt applied # what's currently pushed
$ quilt pop -a # unwind to pristine tree
$ quilt push fix-acpi-quirk.patch # reapply just one
The killer feature: quilt refresh regenerates the patch from the current state of the tracked files. Edit, refresh, edit, refresh. No commit ceremony, no rebase. When you want to split a patch, quilt fork clones the top patch and you trim each half by hand. To fold someone else's patch into yours, quilt fold < mbox.
Where this beats git: you receive a new upstream version. With git you'd rebase twenty commits and resolve conflicts inside the rebase machinery. With quilt:
$ quilt pop -a
$ rsync -a --delete ../linux-6.11/ ./
$ quilt push -a # apply each patch, stop on conflict
File drivers/acpi/scan.c is read-only; refusing to patch
1 out of 3 hunks FAILED -- rejects in file drivers/acpi/scan.c
Patch fix-acpi-quirk.patch does not apply (enforce with -f)
$ quilt push -f # force, leaving .rej files
$ vim drivers/acpi/scan.c # hand-fix
$ quilt refresh # snapshot the resolved version
$ quilt push -a # continue
Each patch is a plain unified diff in patches/. You can email them, version them in git (yes, the patches themselves), grep them, hand-edit them. There's no opaque commit graph — what you see in patches/series is exactly what gets applied.
Other commands worth knowing:
quilt diff -P fix-acpi-quirk.patch — show one specific patch's contentsquilt header -e — edit the patch description (the prose at the top of the file, which becomes the commit message if you import into git)quilt graph --all | dot -Tpng > deps.png — visualize which patches touch overlapping filesquilt mail --mbox out.mbox — turn the series into an mbox for git send-email or LKMLQUILT_PATCHES=debian/patches quilt push -a — point quilt at any directory (this is exactly how Debian's 3.0 (quilt) source format works)When to reach for it: distro packaging, maintaining a long-lived fork that periodically rebases on upstream, prepping a 30-patch kernel series for submission, or any time you want patches as the unit of work rather than commits. It pairs beautifully with git — keep patches/ in git, treat the working tree as throwaway.
