Skip to main content

dffs

Pipe and diff files: execute shell pipelines, diff/compare/join results.

dffs on PyPI

Apply a transform to both sides of a comparison, then diff the results — like Haskell's on:

a ─→ [f] ─→ f(a) ─┐
                    ├─→ [cmp] ─→ result
b ─→ [f] ─→ f(b) ─┘

Three CLIs apply this pattern with different comparators:

CLI cmp Description
git-diff-x diff Diff a Git-tracked file at two commits, through a pipeline
diff-x diff Diff two files through a pipeline
comm-x comm Set operations on two files through a pipeline

Install

pip install dffs

CLIs

git-diff-x

Diff a Git-tracked file at two commits (or one commit vs. the worktree), after piping both versions through a command pipeline.

Examples

JSON: readable diffs of compact files

A config file is stored as compact JSON (one line, no whitespace). In commit 38856a0, a few fields were updated, but git diff is unreadable:

-{"name":"myapp","version":"1.2.3","settings":{"debug":false,"logLevel":"info","maxRetries":3,...}}
+{"name":"myapp","version":"1.3.0","settings":{"debug":false,"logLevel":"warn","maxRetries":3,...}}

git diff-x with jq pretty-prints both sides before diffing, so you see exactly what changed:

git diff-x -R 38856a0 'jq .' example/config.json
# 3c3
# <   "version": "1.2.3",
# ---
# >   "version": "1.3.0",
# 6c6
# <     "logLevel": "info",
# ---
# >     "logLevel": "warn",
# 11c11
# <       "analytics": false
# ---
# >       "analytics": true

This also normalizes out any whitespace or key-ordering differences — only actual value changes appear.

CSV: ignoring row order

A CSV's rows were reordered in commit 7f0c468:

git diff --stat 7f0c468^..7f0c468 -- example/data.csv
# example/data.csv | 4 ++--
# 1 file changed, 2 insertions(+), 2 deletions(-)

git diff shows a noisy patch, but sorting first reveals the data is unchanged:

git diff-x -R 7f0c468 sort example/data.csv
# (no output — the sorted contents are identical)
CSV: comparing column names

In commit 0bdec95, the city column was replaced with role. Extract and compare just the header:

git diff-x -R 0bdec95 "head -1 | tr , '\n'" example/data.csv
# 3c3
# < city
# ---
# > role
Comparing line counts

Compare line-count (wc -l) of this README, before and after commit 8b7a761:

git-diff-x -R 8b7a761 'wc -l' README.md
# 1c1
# < 16
# ---
# > 206
More examples
# Compare the number of lines (`wc -l`) in file `foo` at the previous vs. current commit
# (`-R HEAD` is equivalent to `-r HEAD^..HEAD`).
git diff-x -R HEAD wc -l foo

# Colorized (`-c`) diff of `md5sum`s of `foo`, at HEAD (last committed value) vs. the current
# worktree content.
git diff-x -c md5sum foo

# Use `-` to separate pipeline commands from paths (when more than one path is to be diffed),
# e.g. this compares the largest 10 numbers in `file{1,2}` (HEAD vs. worktree):
git diff-x 'sort -rn' head - file1 file2

Usage

git-diff-x
# Usage: git-diff-x [OPTIONS] [exec_cmd...] [<path> | - [paths...]]
#
#   Diff files at two commits, or one commit and the current worktree, after
#   applying an optional command pipeline.
#
#   Examples:
#
#   # Compare the number of lines (`wc -l`) in file `foo` at the previous vs.
#   current commit (`-r HEAD^..HEAD`):
#
#   git diff-x -r HEAD^..HEAD wc -l foo
#
#   # Colorized (`-c`) diff of `md5sum`s of `foo`, at HEAD (last committed
#   value) vs. the current worktree content:
#
#   git diff-x -c md5sum foo
#
#   # Use `-` to separate pipeline commands from paths (when more than one path
#   is to be diffed), e.g. this compares the largest 10 numbers in `file{1,2}`
#   (HEAD vs. worktree):
#
#   git diff-x 'sort -rn' head - file1 file2
#
# Options:
#   -c, --color / --no-color     Colorize the output (default: auto, based on
#                                TTY)
#   -r, --refspec TEXT           <commit 1>..<commit 2> (compare two commits) or
#                                <commit> (compare <commit> to the worktree)
#   -R, --ref TEXT               Diff a specific commit; alias for `-r
#                                <ref>^..<ref>`
#   -t, --staged                 Compare HEAD vs. staged changes (index)
#   -P, --pipefail               Check all pipeline commands for errors (like
#                                bash's `set -o pipefail`); default only checks
#                                last command
#   -s, --shell-executable TEXT  Shell to use for executing commands; defaults
#                                to $SHELL
#   -S, --no-shell               Don't pass `shell=True` to Python
#                                `subprocess`es
#   -U, --unified INTEGER        Number of lines of context to show (passes
#                                through to `diff`)
#   -V, --version                Show version and exit
#   -v, --verbose                Log intermediate commands to stderr
#   -w, --ignore-whitespace      Ignore whitespace differences (pass `-w` to
#                                `diff`)
#   -x, --exec-cmd TEXT          Command(s) to execute before invoking `comm`;
#                                alternate syntax to passing commands as
#                                positional arguments
#   --help                       Show this message and exit.

