Generate visual diff PDFs for Overleaf/LaTeX projects. Additions are highlighted in blue; deletions are optionally shown in red strikethrough.
Built on top of latexdiff with fixes for common pain points: broken section titles, table environments, merge commits, and noisy single-word changes.
# Clone into your project (or anywhere in PATH)
git clone git@github.com:snuhcs/overleaf-diff.git
# cd into your Overleaf project
cd my-paper/
# Generate diff against a commit
/path/to/overleaf-diff/overleaf-diff.sh HEAD~5The output PDF is saved to ./output/ and opened automatically on macOS.
./overleaf-diff.sh <base-commit> [options]
| Option | Default | Description |
|---|---|---|
--min-words N |
1 |
Ignore changes shorter than N consecutive words |
--show-deletions |
off | Show deletions as red strikethrough |
--output DIR |
./output |
Output directory |
--name PREFIX |
directory name | PDF filename prefix |
--no-open |
auto-open | Don't open PDF after generation |
# Basic diff — blue additions only
./overleaf-diff.sh abc1234
# Filter out trivial 1-2 word changes
./overleaf-diff.sh abc1234 --min-words 3
# Show both additions (blue) and deletions (red strikethrough)
./overleaf-diff.sh abc1234 --show-deletions
# Custom output
./overleaf-diff.sh abc1234 --output ./build --name MyPaper --no-open- latexdiff (included with TeX Live)
- pdflatex + bibtex
- Python 3 (for the short-change filter)
- Extracts the old and current versions from git
- Runs
latexdiffper-file (not flattened) to avoid.bblcorruption - Cleans up structural markers that break compilation
- Filters out short changes (<
--min-words) viastrip_short_diff.py - Handles new files (wraps in blue) and new tables (scoped
\color{blue}) - Injects a minimal preamble for
\DIFadd/\DIFdelrendering - Compiles with 3 pdflatex passes + bibtex
- Section/subsection titles are excluded from diff markup (no broken headings)
.bblfiles are never flattened (noIllegal parametererrors)- Table environments are handled separately (no broken
tabular) - Merge commits are resolved automatically (uses effective parent)
- Noisy changes can be filtered by word count
overleaf-diff.sh # Main script
strip_short_diff.py # Helper: strips \DIFadd{} markup for short changes
The script works with standard Overleaf project structures:
my-paper/
main.tex # Entry point
definition.tex # Optional preamble (used for injection point)
section/ # \input{section/...} files
figure/ # \input{figure/...} table .tex files
reference.bib
If definition.tex is not found, the preamble is injected before \begin{document}.
MIT