Why Version Control for LaTeX?
You're writing your thesis. Three days ago, you deleted a paragraph. Today, you realize it was perfect for another section.
Without version control: Gone forever.
With Git: git checkout HEAD~15 -- chapter3.tex and it's back.
Version control gives you:
- Complete history of every change
- Ability to recover any previous version
- Safe experimentation with branches
- Seamless collaboration without conflicts
- Automatic backup to remote repositories
Setting Up Git for LaTeX
Initial Repository Setup
Start a new LaTeX project with Git:
# Create project directory
mkdir my-paper
cd my-paper
# Initialize Git
git init
# Create .gitignore for LaTeX
cat > .gitignore << 'EOF'
# LaTeX auxiliary files
*.aux
*.bbl
*.blg
*.fdb_latexmk
*.fls
*.log
*.out
*.toc
*.synctex.gz
*.synctex(busy)
# Generated files
*.pdf
# Editor files
*.swp
*~
.DS_Store
# Backup files
*.bak
*.backup
EOF
# Create initial structure
touch main.tex
mkdir figures
mkdir sections
# Initial commit
git add .
git commit -m "Initial project structure"Connecting to GitHub
Create a remote repository:
# Create repo on GitHub first, then:
git remote add origin https://github.com/yourusername/my-paper.git
git branch -M main
git push -u origin mainOr use GitHub CLI:
gh repo create my-paper --private --source=. --pushDaily Workflow
The Basic Cycle
Every writing session should follow this pattern:
# Start of session: get latest changes
git pull
# Write your content in Thetapad...
# End of session: commit and push
git add .
git commit -m "Draft introduction section"
git pushWriting Good Commit Messages
Bad commit messages:
"updates"
"fixed stuff"
"asdfasdf"Good commit messages:
"Add literature review for ML section"
"Fix citation format in methodology"
"Revise abstract based on advisor feedback"
"Add Figure 3: experimental results comparison"Format: What you did + why (if not obvious)
Viewing History
See what changed and when:
# View commit history
git log --oneline
# See what changed in a specific commit
git show abc1234
# See changes between versions
git diff HEAD~5 HEAD -- chapter2.tex
# See who changed what line (useful for collaboration)
git blame chapter2.texBranching Strategies
Simple Strategy: Main Only
For solo projects, working directly on main is fine:
# All work on main
git checkout main
# write...
git commit -m "Progress on results section"
git pushFeature Branches
For larger projects or collaboration:
# Create branch for a specific task
git checkout -b add-methodology-section
# Work on the branch
# ... write methodology ...
git commit -m "Draft methodology section"
# When done, merge back
git checkout main
git merge add-methodology-section
git branch -d add-methodology-section
git pushDocument Versions
Need different versions for different submissions?
# Create branch for journal submission
git checkout -b journal-nature
# Modify format, length, etc.
git commit -m "Format for Nature submission"
# Create another for conference
git checkout main
git checkout -b conference-neurips
# Different modifications
git commit -m "Format for NeurIPS submission"Collaboration Workflow
Sharing the Repository
Add collaborators on GitHub:
- Go to repository Settings → Collaborators
- Add team members by username or email
- They clone and start contributing
Avoiding Conflicts
LaTeX conflicts are painful. Minimize them:
1. Work on different files:
# Split document into sections
main.tex # Just includes
sections/
├── intro.tex # Alice works here
├── methods.tex # Bob works here
├── results.tex # Carol works here2. Pull before you start:
git pull # Always do this first!3. Commit frequently:
# Small, frequent commits > large, rare commits
git commit -m "Add paragraph on data preprocessing"
# Not: one commit with 3 days of workResolving Conflicts
When conflicts happen:
git pull
# CONFLICT in chapter2.tex
# Open the file, find conflict markers:
<<<<<<< HEAD
Your version of the text
=======
Their version of the text
>>>>>>> abc1234
# Edit to resolve, then:
git add chapter2.tex
git commit -m "Resolve conflict in chapter2"
git pushIntegration with Thetapad
Local-First + Git
Thetapad's local-first architecture works naturally with Git:
- Your files exist locally (Git works on local files)
- Make changes in Thetapad
- Commit and push from your terminal
- Pull changes from collaborators
Thetapad ←→ Local Files ←→ Git ←→ GitHubAutomatic Sync Setup
For seamless sync between Thetapad and GitHub:
Option 1: Manual (most control)
# After editing in Thetapad
git add .
git commit -m "Your message"
git pushOption 2: Watch and auto-commit
# Using a file watcher (example with fswatch on Mac)
fswatch -o *.tex | xargs -n1 -I{} git commit -am "Auto-save"Option 3: Git hooks in Thetapad (if available) Configure auto-commit on save in Thetapad settings.
Advanced Techniques
LaTeX + latexmk + Git
Use latexmk for smart compilation:
# .latexmkrc in your project
$pdf_mode = 1;
$pdflatex = 'pdflatex -interaction=nonstopmode';
$bibtex_use = 2;Integrate with Git:
# Pre-commit hook to ensure document compiles
# .git/hooks/pre-commit
#!/bin/bash
latexmk -pdf main.tex
if [ $? -ne 0 ]; then
echo "LaTeX compilation failed!"
exit 1
fiGit LFS for Large Files
For repositories with large figures or PDFs:
# Install Git LFS
git lfs install
# Track large files
git lfs track "*.pdf"
git lfs track "figures/*.png"
git lfs track "figures/*.jpg"
# Commit the tracking config
git add .gitattributes
git commit -m "Configure Git LFS for large files"Continuous Integration
Auto-compile PDFs with GitHub Actions:
# .github/workflows/compile.yml
name: Compile LaTeX
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Compile LaTeX
uses: xu-cheng/latex-action@v2
with:
root_file: main.tex
- name: Upload PDF
uses: actions/upload-artifact@v3
with:
name: paper
path: main.pdfNow every push generates a compiled PDF automatically.
Release Tags for Submissions
Tag important versions:
# Tag submission versions
git tag -a v1.0-submitted -m "Initial journal submission"
git push --tags
# Later, after revisions
git tag -a v2.0-revised -m "Revised submission with reviewer comments"
git push --tags
# View tags
git tag -l
# Checkout a tagged version
git checkout v1.0-submittedBest Practices
1. One Sentence Per Line
Makes diffs readable:
Bad:
This is the first sentence. This is the second sentence. This is the third sentence that goes on for quite a while and makes it hard to see what changed.Good:
This is the first sentence.
This is the second sentence.
This is the third sentence that goes on for quite a while.Now git diff shows exactly which sentence changed.
2. Meaningful Structure
Organize files logically:
my-paper/
├── main.tex # Document root
├── preamble.tex # Packages and config
├── references.bib # Bibliography
├── sections/
│ ├── 01-intro.tex
│ ├── 02-methods.tex
│ ├── 03-results.tex
│ └── 04-conclusion.tex
├── figures/
│ ├── fig1-overview.pdf
│ └── fig2-results.pdf
└── appendices/
└── supplementary.tex3. Commit Logical Units
Each commit should be one logical change:
# Good: separate commits for separate changes
git commit -m "Add Figure 2: experimental setup"
git commit -m "Write results for experiment A"
git commit -m "Fix typo in abstract"
# Bad: everything in one commit
git commit -m "Various updates"4. Use Branches for Experiments
Trying something risky?
git checkout -b experimental-restructure
# Try major changes
# If it works: merge back
# If it fails: git checkout main (abandon branch)5. Regular Backups
Even with Git, push frequently:
# End of every session
git push
# Your work is now:
# - On your machine
# - On GitHub's servers
# - (Optionally) synced to collaboratorsTroubleshooting
"I Made Changes but They're Not Showing"
# Check status
git status
# If untracked files, add them
git add .
# If changes not staged, add them
git add -A"I Want to Undo My Last Commit"
# Undo commit but keep changes
git reset --soft HEAD~1
# Undo commit and changes (careful!)
git reset --hard HEAD~1"I Have Merge Conflicts"
# See what files have conflicts
git status
# Edit files to resolve (remove <<< === >>> markers)
# Then mark as resolved
git add <resolved-file>
git commit -m "Resolve merge conflict""I Accidentally Committed Large Files"
# Remove from history (dangerous, coordinate with team)
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch large-file.pdf' HEAD
# Better: set up .gitignore first
echo "*.pdf" >> .gitignore
git add .gitignore
git commit -m "Ignore PDF files"Conclusion
Git + Thetapad gives you:
- Complete history: Never lose work, always recover past versions
- Safe collaboration: Multiple people, no overwriting
- Experimentation: Branch, try things, merge or abandon
- Backup: Your work exists in multiple places
- Transparency: See who changed what and when
Start simple—just commit and push regularly. Add complexity (branches, CI, releases) as your needs grow.
Your future self, reviewing revision history at 2 AM before a deadline, will thank you.
For more advanced Git workflows, see the Pro Git book (free online) or our LaTeX collaboration best practices guide.