2026-09-12
Everyone's tried to abuse Git as a backup tool. Everyone's watched it explode the first time they committed a 40GB VM image — packing goes quadratic, memory blows up, and there's zero dedup across similar chunks. Meanwhile rsync gives you a mirror, not history; borg/restic work but their chunk stores are proprietary formats you'd have to reverse-engineer if the project ever died.
bup, written by Avery Pennarun around 2010, took Git's packfile format — content-addressable, extensively documented, battle-tested by every developer on earth — and bolted on a rolling-checksum chunker (the same rsync trick) so it can dedupe enormous binary files at the byte level. Every bup repo is a real git repo. In a pinch, git fsck still works on it.
bup init
bup index /var/lib/libvirt/images
bup save -n vmbackup /var/lib/libvirt/images
Run it again tomorrow after 200MB of writes inside a 40GB qcow2. bup rolls a hash across each file, finds chunk boundaries at content-defined points, and stores only the chunks it hasn't seen. A rename or a move? Zero new bytes. A 2MB edit deep inside a huge image? 2MB stored, not 40GB.
Browse and restore feel exactly like Git:
bup ls -l vmbackup/latest
bup restore -C /tmp/out vmbackup/latest/./var/lib/libvirt/images
Or mount the entire history as a filesystem — every snapshot, every version, one FUSE tree:
bup fuse /mnt/bup
ls /mnt/bup/vmbackup/ # every timestamp as a directory
Push to a remote host over ssh, no daemon required:
bup on backup-host save -n laptop $HOME
The wizard tricks are where bup earns its keep:
mysqldump db | bup split -n db-dumps stores the dump as content-addressed chunks. Tomorrow's dump reuses every unchanged chunk. bup join db-dumps/latest streams it back. Same trick works for zfs send.bup fsck --generate writes par2 Reed-Solomon recovery data alongside packs. bup damage intentionally corrupts blobs so you can verify recovery works. No external tooling.git log --all, git gc, even git cat-file -p on a chunk. If bup itself vanished from the internet tomorrow, your backups are still Git objects.Watch out for:
.bupm sidecar files inside each tree. You need bup itself to restore them faithfully — git checkout alone won't do it.bup gc exists but is still marked experimental. Historically bup was append-only; treat repos that way in production.bup index before every bup save. Miss that step and it happily saves nothing.Install: apt install bup, brew install bup, or dnf install bup. Python plus a small C extension for the rolling hash.
