Add infrastructure for binary file patching in rbt patch.

Review Request #14711 — Created Nov. 28, 2025 and updated

Information

RBTools
master

Reviewers

This adds the core infrastructure needed to support binary file patching
when applying review request diffs using rbt patch.

rbtools.diffs.patches.BinaryFilePatch represents binary files in the
diff, and can lazily load their content as-needed.

rbtools.diffs.patcher.Patcher now has several methods to apply binary
files in various ways. They can be overridden by SCM-specific patchers
to perform file operations as necessary.

rbtools.diffs.patches.PatchResult will now track which binary files
were applied (or failed).

The rbt patch command has been updated to:

  • Fetch binary file metadata from diff and commit resources.
  • Pass binary files to Patch instances.
  • Report binary file application results
  • Add the new --no-binary option, which skips patching binary files.

Subsequent changes will add support for individual SCM systems.

  • Ran unit tests.
  • Used this in conjunction with later changes to actually apply patches
    that include binary files.
Summary ID
Add infrastructure for binary file patching in rbt patch.
This adds the core infrastructure needed to support binary file patching when applying review request diffs using `rbt patch`. `rbtools.diffs.patches.BinaryFilePatch` represents binary files in the diff, and can lazily load their content as-needed. `rbtools.diffs.patcher.Patcher` now has several methods to apply binary files in various ways. They can be overridden by SCM-specific patchers to perform file operations as necessary. `rbtools.diffs.patches.PatchResult` will now track which binary files were applied (or failed). The `rbt patch` command has been updated to: - Fetch binary file metadata from diff and commit resources. - Pass binary files to `Patch` instances. - Report binary file application results - Add the new `--no-binary` option, which skips patching binary files. Subsequent changes will add support for individual SCM systems. Testing Done: - Ran unit tests. - Used this in conjunction with later changes to actually apply patches that include binary files.
mxnmkxtkuwpysslkkonvosuyumspvzsx
Description From Last Updated

Since this is only used here internally, it might be worth just letting this live in TYPE_CHECKING.

chipx86chipx86

Can you add double-backticks around this and a period?

chipx86chipx86

Missing a period.

maubinmaubin

This might be a bit easier to follow if we remove a level of nesting, like: if p_num == 0: …

chipx86chipx86

This is a small regex. Might just be worth defining it once globally instead of per-class. Otherwise, if we're likely …

chipx86chipx86

Can we make reverted keyword-only? Same with the other similar methods.

chipx86chipx86

Should this be Sequence?

maubinmaubin

Missing parens around the union.

chipx86chipx86

Missing a trailing period.

chipx86chipx86

Missing a blank line before the if.

chipx86chipx86

This is going to overwrite binary_files_applied each time, preserving only the last filename. append() might be the right thing, but …

chipx86chipx86

Similar issue with json.add. It's going to overwrite each time.

chipx86chipx86

We could do a walrus operator here so we don't have to access patch.binary_files twice.

maubinmaubin

We're inconsistent with localization in RBTools. We probably should work toward localizing all new strings. I just picked one example, …

chipx86chipx86

This sort of reads like "add a file (to the patcher)", but it's really "handle a file add". I wonder …

chipx86chipx86

This needs a Version Added. Same with the functions below.

chipx86chipx86

Can we call this fp, so it's consistent with most other open calls? Other file information objects in this change …

chipx86chipx86

To keep this in alphabetical order, these should be swapped.

chipx86chipx86

Should we make a TypeAlias for this?

maubinmaubin

Missing 'moved'.

maubinmaubin

These comments are missing trailing periods.

chipx86chipx86

Missing period. Same with others in the file.

chipx86chipx86

Missing period and blank line.

chipx86chipx86

Can we stick to one per line?

chipx86chipx86

Can we make these keyword-only?

chipx86chipx86

This needs a Version Added.

chipx86chipx86

It's not really clear what this is ultimately doing. Maybe worth just making a function for this?

chipx86chipx86

line too long (81 > 79 characters) Column: 80 Error code: E501

reviewbotreviewbot

line too long (87 > 79 characters) Column: 80 Error code: E501

