Skip to content

Instantly share code, notes, and snippets.

@fasterthanlime
Last active January 30, 2017 06:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fasterthanlime/686ddd900b3348f637b2271b57c24bae to your computer and use it in GitHub Desktop.
Save fasterthanlime/686ddd900b3348f637b2271b57c24bae to your computer and use it in GitHub Desktop.

Omar is looking for:

  • A tool that generates a zip containing files in "new" that aren't in "old"

(that would effectively act like a "patch" that doesn't delete removed files).

butler in a nutshell

Here's what butler does:

  • Uses the rsync algorithm over all files
  • Which detects renamed/split/merged/changed files
  • Emits a stream of protobuf messages (some headers (canonical file paths/permissions/etc) + rsync operations)
  • ...which are compressed using the method of your choice (for itch.io: brotli-q1)

butler is needed to apply patches (so, not runtime-less like the original zip solution Omar envisioned), but:

  • it's a solid codebase
  • patches are small
  • it has built-in verification & healing
  • it can patch in-place (atomically) or into another folder

see Offline usage for commands used when diff/patching

smaller patches

plus: butler just got patch optimization, which

  • Analyzes the original "rsync" patch
  • Determines file pairs that are good candidates for "bsdiff"
  • Runs bsdiff
  • Emit a different stream of protobuf messages
  • ...usually compressed using a higher compression format/level (for itch.io: zstd-q9)

This generates another patch file, usually smaller than the first one (anywhere from 2x to 10x smaller depending on patch contents)

size problem & solution

if you're shipping that with a game, butler's binary size (about 13-17MB depending on platforms) might be an issue.

however:

  • It's all open-source golang code
  • ...and butler includes many commands besides diff/apply
  • so you can easily strip out what you don't need

alternatively, it may be much easier to just upx the darn thing - would easily reduce it to 3-4MB?

any questions welcome on twitter, butler's github issue tracker, or e-mail (which is in my bio, @fasterthanlime)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment