OVERWRITE_SYSTEM_VOLUME vs MERGE_SYSTEM_VOLUME: OCLP-Mod Patch Application Strategies
TLDR: OCLP-Mod implements OVERWRITE_SYSTEM_VOLUME by deleting existing targets with rm -R before copying new files, while MERGE_SYSTEM_VOLUME uses rsync -a to additively update directories without removing existing content.
The laobamac/oclp-mod patcher modifies macOS system volumes using two distinct deployment mechanisms. Understanding the OVERWRITE_SYSTEM_VOLUME vs MERGE_SYSTEM_VOLUME patch application strategies is critical for developers authoring patchsets, as each method handles existing files differently—either destroying or preserving the target directory structure.
Core Mechanisms: Delete-then-Copy vs Additive Sync
The OVERWRITE Strategy
When the patcher encounters PatchType.OVERWRITE_SYSTEM_VOLUME or PatchType.OVERWRITE_DATA_VOLUME, it executes a destructive replacement workflow. In oclp_mod/sys_patch/utilities/files.py (lines 36–58), the install_new_file function checks if the target exists and removes it completely before installation.
For directories (kexts, apps, or bundles), the logic performs:
if Path(destination_folder + "/" + file_name).exists():
logging.info(f" - 找到现有 {file_name},正在覆盖...")
subprocess_wrapper.run_as_root_and_verify(
["/bin/rm", "-R", f"{destination_folder}/{file_name}"]
)
else:
logging.info(f" - 安装: {file_name}")
subprocess_wrapper.run_as_root_and_verify(
generate_copy_arguments(f"{source_folder}/{file_name}", destination_folder)
)
fix_permissions(destination_folder + "/" + file_name)
This delete-then-copy approach ensures a clean replacement, eliminating any stale files from previous system versions. Single files follow the same removal logic before copying.
The MERGE Strategy
Conversely, PatchType.MERGE_SYSTEM_VOLUME and PatchType.MERGE_DATA_VOLUME employ an additive approach using rsync. The same install_new_file function routes merge operations through a dedicated branch (lines 36–41 in files.py) that preserves existing directory structures:
if method in [PatchType.MERGE_SYSTEM_VOLUME, PatchType.MERGE_DATA_VOLUME]:
logging.info(f" - 安装: {file_name}")
subprocess_wrapper.run_as_root(
["/usr/bin/rsync", "-r", "-i", "-a",
f"{source_folder}/{file_name}",
f"{destination_folder}/"],
stdout=subprocess.PIPE,
)
fix_permissions(destination_folder + "/" + file_name)
The rsync -a command copies new files into the destination while leaving untouched files intact. This makes MERGE ideal for extending existing frameworks or adding new components without destroying sibling files.
Patch Engine Decision Flow
The central driver that processes these strategies is _execute_patchset in oclp_mod/sys_patch/sys_patch.py (lines 404–418). This method iterates over all four install methods to determine which patches apply:
for method_install in [
PatchType.OVERWRITE_SYSTEM_VOLUME,
PatchType.OVERWRITE_DATA_VOLUME,
PatchType.MERGE_SYSTEM_VOLUME,
PatchType.MERGE_DATA_VOLUME,
]:
if method_install not in required_patches[patch]:
continue
# ... resolves source paths and calls install_new_file
The method_install value determines both the destination volume (System vs. Data) and the specific file-handling behavior passed to the installer. The PatchType enum itself is defined in oclp_mod/sys_patch/patchsets/base.py (lines 12–15).
Pre-Install Cleanup with REMOVE Operations
Both strategies can be combined with PatchType.REMOVE_SYSTEM_VOLUME or PatchType.REMOVE_DATA_VOLUME entries. In _execute_patchset, removal operations execute in a dedicated loop (lines 92–102) before any installation begins, allowing patchsets to delete deprecated bundles prior to deploying replacements.
Practical Patchset Implementation
Real-world patchsets, such as those in oclp_mod/sys_patch/patchsets/shared_patches/non_metal_ioaccel.py, combine these strategies to handle complex system modifications:
from oclp_mod.sys_patch.patchsets.base import PatchType
patches = {
"GraphicsPatch": {
# Complete replacement of existing kext
PatchType.OVERWRITE_SYSTEM_VOLUME: {
"/System/Library/Extensions": {
"AppleGraphicsControl.kext": "10.15.7",
},
},
# Additive installation of new framework
PatchType.MERGE_SYSTEM_VOLUME: {
"/System/Library/Frameworks": {
"NewHelper.framework": "10.15.7",
},
},
# Pre-cleanup of deprecated component
PatchType.REMOVE_SYSTEM_VOLUME: {
"/System/Library/Extensions": [
"OldLegacy.kext"
],
},
}
}
The copy operations for OVERWRITE rely on generate_copy_arguments from oclp_mod/volume/copy.py to construct the proper cp commands for payload deployment.
Summary
- OVERWRITE_SYSTEM_VOLUME deletes existing targets with
/bin/rm -Rbefore copying new payloads, ensuring complete replacement of kernel extensions and bundles. - MERGE_SYSTEM_VOLUME uses
/usr/bin/rsync -ato additively update directories, preserving existing files while adding or updating patch-provided content. - The
PatchTypeenum inoclp_mod/sys_patch/patchsets/base.pydefines these strategies, consumed by_execute_patchsetinsys_patch.py. - The
install_new_filefunction inoclp_mod/sys_patch/utilities/files.pyimplements the actual file operations, branching based on the method type. REMOVE_*operations execute before any install phase, allowing deletion of deprecated paths regardless of the subsequent install strategy.
Frequently Asked Questions
What is the difference between OVERWRITE and MERGE in OCLP-Mod?
OVERWRITE strategies completely remove existing files or directories before installing the new payload, while MERGE strategies use rsync to add new content without destroying existing files. OVERWRITE is used for full replacements like kernel extensions, whereas MERGE is used for extending existing directories with additional frameworks or libraries.
When should I use MERGE_SYSTEM_VOLUME instead of OVERWRITE_SYSTEM_VOLUME?
Use MERGE_SYSTEM_VOLUME when you need to add files to an existing directory structure without destroying files already present on the system volume. This is essential for installing supplemental frameworks or plugins that must coexist with existing system components. Use OVERWRITE_SYSTEM_VOLUME when you must ensure a clean, complete replacement of an outdated bundle or kext.
How does the patcher handle existing files during a MERGE operation?
During a MERGE operation, the patcher invokes rsync -a to copy the source tree into the destination. This preserves all existing files that are not part of the patch payload and only updates or adds the files specified in the patchset. Permissions are repaired after the sync, but no deletion occurs unless explicitly specified via a separate REMOVE_* patch entry.
Can I combine REMOVE, OVERWRITE, and MERGE in the same patchset?
Yes. The _execute_patchset method processes REMOVE_* operations first in a dedicated loop, then handles installations. This allows you to delete deprecated paths before applying either OVERWRITE or MERGE strategies. A single patch dictionary can contain all three operation types targeting different paths or even the same directory sequence.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →