Tutorial¶
Binoc is most useful when a plain filesystem diff would be noisy. In this tutorial you will use the sample snapshots in this repository and run a few increasingly useful diffs.
Clone the repository so you have the tutorial fixtures:
git clone https://github.com/harvard-lil/binoc
cd binoc
Install binoc so the plain binoc command is available:
pip install binoc
Or run it without installing:
uvx binoc diff path/to/snapshot-a path/to/snapshot-b
The examples below show the plain commands a user would run after
installing binoc.
Build the example snapshots¶
The repository keeps some fixtures as source trees and materializes the real archives on demand. Run this once from the repository root:
You now have a test-vectors-materialized/ folder full of ready-to-diff
snapshots.
Run your first diff¶
Start with the simplest possible case: two identical snapshots.
binoc diff ./test-vectors-materialized/trivial-identical/snapshot-a ./test-vectors-materialized/trivial-identical/snapshot-b
# Changelog: ./test-vectors-materialized/trivial-identical/snapshot-a → ./test-vectors-materialized/trivial-identical/snapshot-b
See a text-file change¶
Now compare two snapshots where one text file changed:
cat ./test-vectors-materialized/single-file-modify-text/snapshot-a/story.txt
printf '\n---\n'
cat ./test-vectors-materialized/single-file-modify-text/snapshot-b/story.txt
binoc diff ./test-vectors-materialized/single-file-modify-text/snapshot-a ./test-vectors-materialized/single-file-modify-text/snapshot-b
# Changelog: ./test-vectors-materialized/single-file-modify-text/snapshot-a → ./test-vectors-materialized/single-file-modify-text/snapshot-b
- **story.txt**: 2 lines added; 1 line removed
- Line changes
- line 2: 'Line 2' -> 'Line 2 revised'
So far this is just a changelog-style summary of what you would get with a textual diff.
CSV-aware diffing¶
Binoc gets more interesting when the format itself matters. Here the same rows are present in both snapshots, but the CSV columns were reordered:
cat ./test-vectors-materialized/csv-column-reorder/snapshot-a/data.csv
printf '\n---\n'
cat ./test-vectors-materialized/csv-column-reorder/snapshot-b/data.csv
binoc diff ./test-vectors-materialized/csv-column-reorder/snapshot-a ./test-vectors-materialized/csv-column-reorder/snapshot-b
# Changelog: ./test-vectors-materialized/csv-column-reorder/snapshot-a → ./test-vectors-materialized/csv-column-reorder/snapshot-b
- **data.csv**: Columns reordered
That is the first genuinely useful binoc result. A line-oriented diff would treat this like a rewrite. Binoc understands the header row and recognizes that the data itself did not change.
Now look at a more realistic update: one new column, a reorder, and a new row in the same file.
binoc diff ./test-vectors-materialized/csv-mixed-changes/snapshot-a ./test-vectors-materialized/csv-mixed-changes/snapshot-b
# Changelog: ./test-vectors-materialized/csv-mixed-changes/snapshot-a → ./test-vectors-materialized/csv-mixed-changes/snapshot-b
- **data.csv**: Column added: 'email'; Columns reordered; 1 row added
- Rows added
- row 3: 'SF', 'Charlie', '35'
- Add Column: name: 'email'; values: {"total_values":3,"truncated":false,"values":["a@test.com","b@test.com","c@test.com"]}
The changelog expresses a complex change in terms a dataset maintainer can act on.
Look inside a zip¶
The same diff command works on nested content too:
binoc diff ./test-vectors-materialized/zip-simple/snapshot-a ./test-vectors-materialized/zip-simple/snapshot-b
# Changelog: ./test-vectors-materialized/zip-simple/snapshot-a → ./test-vectors-materialized/zip-simple/snapshot-b
- **archive.zip/>data.txt**: 1 line added; 1 line removed
- Line changes
- line 1: 'hello from zip A' -> 'hello from zip B'
- **archive.zip/>extra.txt**: Added
Binoc expands container formats like zip before dispatching their contents.
Paths such as archive.zip/data.txt point inside the archive.
Unsupported formats¶
When Binoc has no semantic rules for a domain format, it still reports a truthful fallback. For example, the standard library does not understand FASTA:
binoc diff ./docs/examples/fasta-demo/snapshot-a/sequences.fasta ./docs/examples/fasta-demo/snapshot-b/sequences.fasta
# Changelog: ./docs/examples/fasta-demo/snapshot-a/sequences.fasta → ./docs/examples/fasta-demo/snapshot-b/sequences.fasta
- **sequences.fasta**: Binary content changed; 1 extracted string added, 1 extracted string removed
- Extracted strings added
- '>gene_1 source=NCBI retrieved=2024-06\nATCGATCGATCG\n>gene_2 source=NCBI retrieved=2024-06\nGCTAGCTAGCTA\n'
- Extracted strings removed
- '>gene_1 src=GenBank date=2024-01\nATCGATCGATCG\n>gene_2 src=GenBank date=2024-01\nGCTAGCTAGCTA\n'
The suggestion is intentional: it tells you the output is a safe byte-level result, not a domain-specific FASTA interpretation.
Where next¶
If you want to keep working from the command line, continue with Diff two snapshots, Save and render changesets, and Extract changed data.
If you want to use packaged extensions, go to Install and use plugins. If you want to understand how current plugins fit into the engine, continue with Plugin model.
If you want to learn more about the design of binoc, start with the Architecture overview.