Quarto GitHub Pages branch graft tool
Project description
quarto-graft
A Python CLI for multi-author Quarto documentation using git worktrees
Quarto Graft is a command-line tool that lets multiple authors collaborate on a single Quarto website without merge conflicts. Each author works in an isolated git branch (a "graft"), and the main branch (the "trunk") automatically assembles everything into one unified, searchable site.
Key Concepts
Trunk
The trunk is your main branch and the foundation of your Quarto site. It defines:
- The overall site structure (navbar, sidebar, styling)
- Collars: named attachment points where grafts connect (e.g., "main", "notes", "bugs")
- Site configuration and templates
Grafts
Grafts are isolated git branches where authors work independently. Each graft:
- Runs in its own git worktree with its own dependencies
- Can use any language or environment (Python, R, Julia, etc.)
- Specifies which collar it attaches to
- Gets automatically included in the trunk's navigation
Collars
Collars are attachment points in the trunk's _quarto.yaml that organize grafts into sections:
sidebar:
contents:
- section: My Grafts
contents:
- _GRAFT_COLLAR: main
- section: Notes
contents:
- _GRAFT_COLLAR: notes
Templates
Everything is template-based and customizable:
- Trunk templates: Define your site's look, feel, and structure
- Graft templates: Provide starter content for different types of contributions
- Templates use Jinja2 for configuration
- Create custom templates for your organization
Why Use Quarto Graft?
Traditional multi-author collaboration problems:
- Merge conflicts on
main - Shared dependencies causing version conflicts
- One author's broken code blocks everyone
- Can't use different languages/tools per section
Quarto Graft solutions:
- ✅ Each author owns a branch = zero merge conflicts
- ✅ Each graft has independent dependencies
- ✅ Broken grafts use last-good fallbacks with warnings
- ✅ Mix Python, R, Julia, or any language per graft
- ✅ Trunk never executes contributor code, only renders artifacts
- ✅ Organize content with multiple collars (sections)
What You Get
- 🚀 Python CLI (
quarto-graft) for project management - 📦 Customizable trunk and graft templates
- 🔧 Git worktree-based isolation
- 🎯 Multiple collar attachment points
- 🔄 Automatic navigation updates
- 💾 Last-good build fallbacks
- 🔍 Full-site search across all grafts
- ⚡ Fast trunk builds (no code execution)
Who This Is For
- Multi-author books and research publications
- Data science teams (quant research, education platforms)
- Internal documentation portals
- Open source projects with distributed contributors
- Anyone managing versioned, multi-contributor content
Quick Start
Prerequisites
Before using Quarto Graft, ensure you have:
- Python 3.11+ installed
- Git initialized in your project (
git initand at least one commit) - Quarto CLI installed:
pip install quarto-cli # OR download from https://quarto.org/docs/get-started/
Installation
pip install quarto-graft
Step 1: Initialize a Trunk
The trunk is your main documentation site. Run this from your git repository root:
# Interactive mode (recommended for first-time setup)
quarto-graft trunk init
# Or non-interactive with options
quarto-graft trunk init --template markdown
This creates:
_quarto.yaml- Quarto configuration with collar markersgrafts.yaml- Graft branch configuration (initially empty)index.qmd- Landing page for your site
Note: The command runs in your current directory (doesn't create a subdirectory).
Step 2: Create Your First Graft
A graft is an isolated author branch:
# Interactive mode (will prompt for template and collar)
quarto-graft graft create demo
# Or specify all options
quarto-graft graft create demo --template py-jupyter --collar main
This creates:
- Git branch:
graft/demo(customizable with--branch-name) - Worktree at:
.grafts-cache/demo/ - Entry in
grafts.yaml - Automatically pushes to origin (use
--no-pushto skip)
Available templates:
markdown- Simple Markdown/QMD documentspy-jupyter- Python + Jupyter notebookspy-marimo- Python + Marimo notebooks
Step 3: Build and Preview
Build all grafts and update the trunk:
# Build all grafts (fetches latest, builds, updates navigation)
quarto-graft trunk build
# Preview the complete site locally
quarto preview
What happens during trunk build:
- Fetches latest changes from all graft branches
- Builds each graft in isolation (or uses last-good fallback if broken)
- Exports content to
grafts__/<graft-name>/ - Updates
_quarto.yamlwith navigation - Creates/updates
grafts.lockwith build state
View your site: Open the URL from quarto preview (usually http://localhost:4200)
Working on a Graft
Authors can work on grafts in two ways:
Option 1: Use the worktree directory (recommended for independent work)
cd .grafts-cache/demo
# Edit files, run notebooks, commit, push
git add . && git commit -m "Updated content"
git push
Option 2: Checkout the branch (if you need to switch contexts)
git checkout graft/demo
# Work normally
git add . && git commit -m "Updates"
git push
git checkout main # Return to trunk
After pushing graft changes, rebuild from trunk to see updates:
quarto-graft trunk build
Full Example Workflow
# 1. Set up project
mkdir my-docs && cd my-docs
git init
git commit --allow-empty -m "Initial commit"
# 2. Install quarto-graft
pip install quarto-graft
# 3. Initialize trunk
quarto-graft trunk init
git add .
git commit -m "Initialize trunk"
git push -u origin main
# 4. Create graft for Alice
quarto-graft graft create alice-chapter --collar main
# 5. Alice works in her graft
cd .grafts-cache/alice-chapter
# ... edit files ...
git add . && git commit -m "Added my chapter"
git push
cd ../..
# 6. Build and preview trunk
git checkout main
quarto-graft trunk build
quarto preview
# 7. Deploy to GitHub Pages (when ready)
quarto publish gh-pages
Key Commands Reference
| Command | Description |
|---|---|
quarto-graft trunk init |
Create trunk structure from template |
quarto-graft trunk build |
Build all grafts and update trunk navigation |
quarto-graft trunk lock |
Update _quarto.yaml from grafts.lock (no rebuild) |
quarto-graft graft create <name> |
Create new graft branch |
quarto-graft graft build --branch <name> |
Build single graft |
quarto-graft graft list |
Show all graft branches and their status |
quarto-graft graft destroy <name> |
Delete graft (branch, worktree, config) |
Need Help?
- Architecture details: See ARCHITECTURE.md
- Interactive mode: Run
quarto-graftwith no arguments - Command help: Use
--helpon any command - Issues: https://github.com/jr200/quarto-graft/issues
License
Released under the MIT License. Free to use, modify, and redistribute with attribution.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quarto_graft-0.0.2.tar.gz.
File metadata
- Download URL: quarto_graft-0.0.2.tar.gz
- Upload date:
- Size: 741.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3802051f2a0e3d56ed56e0cc503863b315a336ee190c4147bcc22d1a848aa00
|
|
| MD5 |
3c9a3dfc31f294c3e8851c75adb050ef
|
|
| BLAKE2b-256 |
87ee2c6fd324492ed0778b6df21cf1edee13724c9b69dba0dafab21e7589b1aa
|
File details
Details for the file quarto_graft-0.0.2-py3-none-any.whl.
File metadata
- Download URL: quarto_graft-0.0.2-py3-none-any.whl
- Upload date:
- Size: 763.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f09536291c2bc141dc3e3cf2f44416b101761bc807e13b59d5b84f274ec7a519
|
|
| MD5 |
74ebe3a55bb02fc86a57b4e7de8585ec
|
|
| BLAKE2b-256 |
5809860b1ecc1f120304e5a37c86a0d749d70d8f50fe7de5400d0710152dfeea
|