reviewbotreviewbot
david
chipx86
  1. 
      
  2. rbtools/clients/base/scmclient.py (Diff revision 2)
     
     
     
     
     
     
    Show all issues

    Since this is only used here internally, it might be worth just letting this live in TYPE_CHECKING.

  3. rbtools/clients/base/scmclient.py (Diff revision 2)
     
     
    Show all issues

    Can you add double-backticks around this and a period?

  4. rbtools/clients/base/scmclient.py (Diff revision 2)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues

    This might be a bit easier to follow if we remove a level of nesting, like:

    if p_num == 0:
        return file_or_files
    
    # Rest here
    
  5. rbtools/clients/base/scmclient.py (Diff revision 2)
     
     
     
     
     
     
    Show all issues

    This is a small regex. Might just be worth defining it once globally instead of per-class.

    Otherwise, if we're likely to access this more than we set it, this can just be a try/except, catching AttributeError.

    1. By the time we're stripping prefixes from diffs we only have one type of SCMClient class anyway. Moving it globally doesn't buy us anything.

  6. rbtools/commands/patch.py (Diff revision 2)
     
     
     
     
     
     
    Show all issues

    Can we make reverted keyword-only?

    Same with the other similar methods.

  7. rbtools/commands/patch.py (Diff revision 2)
     
     
    Show all issues

    Missing parens around the union.

  8. rbtools/commands/patch.py (Diff revision 2)
     
     
    Show all issues

    Missing a trailing period.

  9. rbtools/commands/patch.py (Diff revision 2)
     
     
     
    Show all issues

    Missing a blank line before the if.

  10. rbtools/commands/patch.py (Diff revision 2)
     
     
    Show all issues

    This is going to overwrite binary_files_applied each time, preserving only the last filename.

    append() might be the right thing, but I think you probably just want:

    self.json.add('binary_files_applied', patch_result.binary_applied)
    
  11. rbtools/commands/patch.py (Diff revision 2)
     
     
     
     
     
     
     
    Show all issues

    Similar issue with json.add. It's going to overwrite each time.

  12. rbtools/diffs/patcher.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    We're inconsistent with localization in RBTools. We probably should work toward localizing all new strings. I just picked one example, but this applies more generally.

  13. rbtools/diffs/patcher.py (Diff revision 2)
     
     
    Show all issues

    This sort of reads like "add a file (to the patcher)", but it's really "handle a file add". I wonder if we should call this handle_add_file()? Same thought for move/remove/write.

  14. rbtools/diffs/patcher.py (Diff revision 2)
     
     
     
     
     
     
     
    Show all issues

    This needs a Version Added.

    Same with the functions below.

  15. rbtools/diffs/patcher.py (Diff revision 2)
     
     
     
    Show all issues

    Can we call this fp, so it's consistent with most other open calls? Other file information objects in this change use f.

  16. rbtools/diffs/patches.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    To keep this in alphabetical order, these should be swapped.

  17. rbtools/diffs/tests/test_patch.py (Diff revision 2)
     
     
    Show all issues

    These comments are missing trailing periods.

  18. rbtools/diffs/tests/test_patcher.py (Diff revision 2)
     
     
    Show all issues

    Missing period.

    Same with others in the file.

  19. rbtools/diffs/tests/test_patcher.py (Diff revision 2)
     
     
    Show all issues

    Missing period and blank line.

  20. rbtools/diffs/tests/test_patcher.py (Diff revision 2)
     
     
    Show all issues

    Can we stick to one per line?

  21. rbtools/testing/testcase.py (Diff revision 2)
     
     
     
     
     
     
     
     
     
    Show all issues

    Can we make these keyword-only?

  22. rbtools/testing/testcase.py (Diff revision 2)
     
     
     
     
    Show all issues

    This needs a Version Added.

  23. rbtools/testing/testcase.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    It's not really clear what this is ultimately doing. Maybe worth just making a function for this?

  24. 
      
maubin
  1. 
      
  2. rbtools/clients/base/scmclient.py (Diff revision 2)
     
     
    Show all issues

    Missing a period.

  3. rbtools/commands/patch.py (Diff revision 2)
     
     
    Show all issues

    Should this be Sequence?

  4. rbtools/diffs/patcher.py (Diff revision 2)
     
     
     
     
    Show all issues

    We could do a walrus operator here so we don't have to access patch.binary_files twice.

  5. rbtools/diffs/patches.py (Diff revision 2)
     
     
    Show all issues

    Should we make a TypeAlias for this?

  6. rbtools/diffs/patches.py (Diff revision 2)
     
     
    Show all issues

    Missing 'moved'.

  7. 
      
