Skip to content

feat(binary): add git binary patch support#61

Open
weihanglo wants to merge 16 commits intobmwill:masterfrom
weihanglo:binary-patch
Open

feat(binary): add git binary patch support#61
weihanglo wants to merge 16 commits intobmwill:masterfrom
weihanglo:binary-patch

Conversation

@weihanglo
Copy link
Copy Markdown
Contributor

@weihanglo weihanglo commented Apr 13, 2026

Blocked on #59. Please review from 7a22125

Basically a port of weihanglo#33.

BTW, this is probably the very last major feature PR. I might have some other small ones for housekeeping and preparation of the new release.


Add parsing and application of git binary patches,
including both literal and delta formats.

This feature is behind the binary Cargo feature.

The implementation is based on

Some others highlights:

  • Bump MSRV to 1.75.0 as zlib-rs requiring that.
  • Parsing of binary format is always available, only decode/apply operations is behind the binary feature.
  • Binary format now is always parsed by default in GitDiff mode, unless specified via skip/fail in ParseOptions.

@weihanglo weihanglo force-pushed the binary-patch branch 2 times, most recently from dda555a to 0fbd877 Compare April 13, 2026 03:03
@weihanglo weihanglo force-pushed the binary-patch branch 2 times, most recently from 92aa517 to 61c9c2b Compare April 13, 2026 19:22
`.lines()` strips line endings, so callers tracking byte offsets
need to re-add the `\r\n` or `\n` length manually.
Extract the repeated inline pattern into a reusable helper.
* Parse `diff --git` extended headers
* split multi-file git diffs at `diff --git` boundaries
Compat test for also `git apply`.
Unlike unidiff,
gitdiff produces patches for empty file creations/deletions
(`0\t0` in numstat)
because they carry `diff --git` + extended headers even without hunks.

Binary files (`-\t-\t`) are skipped in gitdiff mode for now.
* Added types representing both literal and delta Git binary patches
* Added a parser for the `GIT binary patch` format.

This doesn't include the patch application
(which will be added in later commits)

The implementation is based on

* Specification from <https://diffx.org/spec/binary-diffs.html>
* Behavior observation of Git CLI
- Add `Binary::Keep` variant (now the default) to `ParseOptions`
- Add `PatchKind::Binary` variant for binary patches
- Parse `GIT binary patch` payload via `parse_binary_patch`
- Handle `Binary files ... differ` as `BinaryPatch::Marker`
- Add `extract_file_op_binary` for file ops without ---/+++ headers
The API was stabilized in 1.73.
The lint was added in 1.93.

This is required for a MSRV bump to 1.75
This is a preparation for binary diff application support.

* Git binary patch is compressed by zlib hence flate2
* zlib-rs (which is the most performant zlib backend)
  requires MSRF 1.75.0+ hence the bump.
* Add base85 encoder/decoder and Git delta format decoder.
* Wire them into `BinaryPatch::apply() and `apply_reverse()`
  for decoding zlib-compressed, base85-encoded binary payload.

These are feature-gated behind the `binary` feature.
Now both tests require `binary` Cargo feature.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant