Skip to content

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

Merged
weihanglo merged 10 commits intogit-format-patchfrom
binary-patch
Feb 2, 2026
Merged

feat(binary): add git binary patch support#33
weihanglo merged 10 commits intogit-format-patchfrom
binary-patch

Conversation

@weihanglo
Copy link
Copy Markdown
Owner

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.

The API was stabilized in 1.73.
The lint was added in 1.93.
* `Binary files a/path and b/path differ`
  (`git diff` without `--binary` flag)
* `GIT binary patch`
  (from `git diff --binary`)
This makes diffy more transparent to users:
diffy parses all, users decide later.
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.
See <https://diffx.org/spec/binary-diffs.html#git-delta-binary-diffs>

Specifically, this part of the example code:

```python
orig_data: bytes = b'<file data>'
modified_data: bytes = b'<file data>'
result = io.Bytes()

for (mode,
     modified_offset,
     modified_hunk,
     modified_size) in calc_hunks(orig_data, modified_data):
    if mode == ADD:
        assert 1 <= modified_size <= 127

        result.write(bytes([modified_size, *modified_hunk]))
    elif mode == COPY:
        control = 0x80
        args = bytearray()

        for shift, mask in zip((0, 8, 16, 24),
                               (0x01, 0x02, 0x04, 0x08)):
            value = (modified_offset >> shift) & 0xFF

            if value:
                control |= mask
                args.append(value)

        for shift, mask in zip((0, 8, 16),
                               (0x10, 0x20, 0x40)):
            value = (modified_size >> shift) & 0xFF

            if value:
                control |= mask
                args.append(value)

        result.write(bytes([control, *args]))
```
This wires up all the previous commits and expose
`BinaryPatch::apply()` to users to apply Git binary patch.

While binary patch application is behind the `binary` feature,
parsing is done regardlessly, so the changed file count in diffy and in
git should be mostly the same except submodule.
@weihanglo weihanglo merged commit cd57d58 into git-format-patch Feb 2, 2026
14 checks passed
@weihanglo weihanglo deleted the binary-patch branch February 2, 2026 01:59
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