diff-x

The underlying building block — same concept, but for two arbitrary files (not Git commits).

Examples

Given two similar JSON objects, where one is compact and the other is pretty-printed:

echo '{"a":1,"b":2}' > 1.json
echo '{"a":1,"b":3}' | jq > 2.json

diff {1,2}.json outputs the entirety of both objects:

1c1,4
< {"a":1,"b":2}
---
> {
>   "a": 1,
>   "b": 3
> }

diff-x 'jq .' {1,2}.json pretty-prints each side before diffing:

3c3
<   "b": 2
---
>   "b": 3

Usage

diff-x
# Usage: diff-x [OPTIONS] [exec_cmd...] <path1> <path2>
#
#   Diff two files after running them through a pipeline of other commands.
#
# Options:
#   -c, --color / --no-color     Colorize the output (default: auto, based on
#                                TTY)
#   -P, --pipefail               Check all pipeline commands for errors (like
#                                bash's `set -o pipefail`); default only checks
#                                last command
#   -s, --shell-executable TEXT  Shell to use for executing commands; defaults
#                                to $SHELL
#   -S, --no-shell               Don't pass `shell=True` to Python
#                                `subprocess`es
#   -U, --unified INTEGER        Number of lines of context to show (passes
#                                through to `diff`)
#   -V, --version                Show version and exit
#   -v, --verbose                Log intermediate commands to stderr
#   -w, --ignore-whitespace      Ignore whitespace differences (pass `-w` to
#                                `diff`)
#   -x, --exec-cmd TEXT          Command(s) to execute before invoking `comm`;
#                                alternate syntax to passing commands as
#                                positional arguments
#   --help                       Show this message and exit.

comm-x

comm performs set intersection/difference; comm-x lets you run a pipeline on each input first.

Examples

Given two similar lists of numbers, but in different orders:

seq 10 > 1.txt
seq 10 -2 0 > 2.txt

comm outputs gibberish, because the files aren't in sorted order:

comm 1.txt 2.txt
# 1
# 	10
# 2
# 3
# 4
# 5
# 6
# 7
# 		8
# comm: file 2 is not in sorted order
# 	6
# 	4
# 	2
# 	0
# 9
# comm: file 1 is not in sorted order
# 10
# comm: input is not in sorted order

comm-x sort sorts each file first:

comm-x sort 1.txt 2.txt
# 	0
# 1
# 		10
# 		2
# 3
# 		4
# 5
# 		6
# 7
# 		8
# 9

Shell Integration

Add convenient aliases to your shell by adding this to your ~/.bashrc or ~/.zshrc:

eval "$(dffs-shell-integration bash)"

This provides aliases with the following suffix conventions:

  • c = color, n = no-color, w = ignore-whitespace
  • r = ref (-R, compare commit to parent), s = refspec (-r), t = staged (--staged)

Examples

Alias Expands to
dx diff-x
dxc diff-x --color
cx comm-x
gdx git diff-x
gdxc git diff-x --color
gdxr git diff-x -R (compare commit to parent)
gdxs git diff-x -r (explicit refspec)
gdxt git diff-x --staged
gdxcr git diff-x --color -R
gdxtw git diff-x --staged -w

To see all available aliases:

dffs-shell-integration bash

To load only aliases for a specific command:

eval "$(dffs-shell-integration bash git-diff-x)"

Metadata

Release files for dffs 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dffs 0.1.7
File Size Uploaded
dffs-0.1.7.tar.gz 37.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dffs 0.1.7
File Interpreter ABI Platform
dffs-0.1.7-py3-none-any.whl Python 3 none any Details

Total release size: 53.5 kB

Release files / dffs-0.1.7.tar.gz

Download URL dffs-0.1.7.tar.gz
Size 37.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9340b783aa4a5a36b289821c59e132707589f2e8e4de15c0ee22c9a9a0ddc613
BLAKE2b-256 checksum
How to use checksums
efe53b19db0093a92ade0f4a7c983fcda292ed0da5dc48367766ef4f54d0f009
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 15, 2026.

Transparency log

Release files / dffs-0.1.7-py3-none-any.whl

Download URL dffs-0.1.7-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
feb40994f197c5b94ea124caf37fd150a8b7729cf9c233b5012b98d24526c3ce
BLAKE2b-256 checksum
How to use checksums
ea55dae8982c989dbea3aaa73a61648242543e1795e6a95aa9593813b62f4c60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.7 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page