Git workflows for documentation
Branches, commits, pull requests and previews for a Reed project, and the workflow that ties them together.
Git tracks every change to your documentation: what changed, who changed it, when, and — if the commit message is any good — why. It lets several people work on the docs at once, lets a reviewer read a change before readers do, and lets you undo a mistake by reverting one commit.
On most documentation platforms git is one option among several. On Reed it is the only
one. There is no web editor, no dashboard and no hosted build: your docs are a
docs.json and a directory of MDX in a repository, and Reed is a CLI that turns them into
a static site. Everything a platform would do for you — branching, review, previews,
publishing — you do with your own repository, your own CI and your own host. That is more
setup than clicking Publish. It is also exactly the workflow your engineers already
use for code, with nothing proprietary in the middle.
Why git for documentation
Section titled “Why git for documentation”- History. Every file carries a full record of what changed and why.
- Parallel work. Different people edit different parts of the docs at the same time without stepping on each other.
- Safety. Changes on a branch cannot affect the live site until you merge them.
- Review. A teammate reads the diff before readers see the change.
- Recovery. A bad change is one
git revertaway from undone.
Core concepts
Section titled “Core concepts”Repository
The project: your docs.json, your content directory, any assets, and the complete history of every one of them. A Reed project is an ordinary repository; nothing about it requires a particular git host.
Remote
A copy of the repository hosted on a server, such as GitHub or GitLab. You push your work to it and pull other people’s work from it.
Clone
A full local copy of a remote repository, including all its history. Cloning is how you start working on an existing docs project.
Branch
A movable pointer to a line of commits. One branch — usually main — is the one your live site is built from. Every other branch is invisible to readers until you merge it. Use branches to make changes, get them reviewed, and try ideas without touching the live site.
Deployment branch
The branch your pipeline builds and deploys. Usually main. Reed has no opinion about which branch this is, because Reed does not deploy anything; your CI or your deploy script decides.
Stage
Choosing which changes go into the next commit, with git add. Staging lets you split unrelated edits into separate, readable commits.
Commit
A saved snapshot of the staged changes, with a message describing them. Commits are the permanent record of the project.
Diff
The line-by-line difference between two versions of a file. Reviewing a pull request is mostly reading a diff.
Push and pull
Push sends your local commits to the remote. Pull fetches other people’s commits and merges them into your local branch.
Pull request
A proposal to merge one branch into another, with room for review and discussion before anything changes. GitLab calls it a merge request.
Merge
Combining the changes from one branch into another. For docs, this is almost always a reviewed pull request merging into the deployment branch.
Conflict
What happens when two branches change the same lines differently. Git stops and asks you to choose one version or combine them.
The Reed workflow
Section titled “The Reed workflow”Every documentation change follows the same loop:
Branch
Start from an up-to-date main and create a branch named for the change.
Edit and preview locally
Edit MDX and docs.json in your own editor. Run reed dev to see the site as you work.
Check
Run reed check before you commit. It is offline, needs no setup, and catches schema errors, unresolved navigation, unknown components and heading problems.
Open a pull request
Push the branch and open a pull request against main. CI runs the same checks, and a teammate reviews the diff.
Merge
Merge once review and checks pass.
Build and deploy from main
Your pipeline runs reed build on main and uploads the output to your host.
The rest of this page walks through each step on the command line.
Branch names
Section titled “Branch names”A branch name should say what the branch is for. Anyone scanning the branch list should be able to tell which one to look at.
Good:
fix-broken-linksadd-webhooks-guidereorganize-getting-startedticket-123-oauth-guide
Bad: temp, my-branch, updates, branch1.
Create a branch
Section titled “Create a branch”Start from the latest main, then create and switch to the new branch in one command:
git switch maingit pullgit switch -c add-webhooks-guidePush it and set the upstream, so later pushes need no arguments:
git push -u origin add-webhooks-guideWork on the branch
Section titled “Work on the branch”Preview as you write. reed dev serves the site locally and needs no network once
reed prefetch has run on your machine:
reed devBefore each commit, validate:
reed checkcheck shares its validation path with build, so a green check catches almost every
schema or content error before build does. A few surface only at build — a broken local
import, or a page file missing from navigation. It does not check links written in page
prose; see
Maintenance for how to add that.
Then stage, commit and push:
git add content/guides/webhooks.mdx docs.jsongit commit -m "Add webhooks guide"git pushCommit a new page and its navigation entry together. Reed has no hidden pages: a page
file that is not in the navigation fails reed check, and so does a navigation entry
for a page that does not exist.
Switch branches
Section titled “Switch branches”git switch other-branchCommit or stash your changes first. Git refuses to switch if uncommitted edits would be overwritten.
Review the change
Section titled “Review the change”Open a pull request from your branch to main on your git host. Then make the review worth something.
Run checks in CI
Section titled “Run checks in CI”Run reed check on every pull request. It is unconditionally offline and needs no prior
setup, which makes it the right gate for every branch. If you also build in CI, restore
both of Reed’s caches first, or a supposedly offline build will quietly reach the network.
Offline builds in CI has a complete GitHub Actions setup.
Add your prose link check to the same job. A root-relative link missing your base prefix
passes reed check and 404s in production, so this is the check that catches it.
Preview builds
Section titled “Preview builds”Reed does not create preview URLs. There is no service watching your pull requests.
If reviewers need to click through the rendered change, build it in CI and publish the output somewhere temporary:
- run
reed build --out distin the pull request job; - upload
distto a host that supports per-branch preview deployments — Cloudflare Pages, Netlify and Vercel all do — or to a throwaway bucket; - post the resulting URL on the pull request.
If your site sets base, stage the output under the mount path before uploading, exactly
as you would for production. Deploy explains why.
Without previews, reviewers can still check out the branch and run reed dev. For most
text changes, reading the diff is enough.
Read the diff
Section titled “Read the diff”Review your own diff before asking anyone else to. Then a reviewer comments on specific lines, you push fixes to the same branch, and the pull request updates.
Merge and deploy
Section titled “Merge and deploy”Merge the pull request once it is approved and CI is green. Then deploy — but only from main.
A deploy uploads a complete built site, which replaces whatever was live. Deploy from a stale feature branch and you silently overwrite every fix merged since that branch was cut. So deploy from a checkout that is exactly the tip of main, with no uncommitted changes:
git fetch origintest "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"test -z "$(git status --porcelain)"reed build --out distThen upload dist with your host’s tooling. Better still, let CI do it on every push to
main, so nobody deploys from a laptop at all.
Finally, check the live site rather than the deploy command’s exit code. Fetch a page and look for a phrase you just added; a CDN serving a cached build reports success too. See Deploy.
Delete the branch
Section titled “Delete the branch”Once merged, delete the branch locally and on the remote:
git branch -d add-webhooks-guidegit push origin --delete add-webhooks-guideMost git hosts can delete the remote branch automatically on merge. Turn that on.
Best practices
Section titled “Best practices”- Write commit messages that say what changed. “Fix broken link in webhooks guide”
beats “update page”. Future you, running
git log, will be grateful. - Keep branches focused. One task per branch. Small branches are faster to review and rarely conflict.
- Pull before you push. Bring in other people’s work first, so conflicts surface on your machine and not in the pull request.
- Run
reed checkbefore you push. CI will catch it anyway, but a failed check you find in five seconds beats one you find in five minutes. - Rename pages with a redirect. Moving a file changes its URL. Add a redirect from the old path in the same pull request.
- Delete merged branches. A branch list full of dead branches hides the live ones.