patch-ng

1.19.0 · active · verified Fri Apr 10

Library to parse and apply unified diffs. `patch-ng` is a fork of the original `python-patch` project, providing active maintenance and bug fixes. The current version is 1.19.0, released in October 2025. It is actively maintained by Conan-io with regular releases and is compatible with Python 3.6+.

Warnings

Install

Imports

Quickstart

This example demonstrates how to create a simple text file, define a unified diff patch as a string, parse it using `from_string`, and then apply the patch to the file within a temporary directory using `patchset.apply()`.

import os
import tempfile
import shutil
from patch_ng import from_string, PatchSet

# Create a temporary directory to work in
temp_dir = tempfile.mkdtemp()
original_file_path = os.path.join(temp_dir, "my_file.txt")

try:
    # 1. Create an original file
    with open(original_file_path, "w") as f:
        f.write("Line 1: Hello world\n")
        f.write("Line 2: This is a test.\n")
        f.write("Line 3: End of file.\n")

    print(f"Original file '{os.path.basename(original_file_path)}' created in {temp_dir}:\n" \
          f"{open(original_file_path, 'r').read()}")

    # 2. Define a unified diff patch string
    # This patch changes 'Line 2' and adds 'New Line 2.5'
    patch_content = """--- a/my_file.txt
+++ b/my_file.txt
@@ -1,3 +1,4 @@
 Line 1: Hello world
-Line 2: This is a test.
+Line 2: This line was changed.
+New Line 2.5: Inserted line.
 Line 3: End of file.
"""

    # 3. Parse the patch string
    # The `strip` argument removes leading path components (e.g., 'a/' or 'b/')
    patchset = from_string(patch_content)

    if not patchset:
        print("Failed to parse patch content.")
    else:
        # 4. Apply the patch to the specified root directory
        # The `root` argument is crucial to apply the patch outside the current working directory.
        success = patchset.apply(strip=1, root=temp_dir)

        if success:
            print(f"Patch applied successfully to files in {temp_dir}.")
            print(f"\nPatched file content of '{os.path.basename(original_file_path)}':\n" \
                  f"{open(original_file_path, 'r').read()}")
        else:
            print("Failed to apply patch.")

finally:
    # Clean up the temporary directory
    shutil.rmtree(temp_dir)
    print(f"\nCleaned up temporary directory: {temp_dir}")

view raw JSON →