Add example

This commit is contained in:
Andras Schmelczer 2026-03-11 21:04:55 +00:00
parent 545be141d8
commit 92e0697b05
4 changed files with 90 additions and 1 deletions

View file

@ -104,7 +104,7 @@ result = reconcile(parent, left, right)
print(result["text"]) # "Hi beautiful world" print(result["text"]) # "Hi beautiful world"
``` ```
See the [advanced Python examples](docs/advanced-python.md) for cursor tracking, change provenance, and compact diffs. See the [merge-file example](examples/merge_file.py) for a file-merging CLI, or the [advanced examples document](docs/advanced-python.md) for cursor tracking, change provenance, and compact diffs.
## Motivation ## Motivation

View file

@ -86,3 +86,7 @@ assert reconstructed == changed
``` ```
Diff entries are positive integers (retain N characters), negative integers (delete N characters), and strings (insert text). Diff entries are positive integers (retain N characters), negative integers (delete N characters), and strings (insert text).
## File Merging Example
For a complete file-merging CLI (a trivial `git merge-file`), see [`examples/merge_file.py`](../examples/merge_file.py).

38
examples/merge_file.py Normal file
View file

@ -0,0 +1,38 @@
"""Merge three versions of a file: mine, base, and theirs.
A trivial version of git merge-file (https://git-scm.com/docs/git-merge-file).
Run it with:
uv run --directory reconcile-python \
python ../examples/merge_file.py my.txt base.txt their.txt [output.txt]
"""
from __future__ import annotations
import sys
from pathlib import Path
from reconcile_text import reconcile
def main() -> None:
args = sys.argv[1:]
if len(args) < 3 or len(args) > 4:
print("Usage: merge_file.py <mine> <base> <theirs> [output]", file=sys.stderr)
sys.exit(1)
mine = Path(args[0]).read_text()
base = Path(args[1]).read_text()
theirs = Path(args[2]).read_text()
result = reconcile(base, mine, theirs)
if len(args) == 4:
Path(args[3]).write_text(result["text"])
else:
print(result["text"], end="")
if __name__ == "__main__":
main()

View file

@ -1,11 +1,14 @@
from __future__ import annotations from __future__ import annotations
import subprocess
import sys
from pathlib import Path from pathlib import Path
import pytest import pytest
from reconcile_text import diff, reconcile, reconcile_with_history, undiff from reconcile_text import diff, reconcile, reconcile_with_history, undiff
EXAMPLES_DIR = Path(__file__).resolve().parent.parent.parent / "examples"
RESOURCES_DIR = Path(__file__).resolve().parent.parent.parent / "tests" / "resources" RESOURCES_DIR = Path(__file__).resolve().parent.parent.parent / "tests" / "resources"
FILES = ["pride_and_prejudice.txt", "room_with_a_view.txt", "blns.txt"] FILES = ["pride_and_prejudice.txt", "room_with_a_view.txt", "blns.txt"]
@ -118,6 +121,50 @@ class TestUndiff:
undiff("short", [100]) undiff("short", [100])
class TestExamples:
def test_merge_file_stdout(self, tmp_path: Path) -> None:
(tmp_path / "base.txt").write_text("Hello world")
(tmp_path / "mine.txt").write_text("Hello beautiful world")
(tmp_path / "theirs.txt").write_text("Hi world")
result = subprocess.run(
[
sys.executable,
str(EXAMPLES_DIR / "merge_file.py"),
str(tmp_path / "mine.txt"),
str(tmp_path / "base.txt"),
str(tmp_path / "theirs.txt"),
],
capture_output=True,
text=True,
check=True,
)
assert result.stdout == "Hi beautiful world"
def test_merge_file_output_file(self, tmp_path: Path) -> None:
(tmp_path / "base.txt").write_text("Hello world")
(tmp_path / "mine.txt").write_text("Hello beautiful world")
(tmp_path / "theirs.txt").write_text("Hi world")
output = tmp_path / "output.txt"
subprocess.run(
[
sys.executable,
str(EXAMPLES_DIR / "merge_file.py"),
str(tmp_path / "mine.txt"),
str(tmp_path / "base.txt"),
str(tmp_path / "theirs.txt"),
str(output),
],
capture_output=True,
text=True,
check=True,
)
assert output.read_text() == "Hi beautiful world"
class TestDiffUndiffInverse: class TestDiffUndiffInverse:
"""Verify diff/undiff roundtrip across large real-world texts.""" """Verify diff/undiff roundtrip across large real-world texts."""