david
Review request changed
Commits:
Summary ID
Add infrastructure for binary file patching in rbt patch.
This adds the core infrastructure needed to support binary file patching when applying review request diffs using `rbt patch`. `rbtools.diffs.patches.BinaryFilePatch` represents binary files in the diff, and can lazily load their content as-needed. `rbtools.diffs.patcher.Patcher` now has several methods to apply binary files in various ways. They can be overridden by SCM-specific patchers to perform file operations as necessary. `rbtools.diffs.patches.PatchResult` will now track which binary files were applied (or failed). The `rbt patch` command has been updated to: - Fetch binary file metadata from diff and commit resources. - Pass binary files to `Patch` instances. - Report binary file application results - Add the new `--no-binary` option, which skips patching binary files. Subsequent changes will add support for individual SCM systems. Testing Done: - Ran unit tests. - Used this in conjunction with later changes to actually apply patches that include binary files.
mxnmkxtkuwpysslkkonvosuyumspvzsx
Add infrastructure for binary file patching in rbt patch.
This adds the core infrastructure needed to support binary file patching when applying review request diffs using `rbt patch`. `rbtools.diffs.patches.BinaryFilePatch` represents binary files in the diff, and can lazily load their content as-needed. `rbtools.diffs.patcher.Patcher` now has several methods to apply binary files in various ways. They can be overridden by SCM-specific patchers to perform file operations as necessary. `rbtools.diffs.patches.PatchResult` will now track which binary files were applied (or failed). The `rbt patch` command has been updated to: - Fetch binary file metadata from diff and commit resources. - Pass binary files to `Patch` instances. - Report binary file application results - Add the new `--no-binary` option, which skips patching binary files. Subsequent changes will add support for individual SCM systems. Testing Done: - Ran unit tests. - Used this in conjunction with later changes to actually apply patches that include binary files.
mxnmkxtkuwpysslkkonvosuyumspvzsx

Checks run (1 failed, 1 succeeded)

flake8 failed.
JSHint passed.

flake8

david
Review request changed
Commits:
Summary ID
Add infrastructure for binary file patching in rbt patch.
This adds the core infrastructure needed to support binary file patching when applying review request diffs using `rbt patch`. `rbtools.diffs.patches.BinaryFilePatch` represents binary files in the diff, and can lazily load their content as-needed. `rbtools.diffs.patcher.Patcher` now has several methods to apply binary files in various ways. They can be overridden by SCM-specific patchers to perform file operations as necessary. `rbtools.diffs.patches.PatchResult` will now track which binary files were applied (or failed). The `rbt patch` command has been updated to: - Fetch binary file metadata from diff and commit resources. - Pass binary files to `Patch` instances. - Report binary file application results - Add the new `--no-binary` option, which skips patching binary files. Subsequent changes will add support for individual SCM systems. Testing Done: - Ran unit tests. - Used this in conjunction with later changes to actually apply patches that include binary files.
mxnmkxtkuwpysslkkonvosuyumspvzsx
Add infrastructure for binary file patching in rbt patch.
This adds the core infrastructure needed to support binary file patching when applying review request diffs using `rbt patch`. `rbtools.diffs.patches.BinaryFilePatch` represents binary files in the diff, and can lazily load their content as-needed. `rbtools.diffs.patcher.Patcher` now has several methods to apply binary files in various ways. They can be overridden by SCM-specific patchers to perform file operations as necessary. `rbtools.diffs.patches.PatchResult` will now track which binary files were applied (or failed). The `rbt patch` command has been updated to: - Fetch binary file metadata from diff and commit resources. - Pass binary files to `Patch` instances. - Report binary file application results - Add the new `--no-binary` option, which skips patching binary files. Subsequent changes will add support for individual SCM systems. Testing Done: - Ran unit tests. - Used this in conjunction with later changes to actually apply patches that include binary files.
mxnmkxtkuwpysslkkonvosuyumspvzsx

Checks run (2 succeeded)

flake8 passed.
JSHint passed.
maubin
  1. Ship It!
  2.